go 支持多类型吗?(泛型类型)

type MyNumber interface {

    float32, float64, uint, int // this is not supported

}


func PrintNumber(n MyNumber) {

    switch n.(type) {

    case float32, float64, uint, int:

        fmt.Printf("%v\n", n)

    default:

        panic("PrintNumber only supports types float32, float64, uint, int")

    }

}

在go中,可以定义一个空白接口,基本上允许任何类型


var v interface{}

v = "string"

v = 0.1

有没有办法将允许的类型减少到特定的类型列表?


就像是


type MyNumber float32, float64, uint, int

或者


type MyNumber interface {

    float32, float64, uint, int

}

这样我就可以让编译器检查函数是否支持该类型。


回首忆惘然
浏览 180回答 3
3回答

白猪掌柜的

有没有办法将允许的类型减少到 [空接口] 的特定类型列表?在编译时,没有。但是,您可以选择在运行时使用限制。当有其他选择时,应该避免这种情况,因为它不能提供足够的安全性。这是在标准库中的许多地方完成的,例如 json marshaler,它需要一个指针作为目标。

ITMISS

您不能在编译时以您想要的方式强制使用一组具体类型。您可以做的是使用接口。列出您期望从实现中获得的接口中的方法。那么具体的运行时类型是什么就无关紧要了。您仅通过接口与值交互,这在编译时保证它是由传递的值实现的。例如,如果您希望该值提供一个int32值,请使用此接口:type HasInt32 interface {    Int32() int32}func f(i HasInt32) {    fmt.Println("int32 value:", i.Int32())}int32传递的值是否具有或float64作为其基础类型,或者它是任何其他复杂类型都无关紧要。你需要一个int32,这就是你得到的。实现者负责如何产生该值。例如:type MyInt32 int32func (m MyInt32) Int32() int32 { return int32(m) }type MyStruct struct {    i int64}func (m MyStruct) Int32() int32 { return int32(m.i) }测试它:var m MyInt32 = 1f(m)var s MyStruct = MyStruct{i: 2}f(s)哪些输出(在Go Playground上尝试):int32 value: 1int32 value: 2

30秒到达战场

有没有办法将允许的类型减少到特定的类型列表?是的,从 Go 1.18 开始,使用带有类型元素的接口。但是这样的接口只能作为类型参数的约束。在规范的草案版本中,接口类型下提到了这一点:包含非接口类型、~T 形式的术语或联合的接口只能用作类型约束,或用作用作约束的其他接口的元素。它们不能是值或变量的类型,也不能是其他非接口类型的组件。简而言之,在接口中,除了方法签名和其他嵌入式接口之外,您现在可以添加类型元素。这定义了一个类型约束,即“相应类型参数的允许类型参数集”。尤其:接口约束可以指定一个或多个类型元素。它将类型参数限制为指定的类型。您可以将多个类型元素指定为联合(更多信息:Go Generics - Unions)type MyNumber interface {    float32 | float64 | uint | int}您可以使用标记~来指定近似元素,即基础类型为的所有类型的集合T(更多信息:Go 中新标记〜的含义是什么(近似元素)?)。这些也可以是工会的一部分。type MyNumber interface {    ~float32 | ~float64 | ~uint | ~int}您仍然可以在这样的接口中指定方法签名。它将类型参数限制为也实现接口的那些类型的集合:// set of types with underlying int that also implement `String() string`type MyNumber interface {    ~int    String() string}作为上述推论,如果接口指定了非近似的预声明类型和方法,则没有类型会满足接口(因为您不能在预声明类型上声明方法)// empty type settype MyNumber interface {    int    String() string}如前所述,您仅将其用作类型参数约束,您将无法在类型切换、声明变量等中使用它:func foo[T MyNumber](v T) {    // ...}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go