可以在一个结构体中嵌套另一个结构体以满足接口的要求。

huangapple go评论121阅读模式
英文:

Can One Embed A Struct In A Struct To Satisfy An Interface

问题

我有以下代码(也可以在Go Playground中找到)。是否可能实例化一个包含嵌入式C、S和X的A结构体?我使用接口的原因是,根据我调用的Build函数,我希望拥有具有不同Bar()实现的结构体。我可以有一个S1或S2,其中Bar()略有不同,但都是S'ers。

  1. package main
  2. import "fmt"
  3. type Cer interface {
  4. Foo()
  5. }
  6. type Ser interface {
  7. Bar()
  8. }
  9. type Aer interface {
  10. Cer
  11. Ser
  12. }
  13. type C struct {
  14. CField string
  15. }
  16. func (this *C) Foo() {
  17. }
  18. type S struct {
  19. SField string
  20. }
  21. func (this *S) Bar() {
  22. }
  23. type X struct {
  24. XField string
  25. }
  26. type A struct {
  27. Cer
  28. Ser
  29. X
  30. }
  31. func main() {
  32. x := new(X)
  33. a := Build(x)
  34. fmt.Println(a)
  35. }
  36. func Build(x *X) A {
  37. a := new(A)
  38. a.X = *x
  39. a.XField = "set x"
  40. return *a
  41. }
英文:

I have the following code (also available in the Go Playground). Is it possible to instantiate an A struct such that it contains an embedded C, S and an X. The reason I am using interfaces is because, depending on the Build function I call, I'd like to have structs that have different implementations of Bar(). I could have an S1 or an S2, where Bar() is slightly different, but both are S'ers.

  1. package main
  2. import "fmt"
  3. type Cer interface {
  4. Foo()
  5. }
  6. type Ser interface {
  7. Bar()
  8. }
  9. type Aer interface {
  10. Cer
  11. Ser
  12. }
  13. type C struct {
  14. CField string
  15. }
  16. func (this *C) Foo() {
  17. }
  18. type S struct {
  19. SField string
  20. }
  21. func (this *S) Bar() {
  22. }
  23. type X struct {
  24. XField string
  25. }
  26. type A struct {
  27. Cer
  28. Ser
  29. X
  30. }
  31. func main() {
  32. x := new(X)
  33. a := Build(x)
  34. fmt.Println(a)
  35. }
  36. func Build(x *X) A {
  37. a := new(A)
  38. a.X = *x
  39. a.XField = "set x"
  40. return *a
  41. }

答案1

得分: 1

简短回答是:是的,你可以。

但是,当嵌入接口时,如果在调用嵌入的方法之前没有先给定一个值,你将会遇到运行时错误。

所以,下面的代码是正确的:

  1. a := Build(x)
  2. // 如果删除下面这行代码,在调用 a.Foo() 时将会导致运行时错误
  3. a.Cer = &C{"The CField"}
  4. a.Foo()
英文:

Short answer is: Yes, you can.

But when embedding interfaces, you will have a runtime error incase you try to call the embedded method without having given a value first.

So, the following works fine:

  1. a := Build(x)
  2. // Removing the line below will cause a runtime error when calling a.Foo()
  3. a.Cer = &C{"The CField"}
  4. a.Foo()

huangapple
  • 本文由 发表于 2014年5月6日 11:35:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/23485542.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定