繁体   English   中英

去“继承” - 在结构中使用匿名类型作为方法参数

[英]Go “inheritance” - using anonymous type in a struct as a method parameter

我试图巩固Go提供的遗传概念(可能是“组合”而不是纯粹的遗传)。 但是,我无法理解为什么我不能使用“父”类型作为func参数来生成一个作用于参数的泛型函数。

package main

import "log"

type Animal struct {
    Colour string
    Name string
}

type Dog struct {
    Animal
}

func PrintColour(a *Animal) {
    log.Printf("%s\n", a.Colour)
}


func main () {
    a := new (Animal)
    a.Colour = "Void"
    d := new (Dog)
    d.Colour = "Black"

    PrintColour(a)
    PrintColour(d)
}

假设我的理解不正确,我怎样才能在Go中实现我想要的?

编辑注意:

  • 我不想将行为附加到结构

  • 我想保持指针类型作为方法参数,因为我在一个宠物项目上单独工作,这需要我操纵传入的结构,然后再对其进行操作。

  • 实际上我的Dog结构会有额外的字段/成员; 希望这不会进一步混淆水

到目前为止,我喜欢这里的答案,我想添加一个允许您使用接口传入的接口进行静态类型检查:

package main

import (
    "fmt"
)

type Animalizer interface {
    GetColour() string
}

type Animal struct {
    Colour string
    Name   string
}

type Dog struct {
    Animal
}

func (a *Animal) GetColour() string {
    return a.Colour
}

func PrintColour(a Animalizer) {
    fmt.Print(a.GetColour())
}

func main() {
    a := new(Animal)
    a.Colour = "Void"
    d := new(Dog)
    d.Colour = "Black"

    PrintColour(a)
    PrintColour(d)
}

在操场上

可以向Dog添加更多字段。 与Uriel的答案的不同之处在于,如果传入实现Animalizer的结构之外的其他内容,则在编译时对PrintColour调用将失败。

此外,您不必使用typeswitch,因为编译器知道Animalizer正在实现GetColour

最后,行为(打印)与结构分离, GetColour只返回颜色。

如果在Animal类型上声明PrintColour方法,那么当您在Dog包含Animal时,它将被“继承”。

这在Go世界中被称为“嵌入”。 有关详细信息,请参阅Effective Go的“嵌入”部分

尝试类似的东西:

package main

import "log"

type Animal struct {
    Colour string
    Name string
}

type Dog struct {
    Animal
}

func (a *Animal) PrintColour() {
    log.Printf("%s\n", a.Colour)
}


func main () {
    a := new (Animal)
    a.Colour = "Void"
    d := new (Dog)
    d.Colour = "Black"

    a.PrintColour()
    d.PrintColour()
}

生产:

2009/11/10 23:00:00无效
2009/11/10 23:00:00黑色

操场

您可以使用interface{}尝试

package main

import ("fmt"
       "reflect")

type Animal struct {
    Colour string
    Name string
}

type Dog struct {
    Animal
}

func PrintColour(a interface{}) {
    switch a.(type){
        case *Dog:
            fmt.Printf("Dog %s\n", a.(*Dog).Colour)
        case *Animal:
            fmt.Printf("Aimal %s\n", a.(*Animal).Colour)
        default:        
            fmt.Printf("hmm %s\n", reflect.TypeOf(a))

    }
}


func main () {
    a := new (Animal)
    a.Colour = "Void"
    d := new (Dog)
    d.Colour = "Black"

    PrintColour(a)
    PrintColour(d)

}

仍然可以使用其typename显式访问嵌入(匿名)字段:

package main

import "log"

type Animal struct {
    Colour string
    Name   string
}

type Dog struct {
    Animal
}

func PrintColour(a *Animal) {
    log.Printf("%s\n", a.Colour)
}

func main() {
    a := new(Animal)
    a.Colour = "Void"
    PrintColour(a)

    d := new(Dog)
    d.Colour = "Black"
    // you can access the underlying "Animal" through "d.Animal"
    PrintColour(&d.Animal)
}

操场

在引用中 :第二个代码块之后的句子解释了如何声明“匿名”字段,并指出:

非限定类型名称充当字段名称。

我的例子可能不是很好,但你可以这样做你想要的:

http://play.golang.org/p/JoAlOvJthr

基本上使用一个接口来定义您希望为所有类型和嵌入类型公开给外部世界的公共功能。

(我的例子可能不是最好但它有效)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM