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條經驗 獲得超16個贊
只有你能做的是,用 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 關注
- 133 瀏覽
添加回答
舉報