在golang中,如何将方法分配给现有的struct对象?

时间:2017-03-31 19:07:40

标签: go

我想知道在golang中做这样的事情是否可行 -

type MyStruct struct {
    id int
}

func (ms *MyStruct) PrintHello() {
    fmt.Printf("Hello from original method %v", ms.id)
}

func main() {
    fmt.Println("Hello, playground")
    m := MyStruct{}
    m.PrintHello()

    m.PrintHello = func() {fmt.Printf("Hello from newer method 2")}
}

Error: cannot assign to m.PrintHello

https://play.golang.org/p/2oJQFFH4O5

对不起,如果这对Go程序员没有意义,我是Go的新手,想知道在动态类型语言中可以做的一些事情是否可以在Go中完成。谢谢! : - )

1 个答案:

答案 0 :(得分:8)

鉴于Go是一种静态类型语言,您无法执行此特定代码。但是,函数是变量,所以你可以做这样的事情。请记住,这在技术上与分配新方法不同,正如JimB在评论中所述。

https://play.golang.org/p/rfuCzXD8fP

package main

import (
    "fmt"
)

type MyStruct struct {
    id         int
    PrintHello func(ms * MyStruct)
}

func (ms *MyStruct) init() {
    ms.PrintHello = func(ms *MyStruct) { fmt.Printf("Hello from original method %v\n", ms.id) }
}

func main() {
    m := &MyStruct{id: 42}
    m.init()
    m.PrintHello(m)

    m.PrintHello = func(ms *MyStruct) { fmt.Printf("Hello from newer method 2 %d\n", ms.id) }
    m.PrintHello(m)
}

因为此函数实际上不是一个方法,所以只能通过将其作为参数传递来访问内部struct值。这意味着如果必须跨越包边界,则未导出的值将不可用。

同样重要的是要注意功能类型必须相同。因此,如果您在结构中将函数定义为PrintHello func(ms * MyStruct) error,则需要指定一个返回错误的函数。