我正在将我的应用程序从 Java 重写为 Go,我知道这些语言以及范式完全不同,但我仍然设法转换几乎所有内容。
不幸的是,我无法将通用函数作为参数传递给另一个函数。在 Java 中它看起来像这样:
我有一个界面:
public interface Parser<T> {
public T parse(String line);
}
Run Code Online (Sandbox Code Playgroud)
fetch然后我在通用方法中使用这个接口
public static <T> List<T> fetch(Parser<T> parser) {
...
parser.parse(someLine);
...
return the list of generic types
}
Run Code Online (Sandbox Code Playgroud)
那么解析器方法如下所示:
class Parser{
static Foo ParseFoo(String line){
...
some custom parsing
...
}
}
Run Code Online (Sandbox Code Playgroud)
我这样使用它:
List<Foo> list = fetch(Parser::ParseFoo);
Run Code Online (Sandbox Code Playgroud)
我如何在 Go 中实现这一目标?
我尝试过声明通用接口、通用函数,但我无法理解这一点。
等效的通用Parser接口如下所示:
type Parser[T any] interface {\n Parse(line string) T\n}\nRun Code Online (Sandbox Code Playgroud)\n任何具有Parse(string) S方法的类型都会隐式满足Parser[S]接口。例如,以下类型Foo满足Parser[int]:
type Foo struct{}\n\nfunc (f Foo) Parse(string) int {\n return 0\n}\nRun Code Online (Sandbox Code Playgroud)\n然后,使用通用Parser接口,您可以实现通用Fetch功能:
func Fetch[T any](parser Parser[T]) []T {\n panic("not implemented")\n}\nRun Code Online (Sandbox Code Playgroud)\n那么,在 Go 中,您将如何执行相当于传递 Java静态方法的操作,如下ParseFoo()所示?
class Parser {\n static Foo ParseFoo(String line) {\n ...\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n在 Go 中,没有静态方法。函数可以附加到类型,在这种情况下它们就成为方法。因此,对于 Java 中的静态方法的情况,通常会在 Go 中得到非方法函数或独立函数:
\nfunc ParseFoo(line string) Foo {\n ...\n}\nRun Code Online (Sandbox Code Playgroud)\n为了使这个函数满足Parser[Foo]接口,可以定义如下ParserFunc适配器:
type ParserFunc[T any] func(string) T\n\nfunc (f ParserFunc[T]) Parse(line string) T {\n return f(line)\n}\nRun Code Online (Sandbox Code Playgroud)\n这样,从不ParseFoo附加到任何类型 \xe2\x80\x93 的独立函数 \xe2\x80\x93 中,您可以创建一个值ParserFunc[Foo],它确实满足Parser[Foo],并且只会在调用ParseFoo其Parse方法时调用:
f := ParserFunc[Foo](ParseFoo)\nRun Code Online (Sandbox Code Playgroud)\n最后,您可以将此f值传递给fetchsince fsatisfies Parser[Foo]:
fetch[Foo](f)\nRun Code Online (Sandbox Code Playgroud)\n请注意,您需要指定类型参数Foo,因为fetch编译器无法推断它。
如果您确实需要一个方法(即,像 Java 中的非静态/实例方法),那么您可能需要查看方法值。该过程将与此处公开的过程类似。
\n