考虑 Go 语言中的这个例子:type I interface { get() string}type S struct {}func (s *S) get() string { return "here!"}var sSupplier = func() *S { return &S{}}func foo(supplier func () I) { i := supplier() println(i)}func main() { foo(sSupplier) // compile error, type mismatch}类型S继承接口I。但显然 typefunc () *S不继承func () I,所以我不能调用foowithsSupplier来代替supplier函数。有没有办法在不强制sSupplier返回类型的情况下修复它I?在 java 中,您可以使用泛型来执行类似<T extends I> void foo(Supplier<T> supplier) {...}then 调用类型的foo(sSupplier);操作。Supplier<S> sSupplier我不确定在go中是否可以使用类似的方法?
1 回答
qq_花开花谢_0
TA贡献1835条经验 获得超7个赞
如果您考虑一下泛型为您做了什么,它们实际上是一种要求编译器在现场编译匿名包装函数或 lambda 或从某些具体类型映射所需的任何内容的方法。也就是说,给定类似的东西(我将在这里使用 C++ 语法而不是 Java,因为我更熟悉 C++):
template<T>
void f(T obj) {
// do stuff with the object
}
你告诉编译器,当它看到f(int_value)它应该构建一个接受 a 的函数f,int当它看到它应该构建一个接受 af(struct S)的函数,依此类推。(这在 Java 中比在 C++ 的 C 基础中更自然一些,因为 Java 完成了整个参数匹配的事情来决定调用这些不同函数中的哪一个。)fstruct Sf
实际上,不是编写实际的函数,而是编写一个模板——因此是 C++ 关键字——编译器可以在编译时使用它来生成你真正想要的函数。由于 Go 缺乏泛型,因此它缺乏这种模板扩展技巧。
不过,这给您留下了几个明显的选择。一个例子是go:generate(参见,例如,Explain go generate in this example)。不过,在这种特别简单的情况下,您可以自己编写展开式:
foo(func() I { return sSupplier() })
在Go 操场上查看更完整的示例。我将您println(i)替换fmt.Printf("%#v\n", i)为以更有用的形式打印接口对象的值。
- 1 回答
- 0 关注
- 124 浏览
添加回答
举报
0/150
提交
取消