Posted at

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

More than 5 years have passed since last update.

正直,何に使えるのよくわかりませんが,以下のようにすると動的に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)

なんか面白いことに使えそうですが,今のところ思いつきませんでした.

なにか思いついた方はぜひ教えて下さい.