猿问

如何声明和使用可以存储字符串和 int 值的结构字段?

我有以下结构:


type testCase struct {

   input   string

   isValid bool

}

我想在多个测试中使用这个结构,输入可以是 astring或 anint等。

我可以在处理时将int输入转换为string并将其转换回int,或者我可以定义两个不同的结构,例如testCaseInt,testCaseStruct这将解决我的问题,但怎么做我通过转换input为interface?


我是 Go 新手,并尝试用谷歌搜索,但可能找不到,因为我不知道要搜索什么。


杨魅力
浏览 94回答 4
4回答

动漫人物

如何在 Go 中声明和使用可以同时存储字符串和 int 值的变量?你不能。Go 的类型系统(从 Go 1.17 开始)不提供 sum 类型。你将不得不等待 Go 1.18。

明月笑刀无情

权衡是在静态类型和灵活容器之间。在 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,请使用联合约束。

侃侃尔雅

只有你能做的是,用 interface{} 改变字符串检查播放(它工作正常)https://go.dev/play/p/pwSZiZp5oVxpackage mainimport "fmt"type testCase struct {&nbsp; &nbsp; input&nbsp; &nbsp;interface{}&nbsp; &nbsp; isValid bool}func main() {&nbsp; &nbsp; test1 := testCase{}&nbsp; &nbsp; test1.input = "STRING".&nbsp; // <-------------------STRING&nbsp; &nbsp; fmt.Printf("input: %v \n", test1)&nbsp; &nbsp; test2 := testCase{}&nbsp; &nbsp; test2.input = 1&nbsp; &nbsp; &nbsp; // <-------------------INT&nbsp; &nbsp; fmt.Printf("input: %v \n", test2)}

守候你守候我

方法一:package mainimport (&nbsp; &nbsp; "fmt")func main() {&nbsp; &nbsp; var a interface{}&nbsp; &nbsp; a = "hi"&nbsp; &nbsp; if valString, ok := a.(string); ok {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Printf("String: %s", valString)&nbsp; &nbsp; }&nbsp; &nbsp; a = 1&nbsp; &nbsp; if valInt, ok := a.(int); ok {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Printf("\nInteger: %d", valInt)&nbsp; &nbsp; }}方法二:package mainimport (&nbsp; &nbsp; "fmt")func main() {&nbsp; &nbsp; print("hi")&nbsp; &nbsp; print(1)}func print(a interface{}) {&nbsp; &nbsp; switch t := a.(type) {&nbsp; &nbsp; case int:&nbsp; &nbsp; &nbsp; &nbsp; fmt.Printf("Integer: %v\n", t)&nbsp; &nbsp; case string:&nbsp; &nbsp; &nbsp; &nbsp; fmt.Printf("String: %v\n", t)&nbsp; &nbsp; }}
随时随地看视频慕课网APP

相关分类

Go
我要回答