英文:
Defining a named function type that returns any type
问题
我想定义一个函数类型(在C#中称为委托),其返回值可以是任何类型(在编译时未知),在阅读Go文档后,我发现当前版本的语言不支持泛型。
在StackOverflow上搜索后,我看到一篇帖子建议将返回类型设置为interface{}
,这意味着该函数可以返回任何类型。然后我编写了以下代码来测试它的工作原理:
type Consumer func() interface {}
func TestConsumer() Consumer {
return func() string {
return "ok"
}
}
但是我得到了以下错误:
无法将函数文字(类型为func() string)用作返回参数中的Consumer类型
而当我将Consumer
的返回类型更改为string
时,它可以正常工作。
问题是我做错了什么,如何编写一个可以返回任何类型的函数类型(委托)并将实际函数分配给它?
英文:
I would like to define a function type (what we call delegate in C#) whose return value can be anything (is unknown at compile type) and after reading Go docs I found that the current version of the language does not support generics.
After searching StackOverflow I came across a post suggesting that the return type can be set as interface{}
which implies that any type can be returned by that function. Then I wrote the following code to test how it works:
type Consumer func() interface {}
func TestConsumer() Consumer {
return func() string {
return "ok"
}
}
But I got the following error
> cannot use func literal (type func() string) as type Consumer in return argument
This is while when I change the return type of Consumer
to string
, it works without any problem.
The question is what is that I am doing wrong and how can I achieve writing a function type (delegate) that can return anything and assign an actual functions to that?
答案1
得分: 1
问题在于函数类型 func() string
不符合函数类型 func() interface{}
。
原因是函数类型 func() interface{}
表示一个显式返回 interface{}
类型值的函数,而 string
类型可以轻松地转换为 interface{}
,但是整体的 函数签名 是不同的。
正确的代码应该是:
type Consumer func() interface {}
func TestConsumer() Consumer {
return func() interface{} {
return "ok"
}
}
字符串会隐式转换为 interface{}
类型,函数签名相同。
英文:
The issue is that the function type func() string
does not conform to the function type func() interface{}
.
The reason for this is because the function type func() interface{}
means a function that explicitly returns a value of type interface{}
, and while a string
can be easily casted to an interface{}
, the overall function signatures are not the same.
The correct code would be:
type Consumer func() interface {}
func TestConsumer() Consumer {
return func() interface{} {
return "ok"
}
}
The string gets implicity casted to the interface{}
type, and the function signatures are the same.
答案2
得分: 1
如果您可以使用Go 1.18,可以使用类型参数来定义自己的通用命名函数类型。然后,您可以在其他通用函数中使用它,并在需要时使用类型参数进行实例化,或者使用具体类型进行实例化:
假设一个返回T
的函数被称为"producer":
type Producer[T any] func() T
// 使用具体类型进行实例化
func TestProducer() Producer[string] {
return func() string {
return "ok"
}
}
// 使用类型参数进行实例化
func TestProducer[T any]() Producer[T] {
return func() T {
return *new(T)
}
}
在后一种情况下,您将需要实例化TestProducer
—— 一般规则是,在某个时刻,类型参数必须在编译时已知。
func main() {
fn := TestProducer[string]()
foo := fn()
fmt.Println(foo) // foo 是空字符串
fn2 := TestProducer[uint64]()
bar := fn2()
fmt.Println(bar) // bar 是 0
}
Playground: https://go.dev/play/p/HDmgV_vu7MN
英文:
If you can use Go 1.18, use type parameters to define your own generic named function type. You can then use it in other generic functions and instantiate it with a type parameter, or instantiate it with concrete types when needed:
<sup>let's say that a function that returns T
is called a "producer" though</sup>
type Producer[T any] func() T
// instantiate with concrete type
func TestProducer() Producer[string] {
return func() string {
return "ok"
}
}
// instantiate with type parameter
func TestProducer[T any]() Producer[T] {
return func() T {
return *new(T)
}
}
In the latter case, you'll have to instantiate TestProducer
— the general rule being, at some point the type parameters must be known at compile time.
func main() {
fn := TestProducer[string]()
foo := fn()
fmt.Println(foo) // foo is the empty string
fn2 := TestProducer[uint64]()
bar := fn2()
fmt.Println(bar) // bar is 0
}
Playground: https://go.dev/play/p/HDmgV_vu7MN
答案3
得分: -1
func TestConsumer() interface{} {
return func() string {
return "ok"
}
}
请尝试使用这个代码。
英文:
func TestConsumer() interface{} {
return func() string {
return "ok"
}
}
Please try with this one
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论