41
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

posted at

Organization

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

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

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

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
41
Help us understand the problem. What are the problem?