英文:
Why does Go allow pointers to interfaces?
问题
在我写Go代码的任期中,我从未遇到过一种情况,也无法想到一种情况,需要使用指向接口的指针,除非是编写一个大量使用运行时反射的库。一些人提到了有合理的理由这样做,但似乎从未详细说明。这个特性似乎也给那些刚开始使用Go的开发者带来了很多困惑。
main.go:22: 无法将&a (类型 *A) 作为类型 **interface {} 的参数传递给 run
有没有一个使用接口指针的好例子?
英文:
In my tenure of writing Go code, I have never encountered a case, nor can I think of one that would require using a pointer to an interface, except for perhaps writing a library that makes heavy use of runtime reflection. Some people allude to the fact that there are valid reasons for doing so, but seem to never elaborate further. This feature also seems to cause quite a bit of confusion with developers who are getting started with Go.
main.go:22: cannot use &a (type *A) as type **interface {} in argument to run
What would be a good example of using an interface pointer?
答案1
得分: 4
在语言规范中,有一个特殊情况需要禁止指向接口的指针。这使得语言更加复杂。
创建一个接口类型的reflect.Type
是一个场景,其中指向接口的指针非常有用:reflect.TypeOf((*io.Closer)(nil)).Elem()
是io.Closer
的反射类型。
英文:
A special case in the language specification is required to disallow pointers to interfaces. That makes the language more complex.
Creating a reflect.Type
for an interface interface type is one scenario where pointers to interfaces come in handy: reflect.TypeOf((*io.Closer)(nil)).Elem()
is the reflect type of io.Closer
.
答案2
得分: 1
我可以给你提供一个例子,但是我从未在实际应用中使用过,也没有见过。这个例子是让另一个函数填充你的接口。
以下是示例代码:
package main
import "fmt"
func main() {
var s fmt.Stringer
setMyStringer(&s)
fmt.Println("Hello, stringer:", s)
}
func setMyStringer(target *fmt.Stringer) {
*target = Stringable(5)
}
type Stringable int
func (s Stringable) String() string {
return fmt.Sprint(int(s))
}
你可以在这里查看示例运行结果。我很难想象出需要这样做的情况。正如其他人指出的,不允许这样做可能是错误的,因为这会使编译器变得更加复杂。
英文:
Only example I can come up with, but never used nor seen in the wild, is to let another function populate your interface.
Example on Play. I can't really imagine a case where it is needed.
As others have pointed out, not allowing it would probably be wrong as that would make the compiler more complicated.
package main
import "fmt"
func main() {
var s fmt.Stringer
setMyStringer(&s)
fmt.Println("Hello, stringer:", s)
}
func setMyStringer(target *fmt.Stringer) {
*target = Stringable(5)
}
type Stringable int
func (s Stringable) String() string {
return fmt.Sprint(int(s))
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论