Go中的多态性 - 它存在吗?

时间:2014-04-22 06:07:15

标签: go

我试图在Go上做一些简单的事情:拥有一个带有getter和setter方法的接口。并且似乎不允许使用setter方法。

鉴于此代码:

package main

import "fmt"

type MyInterfacer interface {
    Get() int
    Set(i int)
}

type MyStruct struct {
    data int
}

func (this MyStruct) Get() int {
    return this.data
}

func (this MyStruct) Set(i int) {
    this.data = i
}

func main() {
    s := MyStruct{123}
    fmt.Println(s.Get())

    s.Set(456)
    fmt.Println(s.Get())

    var mi MyInterfacer = s
    mi.Set(789)
    fmt.Println(mi.Get())
}

Set方法不起作用,因为在func (this MyStruct) Set(i int)中,this MyStruct不是指针,并且在函数退出时很快就会丢失更改。但是使this *MyStruct无法编译。有没有解决方法?

4 个答案:

答案 0 :(得分:7)

以下是您的代码的更正版本(playground)。这并不完全是多态性,但使用界面是很好的Go风格。

package main

import "fmt"

type MyInterfacer interface {
    Get() int
    Set(i int)
}

type MyStruct struct {
    data int
}

func (this *MyStruct) Get() int {
    return this.data
}

func (this *MyStruct) Set(i int) {
    this.data = i
}

func main() {
    s := &MyStruct{123}
    fmt.Println(s.Get())

    s.Set(456)
    fmt.Println(s.Get())

    var mi MyInterfacer = s
    mi.Set(789)
    fmt.Println(mi.Get())
}

答案 1 :(得分:4)

我曾经在Go:

中找到了如何进行多态的示例

http://play.golang.org/p/6Ip9scm4c3

package main

import "fmt"

type Talker interface {
        Talk(words string)
}

type Cat struct {
        name string
}

type Dog struct {
        name string
}

func (c *Cat) Talk(words string) {
        fmt.Printf("Cat " + c.name + " here: " + words + "\n")
}

func (d *Dog) Talk(words string) {
        fmt.Printf("Dog " + d.name + " here: " + words + "\n")
}

func main() {
        var t1, t2 Talker

        t1 = &Cat{"Kit"}
        t2 = &Dog{"Doug"}

        t1.Talk("meow")
        t2.Talk("woof")
}

答案 2 :(得分:2)

回答标题中的问题:

  

Go不使用类,但提供了许多相同的功能:

* message passing with methods
* automatic message delegation via embedding
* polymorphism via interfaces
* namespacing via exports

来自:http://nathany.com/good/

解决你提供的代码,我将留给更多学问的Gopher

答案 3 :(得分:1)

AD HOC多态性

Ad hoc多态性是静态类型语言的多态实现的一般方法。 Go中的多态性是ad hoc多态性,与Bjarne的Stroustrup定义非常接近:

  

多态性 - 为不同类型的实体提供单一接口。

接口

Go interface是专为多态实现而设计的强大工具。接口是一种类型抽象(方法集),它提供了一种指定对象行为的方法:如果某些东西可以做到这一点,那么它可以在这里使用。回到Straustrup的多态定义:如果实现接口,可以使用不同类型的对象作为公共接口的类型。

Playground with an example.

参数多态性

维基:

  

可以一般性地编写函数或数据类型,以便它可以相同地处理值而不依赖于它们的类型。

对于像Python或Ruby这样的动态类型语言,这种多态性更为常规,但Go也实现了它!为此,Go使用类型空接口interface{}

输入interface{}

来自Tour of Go:

  

指定零方法的接口类型称为空接口:

     

interface{}   空接口可以保存任何类型的值。每种类型至少实现零方法。

     

处理未知类型值的代码使用空接口。例如,fmt.Print采用任意数量的interface{}类型的参数。

并且可以获得具有类型断言的特定类型的对象。

再次参观Tour:

  

类型断言提供对接口值的基本具体值的访问。

t := i.(T)

  

该语句声明接口值i保存具体类型T并将基础T值分配给变量t。

我们有静态鸭子类型的参数多态性。