テストでmockを使う方法を調べているつもりだったが、いつの間にか埋め込みというものを調べていた。
まあよくあることだ。
そもそも、埋め込みのパターンの記事から読み始めてはいかんな。
埋め込みとは何か、から見なくては。
【Go言語】埋め込みでinterfaceを簡単に満たす - Eureka Engineering - Medium
https://medium.com/eureka-engineering/golang-embedded-ac43201cf772
大ざっぱな理解だろうが、継承っぽいことができる、ということでいいのかな。
vtblをコピーしてアドレスが同じところを指しているだけなので、定義すればオーバーライドしてそのメソッドだけは別のものを指定できる、と。
interfaceを埋め込んだ場合はどこも指していないので、定義すれば呼び出せるし、定義しなければnilか何かになっていて呼べない。
body.go
01: package body
02:
03: type BodyInterface interface {
04: Go() string
05: GoGo() string
06: }
07:
08: type BodyStruct struct {
09: BodyInterface
10: }
11:
12: func (body *BodyStruct) Go() string {
13: return "Go"
14: }
15:
16: func (body *BodyStruct) GoGo() string {
17: return "GoGo"
18: }
mummy.go
01: package body
02:
03: type MummyStruct struct {
04: BodyStruct
05: }
06:
07: func (body *MummyStruct) GoGo() string {
08: return "MuMu"
09: }
main.go
01: package main
02:
03: import (
04: "ex6/body"
05: "fmt"
06: )
07:
08: func main() {
09: var body0 body.BodyStruct
10: fmt.Printf("%s\n", body0.Go())
11: fmt.Printf("%s\n", body0.GoGo())
12:
13: var body body.MummyStruct
14: fmt.Printf("%s\n", body.Go())
15: fmt.Printf("%s\n", body.GoGo())
16: }
$ go run ex6/main
Go
GoGo
Go
MuMu
MummyStructをreceiverに持つGo()は実装していないのだが、BodyStructのGo()が呼び出せている。
予想通りだ。
では、こうしたらどうなる?
mummy.go
01: package body
02:
03: type MummyStruct struct {
04: BodyInterface
05: }
06:
07: func (body *MummyStruct) GoGo() string {
08: return "MuMu"
09: }
main.go
01: package main
02:
03: import (
04: "ex6/body"
05: "fmt"
06: )
07:
08: func main() {
09: var body0 body.BodyStruct
10: fmt.Printf("%s\n", body0.Go())
11: fmt.Printf("%s\n", body0.GoGo())
12:
13: var body body.MummyStruct
14: fmt.Printf("%s\n", body.GoGo())
15: fmt.Printf("%s\n", body.Go())
16: }
継承っぽいことをしている箇所を、BodyStructではなくBodyInterfaceにしたのだ。
まあ、結果の予想が付くので、Printfするところもbody.GoGo()を先に呼び出すようにした。
$ go run ex6/main
Go
GoGo
MuMu
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0x48ea85]goroutine 1 [running]:
main.main()
/home/xxx/go/src/ex6/main/main.go:15 +0x1e5
exit status 2
定義したMummyStructのGoGo()は呼び出しできているが、定義していないGo()を呼び出すとpanicが発生している。
予想通りですな。
では、次回はこれをどうテストに応用できるのか、だ。
0 件のコメント:
コメントを投稿
コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。
注: コメントを投稿できるのは、このブログのメンバーだけです。