当前位置: 首页 > 面试题库 >

了解Go中的多态性

束帅
2023-03-14
问题内容

我想我一直在考虑针对以下问题的多态解决方案:

假设我有一个BaseTX structwith字段用于交易。现在,我有两种特殊的交易类型:RewardTX structAllowanceTX struct

RewardTX struct目前只有的组成BaseTX struct

AllowanceTX structBaseTX struct和组成AddField

我还有一个函数logicAndSaveTX(),该函数在字段上具有一些逻辑,BaseTX但最后是使用json.Marshal()并保存byte[]某处序列化整个对象。

type TXapi interface {
    logicAndSaveTX()
}

type BaseTX struct {
    Field1 string
    Field2 string
}

type RewardTX struct {
    BaseTX 
}

type AllowanceTX struct {
    BaseTX 
    AddField string
}

func (tx BaseTX) logicAndSaveTX() {
    // logic on BaseTX fields; simplified:
    tx.Field1 = "overwritten"
    tx.Field2 = "logic done"

    // here would be marshal to json and save; simplified to print object:
    fmt.Printf("saved this object: %+v \n", tx)
}

func SaveTX(tx TXapi) {
    tx.logicAndSaveTX()
}


func main() {
    rewardTX := RewardTX{BaseTX : BaseTX{Field1: "Base info1", Field2: "Base info2"}}
    SaveTX(rewardTX) // should print rewardTX with fields from BaseTX
    allowanceTX := AllowanceTX{BaseTX : BaseTX{Field1: "Base info1", Field2: "Base info2"}, AddField: "additional field"}
    SaveTX(allowanceTX) // would like to print allowanceTX with fields from BaseTX + AdditionalField >>> instead only printing fields from BaseTX
}

https://play.golang.org/p/0Vu_YXktRIk

我试图弄清楚如何实现在两种事务上都可以使用的结构和功能,但是最后正确地序列化了这两种结构。我的问题是,AddField在我当前的实现中看不到。

也许我在这里有些脑力衰竭-我真的很想以“正确的行进方式”实现这一目标。:)


问题答案:

Go不是面向对象的。 多态性围棋的形式是接口

来自其他面向对象的语言可能很困难,因为您必须摆脱可能要继承的许多想法,例如“基础”类/类型。只需从设计思想中删除“基础”即可;您正在尝试将合成转换为继承,这只会使您陷入麻烦。

在这种情况下,也许您在这里有合理的构图理由;您有一些通用的共享字段供多种类型使用,但这不是“基本”类型。可能是“元数据”之类的东西-
考虑到您的示例非常抽象,我不能说该怎么称呼,但是您知道了。

所以也许您有:

type TXapi interface {
    logicAndSaveTX()
}

type Metadata struct {
    Field1 string
    Field2 string
}

type RewardTX struct {
    Metadata 
}

func (tx RewardTX) logicAndSaveTX() {
    // logic on BaseTX fields; simplified:
    tx.Field1 = "overwritten"
    tx.Field2 = "logic done"

    // here would be marshal to json and save; simplified to print object:
    fmt.Printf("saved this object: %+v \n", tx)
}

type AllowanceTX struct {
    Metadata 
    AddField string
}

func (tx AllowanceTX) logicAndSaveTX() {
    // logic on BaseTX fields; simplified:
    tx.Field1 = "overwritten"
    tx.Field2 = "logic done"
    tx.AddField = "more stuff"

    // here would be marshal to json and save; simplified to print object:
    fmt.Printf("saved this object: %+v \n", tx)
}

如果元数据(或其他任何内容)字段的处理在所有用途上都是相同的,则也许您可以给该类型使用它自己的logicTX方法来填充这些字段,可以通过logicAndSaveTX嵌入它的结构的调用。

这里的关键是要考虑要 限制在该类型 上的类型的行为(方法),而不是将其视为能够对“子类型”进行操作。子类型不存在,并且 嵌入
在其他类型中的类型也无法在其容器上进行操作。



 类似资料:
  • 问题内容: 我正在学习go lang,我想知道是否可以做这样的事情: 在面向对象的语言中,这样的代码应该可以正常工作,但是在执行过程中会抛出一个错误,说必须返回Foo类的实例。 有没有一种方法可以类似于我在Go中描述的多态性? 问题答案: Go不是典型的OO语言。同样,每种语言都有自己的处理方式。您可以使用界面和组成来实现所需的目标,如下所示: http://play.golang.org/p/i

  • Go的多态 go 是一种强类型的语言,每当我从java切换到go时总有些许的不适应,但是追求优雅,就不应该妥协。 go没有 implements, extends 关键字,所以习惯于 OOP 编程,或许一开始会有点无所适从的感觉。 但go作为一种优雅的语言, 给我们提供了另一种解决方案, 那就是鸭子类型:看起来像鸭子, 那么它就是鸭子. go中的多态比java的隐匿得多,严格上说没有多态,但可以利

  • 问题内容: 我正在学习语言,这些要点摘自的规范。 虽然我能理解分1-4,我很困惑的点和: 5. 在函数内部声明的常量或变量标识符的范围始于ConstSpec或VarSpec的末尾(对于简短变量声明为ShortVarDecl),并在最里面的包含块的末尾结束。 6. 在函数内部声明的类型标识符的范围始于TypeSpec中的标识符,并终止于最里面的包含块的末尾。 这是我用来了解Go范围的代码: 据此,我

  • 本文向大家介绍解释PHP中的多态性。,包括了解释PHP中的多态性。的使用技巧和注意事项,需要的朋友参考一下 首先,多态是从希腊语Poly(表示很多)和morphism(表示形式)中获得的。 多态描绘了面向对象编程中的一个示例,在该示例中,具有相似功能的各个类中的方法应具有相似的名称。多态本质上是一种OOP模式,它使具有不同功能的多个类可以执行或共享commonInterface。多态性的用处在于,

  • 本文向大家介绍JS中的多态实例详解,包括了JS中的多态实例详解的使用技巧和注意事项,需要的朋友参考一下  多态在面向对象编程语言中是十分重要的。在JAVA中是通过继承来得到多态的效果。如下: 多态的思想实际上是把“做什么”和“谁去做”分离开来,要实现这一点,归根结底先要消除类型之间的耦合关系。 在Java中,可以通过向上转型来实现多态。而javascript的变量在运行期是可变的,一个js对象既可

  • 问题内容: 使用该包可以很容易地解析如下对象。 我面临的问题是从服务器返回多个命令,如下所示: 无法使用以下代码进行解析。 我正在尝试解析Common Crawl数据(请参阅示例)。 我怎样才能做到这一点? 问题答案: 假设您的输入确实是一系列有效的JSON文档,请使用json.Decoder对其进行解码: 游乐场:https://play.golang.org/p/ANx8MoMC0yq 如果您