dongxueji2838
2015-02-18 06:39 阅读 179
已采纳

如何在运行时使用反射更改方法的实现?

I have this type implementation:

type A struct{
  name string
}

func (a A) getName() string {
  return "My name is " + a.name 
}

How I can change implementation of method getName() for this type using reflection? For example, I want use next implementation instead of current:

func newGetName() string {
  return "test reflection"
} 
  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享

2条回答 默认 最新

  • 已采纳
    douqing5981 douqing5981 2015-02-18 11:14

    Go is a compiled language. As such, it's not possible to modify the implementation of things at runtime. What you can do is changing the place function pointers point to:

    var getName func(string) = func(name string) {
        return "my name is " + name
    }
    

    In order to make this work with a structure, you have to resort to a few tricks. First add getName as a member to A:

    type A struct {
        name string
        getName func() string
    }
    

    Then we enclose a pointer to the structure as an implicit (i.e. closed over) parameter:

    foo := &A{name: "Hans"}
    foo.getName = func() string {
        return "my name is " + name
    }
    

    Now you can call A.getName() and the result is "my name is hans". You can use method expressions and many other features just fine, but getName is a structure member and not a method of A, so keep this in mind. When you want to give a new meaning to getName, assign something different to it:

    foo.getName = func() string {
        return "test reflection"
    }
    

    Another idea that is especially applicable if you know in advance what implementations getName could have is to add a new member to A that says what implementation getName currently has and then switch over this variable.

    点赞 评论 复制链接分享
  • dqe55175 dqe55175 2015-02-18 06:46

    Note the idiomatic Go is to not do that and use interface instead:

    See this example:

    package main

    import "fmt"
    
    type Aer interface {
        getName() string
    }
    
    type A struct {
        name string
    }
    
    func (a A) getName() string {
        return "My name is " + a.name
    }
    
    type testA struct {
        a A
    }
    
    func (ta testA) getName() string {
        return "NEW: My name is " + ta.a.name
    }
    func main() {
        a := A{name: "nameA"}
        fmt.Println(a.getName())
        ta := testA{a: a}
        fmt.Println(ta.getName())
    }
    

    Output:

    My name is nameA
    NEW: My name is nameA
    
    点赞 评论 复制链接分享

相关推荐