繁体   English   中英

golang函数类型继承?

[英]golang function type inheritance?

考虑这个 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 但显然类型func () *S没有继承func () I ,所以我不能用sSupplier调用foo代替supplier函数。 有没有办法在不强制sSupplier返回类型I情况下修复它?

在 Java 中,您可以使用泛型来执行类似<T extends I> void foo(Supplier<T> supplier) {...} foo(sSupplier); <T extends I> void foo(Supplier<T> supplier) {...}然后调用foo(sSupplier); 使用Supplier<S> sSupplier类型。 我不确定在 go 中是否可以使用类似的方法?

如果您稍微考虑一下泛型为您做什么,它们实际上是一种要求编译器在现场编译匿名包装函数或 lambda 或从某些具体类型映射所需的任何内容的方法。 也就是说,给定类似的东西(我将在这里使用 C++ 语法而不是 Java,因为我更熟悉 C++):

template<T>
void f(T obj) {
    // do stuff with the object
}

你告诉编译器,当它看到f(int_value)它应该构建一个接受int的函数f ,当它看到f(struct S)它应该构建一个接受struct S的函数f ,依此类推。 (这在 Java 中比在 C++ 的 C 基础中更自然一些,因为 Java 做了整个参数匹配的事情来决定调用这些各种f函数中的哪一个。)

实际上,不是编写实际的函数,而是编写一个模板(因此是 C++ 关键字),编译器可以使用它在编译时生成您真正想要的函数。 由于 Go 缺少泛型,因此它缺少这种模板扩展技巧。

不过,这给您留下了几个明显的选择。 一个例子是go:generate (参见,例如,在这个例子中解释 go generate )。 但是,在这种特别简单的情况下,您可以自己编写扩展:

foo(func() I { return sSupplier() })

Go playground上查看更完整的示例。 我用fmt.Printf("%#v\\n", i)替换你的println(i)以稍微更有用的形式打印接口对象的值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM