LoginSignup
1
0

More than 3 years have passed since last update.

構造体へのインターフェースの埋め込み

Last updated at Posted at 2019-11-28

構造体へのインターフェースの埋め込みについての知識に漏れがあったので、調べたことをまとめました。

Goでは、インターフェースの明示的宣言はなく、インターフェースの持つメソッドを実装することでそのインターフェースを満たしていることになります(ダックタイピング)。

しかし、実はインターフェースを構造体に埋め込むことでも、例えその構造体はインターフェースの持つメソッドを持っていなくても、そのインターフェースを満たしていることになります。

下記のコードでは、user構造体はUserInterfaceを持っているのでUserInterfaceのもつFullName()を持っていなくてもUserInterfaceを満たしていることになります。よって、下記のコードはビルドが通ります。

func main() {
    taro := testUser{
        firstName: "Taro",
        lastName:  "Yamada",
    }
    outputUser(taro) //testUserがUserInterfaceを満たしているため、taroをoputputUserに渡せる
}

type UserInterface interface {
    FullName() string
}

type testUser struct {
    UserInterface       // interfaceを埋め込むことで、メソッドを実装しなくてもそのinterfaceを満たせる
    firstName, lastName string
}

func outputUser(u UserInterface) {
    fmt.Println(u.FullName())//userはFullNameメソッドを持っていないがコンパイルエラーにならない
}

しかし、ouputUserメソッド内で実際には実装されていないFullName()メソッドを呼んでいるため、実行時にはpanicが起きます。

❯ go run main.go
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x10992c7]

goroutine 1 [running]:
main.main()
        /Users/mmm/go/src/github.com/masalennon/test/main.go:13 +0x87
exit status 2

上記のコードに、FullNameメソッドを追加すれば、ちゃんと実行されます。


func (u user) FullName() string {
    return u.firstName + " " + u.lastName
}
// Taro Yamada

おわり

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0