Set reference in Go

huangapple go评论81阅读模式
英文:

Set reference in Go

问题

如何通过引用传递接口,并让方法为我填充它?类似于这样:

var i CustomInterface
Get("title", &i)
i.SomeOperationWithoutTypeAssertion() // 这里 i 是 nil(我的问题)

func Get(title string, iRef interface{}) {
    iRef = new(ATypeWhichImplementsTheUnderlyingInterface)
}

我希望在调用 Get 方法后,i 不是 nil。如何将 i 作为引用传递给 Get 方法?

英文:

How to pass an interface by reference and let the method fill it for me? Something like this:

var i CustomInterface
Get("title" , ref i)
i.SomeOperationWithoutTypeAssertion() //i is nil here(my problem)

func Get(title string, iRef ref interface{}){
     iRef = new(ATypeWhichImplementsTheUnderlyingInterface)
}

I want i not to be nil after calling the Get method. How to pass i as reference to the Get method?

答案1

得分: 3

Go语言没有像C++等语言中的透明引用参数的概念,所以你所问的是不可能的:你的Get函数接收的是接口变量的副本,所以不会更新调用范围内的变量。

如果你确实希望函数能够更新传递的参数,那么必须将其作为指针传递(即调用为Get("title", &i))。没有语法来指定参数应该是任意类型的指针,但是所有指针都可以存储在interface{}中,因此该类型可以用于参数。然后,你可以使用type assertion / switchreflect来确定你所获得的类型。你需要依赖运行时错误或恐慌来捕获参数的错误类型。

例如:

func Get(title string, out interface{}) {
    ...
    switch p := out.(type) {
    case *int:
        *p = 42
    case *string:
        *p = "Hello world"
    ...
    default:
        panic("Unexpected type")
    }
}
英文:

Go doesn't have the concept of transparent reference arguments as found in languages like C++, so what you are asking is not possible: Your Get function receives a copy of the interface variable, so won't be updating variable in the calling scope.

If you do want a function to be able to update something passed as an argument, then it must be passed as a pointer (i.e. called as Get("title", &i)). There is no syntax to specify that an argument should be a pointer to an arbitrary type, but all pointers can be stored in an interface{} so that type can be used for the argument. You can then use a type assertion / switch or the reflect package to determine what sort of type you've been given. You'll need to rely on a runtime error or panic to catch bad types for the argument.

For example:

func Get(title string, out interface{}) {
    ...
    switch p := out.(type) {
    case *int:
        *p = 42
    case *string:
        *p = "Hello world"
    ...
    default:
        panic("Unexpected type")
    }
}

huangapple
  • 本文由 发表于 2015年7月5日 15:26:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/31228093.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定