4 回答
TA贡献1815条经验 获得超10个赞
如何在 Go 中声明和使用可以同时存储字符串和 int 值的变量?
你不能。Go 的类型系统(从 Go 1.17 开始)不提供 sum 类型。
你将不得不等待 Go 1.18。
TA贡献1828条经验 获得超4个赞
权衡是在静态类型和灵活容器之间。
在 Go 1.17 之前,您不能拥有具有不同静态类型的结构字段。最好的方法是interface{}, 然后在使用时断言动态类型。这有效地允许您testCases在运行时拥有任一类型的容器。
type testCase struct {
input interface{}
isValid bool
}
func main() {
// can initialize container with either type
cases := []testCase{{500, false}, {"foobar", true}}
// must type-assert when using
n := cases[0].(int)
s := cases[1].(string)
}
使用 Go 1.18,您可以稍微提高类型安全性,以换取更少的灵活性。
使用联合对结构进行参数化。这静态地限制了允许的类型,但现在必须显式实例化结构,因此您不能拥有具有不同实例化的容器。这可能与您的目标兼容,也可能不兼容。
type testCase[T int | string] struct {
input T
isValid bool
}
func main() {
// must instantiate with a concrete type
cases := []testCase[int]{
{500, false}, // ok, field takes int value
/*{"foobar", true}*/, // not ok, "foobar" not assignable to int
}
// cases is a slice of testCase with int fields
}
不,实例化testCase[any]是一个红鲱鱼。首先,any只是不满足约束int | string;即使您放松了这一点,它实际上也比 Go 1.17 解决方案更糟糕,因为现在您不能只testCase在函数参数中使用,而是必须使用完全testCase[any].
使用联合参数化结构,但仍使用interface{}/any作为字段类型:(如何)我可以在 go 中实现通用的“Either”类型吗?. 这也不允许同时拥有两种类型的容器。
一般来说,如果您的目标是使用任一类型的灵活容器类型(切片、映射、通道),则必须将字段保持为interface{}/any并断言使用情况。如果您只想在编译时重用具有静态类型的代码并且您使用的是 Go 1.18,请使用联合约束。
TA贡献1801条经验 获得超15个赞
只有你能做的是,用 interface{} 改变字符串
检查播放(它工作正常)
https://go.dev/play/p/pwSZiZp5oVx
package main
import "fmt"
type testCase struct {
input interface{}
isValid bool
}
func main() {
test1 := testCase{}
test1.input = "STRING". // <-------------------STRING
fmt.Printf("input: %v \n", test1)
test2 := testCase{}
test2.input = 1 // <-------------------INT
fmt.Printf("input: %v \n", test2)
}
TA贡献1802条经验 获得超10个赞
方法一:
package main
import (
"fmt"
)
func main() {
var a interface{}
a = "hi"
if valString, ok := a.(string); ok {
fmt.Printf("String: %s", valString)
}
a = 1
if valInt, ok := a.(int); ok {
fmt.Printf("\nInteger: %d", valInt)
}
}
方法二:
package main
import (
"fmt"
)
func main() {
print("hi")
print(1)
}
func print(a interface{}) {
switch t := a.(type) {
case int:
fmt.Printf("Integer: %v\n", t)
case string:
fmt.Printf("String: %v\n", t)
}
}
- 4 回答
- 0 关注
- 93 浏览
添加回答
举报