2017-03-31 39 views
1

我在想,如果做这样的事情在golang甚至有可能 -在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中完成可以用动态类型语言完成的事情。谢谢! :-)

+1

这个答案可能会提供一些见解http://stackoverflow.com/questions/21251242/is-it-possible-to-call-overridden-method-from-parent-struct-in-golang – Adam

+2

https:// play .golang.org/p/Lp3aP2dqpt – mkopriva

+0

@mkopriva做这件事的特殊方式可能比我的更优先。但是再次,它仍然包含能够访问内部结构数据成员的问题。但至少该方法本身是一个真正的方法。 – RayfenWindspear

回答

4

鉴于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) 
} 

因为这个功能是不是一个真正的方法,你只能把它当作一个参数访问内部结构值。这意味着如果这必须跨越包装边界,则未提供的值将不可用。

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

+0

但这不是一种方法,因此它不是方法集的一部分。 – JimB

+0

@JimB确实如此,但这是一种替代方法来完成所期望的任务。如果修改方法真的是我想要的,我认为不能完成。 – RayfenWindspear

+0

实际上,不,你是对的,这是不理想的,因为你不能以这种方式访问​​结构值。你可以通过'PrintHello func(ms * MyStruct)'来定义函数var来接受结构指针。编辑回答对此进行说明。 – RayfenWindspear