テストで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 件のコメント:
コメントを投稿
コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。
注: コメントを投稿できるのは、このブログのメンバーだけです。