英文:
Returning Go Generic Type
问题
以下代码在第res = fmt.Sprintf("%s + %s", i, j)
行无法编译通过,报错信息为:cannot use fmt.Sprintf("%s + %s", i, j) (value of type string) as type T in assignment
。
如果我只是简单地return i + j
,它确实允许我返回一个int
,并且代码可以编译和运行。
我缺少一些基本的理解,需要指点正确的方向。
package main
import (
"fmt"
"reflect"
)
type Adder interface {
string | int
}
func Add[T Adder](i, j T) T {
var res T
switch reflect.TypeOf(i).Name() {
case "int":
res = i + j
case "string":
res = fmt.Sprintf("%s + %s", i, j)
}
return res
}
func main() {
it := Add(3, 4)
st := Add("one", "two")
fmt.Println("Int:", it)
fmt.Println("Str:", st)
}
英文:
The following fails to compile on line res = fmt.Sprintf("%s + %s", i, j)
with the error: cannot use fmt.Sprintf("%s + %s", i, j) (value of type string) as type T in assignment
It does allow me to return an int
and the code does compile and run if I simply return i + j
.
I'm missing some fundamental understanding and need to be pointed in the correct direction.
import (
"fmt"
"reflect"
)
type Adder interface {
string | int
}
func Add[T Adder](i, j T) T {
var res T
switch reflect.TypeOf(i).Name() {
case "int":
res = i + j
case "string":
res = fmt.Sprintf("%s + %s", i, j)
}
return res
}
func main() {
it := Add(3, 4)
st := Add("one", "two")
fmt.Println("Int:", it)
fmt.Println("Str:", st)
}
答案1
得分: 2
看一下Add
函数对字符串的操作:
func Add[string](i, j string) string {
var res string
switch reflect.TypeOf(i).Name() {
case "int":
res = i + j
case "string":
res = fmt.Sprintf("%s + %s", i, j)
}
return res
}
这是可以的。表达式i + j
只是将两个字符串连接起来。再看一下Add
函数对整数的操作:
func Add[int](i, j int) int {
var res int
switch reflect.TypeOf(i).Name() {
case "int":
res = i + j
case "string":
res = fmt.Sprintf("%s + %s", i, j)
}
return res
}
这是一个类型错误。并不重要"string"
分支在运行时永远不会被执行-整个函数必须进行类型检查!
(请注意,Go语言实际上不通过插入类型来实例化泛型-但你可以理解这个概念。)
英文:
Take a look at what Add
does for strings:
func Add[string](i, j string) string {
var res string
switch reflect.TypeOf(i).Name() {
case "int":
res = i + j
case "string":
res = fmt.Sprintf("%s + %s", i, j)
}
return res
}
This is ok. The expression i + j
just concatenates two strings. Take a look at what Add
does for int
:
func Add[int](i, j int) int {
var res int
switch reflect.TypeOf(i).Name() {
case "int":
res = i + j
case "string":
res = fmt.Sprintf("%s + %s", i, j)
}
return res
}
This is a type error. It does not matter that the "string"
branch is never taken at runtime—the entire function must typecheck!
(Note that Go does not actually instantiate generics by inserting the types—but you get the idea.)
答案2
得分: 1
通用函数的主体必须对所有可能的类型都有效。如果res
是int,那么"string"情况无法编译。如果res
是string,那么两种情况都是有效的表达式。
您可以通过声明以下内容来尝试这个想法:
type Adder interface {
string
}
并进行必要的更改。您仍然需要:
res = T(fmt.Sprintf("%s + %s", i, j))
英文:
The body of the generic function must be valid for all possible types. If res
is int, the "string" case cannot be compiled. If res
is string, both cases are valid expressions.
You can try this idea by declaring
type Adder interface {
string
}
and making the necessary changes. You still need to:
res = T(fmt.Sprintf("%s + %s", i, j))
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论