[Go言語]structにinterfaceを埋め込んで,動的に入れ替えるパターン

  • 37
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

正直,何に使えるのよくわかりませんが,以下のようにすると動的にinterfaceの実装方法を変更できることに気づきました.

structの匿名フィールド(埋め込み)として,interfaceを設定すると,そのstructも埋め込んだinterfaceを実装していることになります.埋め込んだinterfaceは匿名フィールドなので,型名でアクセスして入れ替えることができます.

以下の例では,fmt.Stringerインタフェースの実装を動的に変更しています.

package main

import (
    "fmt"
    "strings"
)

type StringerFunc func() string

func (sf StringerFunc) String() string {
    return sf()
}

type Person struct {
    fmt.Stringer
    FirstName string
    LastName  string
    Age       int
}

func NewPerson(firstName, lastName string, age int) (p *Person) {
    p = &Person{
        nil,
        firstName,
        lastName,
        age,
    }

    p.Stringer = StringerFunc(func() string {
        return fmt.Sprintf("%s %s (%d)", p.FirstName, p.LastName, p.Age)
    })

    return
}

func (p *Person) SetStringer(sf func(p *Person) string) {
    p.Stringer = StringerFunc(func() string {
        return sf(p)
    })
}

func main() {
    p := NewPerson("Taro", "Yamada", 20)
    fmt.Println(p)
    p.SetStringer(func(p *Person) string {
        return fmt.Sprintf("%s, %s (%d)", strings.ToUpper(p.LastName), p.FirstName, p.Age)
    })
    fmt.Println(p)
}

上記のプログラムを実行すると,以下のような結果になります.

Taro Yamada (20)
YAMADA, Taro (20)

なんか面白いことに使えそうですが,今のところ思いつきませんでした.
なにか思いついた方はぜひ教えて下さい.