级联调用泛型函数时的泛型类型推断

在构建(我的第一个)泛型重库时,我遇到了泛型类型检查实现的一些明显限制——更可能是我缺乏知识。


任何想法如何让下面的东西工作?


package main


import (

    "fmt"

    "reflect"

)


type Number interface {

    int | float32

}


type MultiDimensionSlice interface {

    int | float32 | []int | []float32 | [][]int | [][]float32

}


func dimensions[S MultiDimensionSlice](s S) int {

    dims := 0

    t := reflect.TypeOf(s)

    for t.Kind() == reflect.Slice {

        dims += 1

        t = t.Elem()

    }

    return dims

}


func indirection[T Number](v T) int {

    var slice2D [][]T

    return dimensions(slice2D)

}


func main() {

    x := [][]float32{{1}, {2}, {3}}

    fmt.Printf("x=%v, dims=%d\n", x, dimensions(x))

    fmt.Printf("indirection should return 2, got %d\n", indirection(0))

}

这无法与消息一起编译[][]T does not implement MultiDimensionSlice ([][]T missing in int | float32 | []int | []float32 | [][]int | [][]float32)


但在函数内,indirection()所有允许的值都T将在dimensions().


任何帮助或指示将不胜感激!


(游乐场链接)


ps.: 我的问题比那复杂一点,但问题是一个泛型函数(indirection()在这个例子中)不能调用另一个(dimensions()这里)因为(显然)Go 编译器不能解析类型参数约束(信息在编译时存在......)。


当年话下
浏览 117回答 1
1回答

HUH函数

正如评论中提到的,go 在其泛型方面有一些限制。您可以通过解决方法实现所需的功能。首先,您需要更改您定义的接口。(也让它通用)type Number interface {    int | float32}type MultiDimensionSlice[T Number] interface {    Number | []T | [][]T}然后我们需要更改dimension方法类型参数。dimensions如果 go 让我们这样定义方法,那会更清晰func  dimensions[S Number](s MultiDimensionSlice[S]) int {但我们所能做的就是:func dimensions[S Number, K MultiDimensionSlice[S]](s K) int {    dims := 0    t := reflect.TypeOf(s)    for t.Kind() == reflect.Slice {        dims += 1        t = t.Elem()    }    return dims}然后我们需要改变我们调用dimensions方法的方式。我们需要提供一个额外的类型参数,以便可以推断类型参数Sfunc indirection[T Number](v T) int {    var slice2D [][]T    return dimensions[T](slice2D)}func main() {    x := [][]float32{{1}, {2}, {3}}    fmt.Printf("x=%v, dims=%d\n", x, dimensions[float32](x))    fmt.Printf("indirection should return 2, got %d\n", indirection(0))}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go