为了账号安全,请及时绑定邮箱和手机立即绑定

访问嵌入式函数中的函数

访问嵌入式函数中的函数

Go
斯蒂芬大帝 2022-01-10 10:57:18
首先,我对 Go 很陌生,所以请原谅术语中的任何失误或错误。我怀疑我缺乏对术语的掌握也部分归咎于经过数小时的查找后没有找到以下问题的答案。简而言之,我希望以下代码的输出为I am the AdultI am the Child相反,输出在哪里I am the AdultI am the Adult代码:package mainimport "fmt"type Human struct {    age  uint    name string}func (h Human) sayName() error {    fmt.Println("I am the Adult")    return nil}func (h Human) Introduce() error {    h.sayName()    return nil}type Child struct {    Human}func (c Child) sayName() error {    fmt.Println("I am the Child")    return nil}func main() {    h := Human{}    h.Introduce()    c := Child{Human{}}    c.Introduce()}所以本质上,虽然 Introduce() 只在嵌入类型 Human 中实现,但它调用了 sayName(),它在嵌入类型和嵌入类型中都实现了。我知道当前的输出是这样的,因为嵌入的 Human 结构不“知道”它是嵌入的,因此永远不能调用 Child.sayName 并且只会调用它自己的 sayName() 函数。有没有办法实例化一个 Human 结构(或一个嵌入结构),您可以在其中用另一个 sayName() 函数“替换” Human.sayName()?
查看完整描述

3 回答

?
呼如林

TA贡献1798条经验 获得超3个赞

获得这种后期绑定行为的方法是使用接口。IfIntroduce是接口上的一个sayName方法,它需要一个方法,那么HumanChild 都将满足该接口,并且可以Introduce自己满足,并且sayName在任何一种情况下都将调用正确的方法,因为它将通过接口类型而不是 via 分派Human


查看完整回答
反对 回复 2022-01-10
?
慕的地10843

TA贡献1785条经验 获得超8个赞

你想做的事情是不可能的。正如你所说,Human类型永远无法知道它的嵌入Child型和为此时Introduce被调用它没有调用方式Child的类型版本sayName()。您正在尝试反转关系,让嵌入类型在嵌入器中调用其方法的另一个版本。

嵌入类型的方法被提升到嵌入器的范围,但这是一条单行道,这是明智的。在这种情况下,您只需要以不同的方式构造您的代码。最有可能的是,您正在寻找的任何行为都可以通过使用接口而不是嵌入来实现。我会提供更多示例,但是对于您的代码示例,没什么好说的,显然要解决这里的问题,您只需调用sayName()并且永远不会Introduce首先定义,因为它什么都不做。

您可能应该只嵌入相反的方向。Human不包含对的引用,ChildChild确实有对Human和的引用,在这种情况下,两者都有对 的定义sayName()Child可以Human通过做来调用's c.Human.sayName()。所以我的直觉说你嵌入了错误的方向,或者你应该使用接口。这纯粹是一个假设,但我猜你可能有错误的想法,因为你指的Human是和“成人”(如父母)和Child作为孩子(就像一个孩子班)。根本不是这种情况。嵌入与组合相同,只是嵌入类型的方法和字段被提升或提升,或者您喜欢说它们被移动到嵌入器范围的任何术语。话虽如此,我在 SO 上看到了很多关于这个的困惑,这几乎总是因为提问者把它看作是继承,而实际上它是组合。


查看完整回答
反对 回复 2022-01-10
?
料青山看我应如是

TA贡献1772条经验 获得超8个赞

我想错了。正如 hobbs 和 evanmcdonnal 所说,“正确”的做法是让 Introduce() 函数成为一个带有接口参数的函数,然后创建一个 Child 和 Human 都实现的接口。


以下给出了所需的输出:


package main


import "fmt"


type Talker interface {

    sayName() error

}


type Human struct {

    age  uint

    name string

}


func (h Human) sayName() error {

    fmt.Println("I am the Adult")

    return nil

}


type Child struct {

    Human

}


func Introduce(t Talker) error {

    t.sayName()

    return nil

}


func (c Child) sayName() error {

    fmt.Println("I am the Child")

    return nil

}


func main() {

    h := Human{}

    Introduce(h)


    c := Child{Human{}}

    Introduce(c)

}


查看完整回答
反对 回复 2022-01-10
  • 3 回答
  • 0 关注
  • 156 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信