猿问

使用具有不同运行时类型的通用容器

我目前正在尝试通过通道将数据发送到戈鲁廷,然后戈鲁廷将进一步处理它。我的问题是,我希望频道能够与任何类型一起使用。为此,我正在研究Go 1.18中新引入的泛型。


我的问题是,当我启动它时,我需要告诉goroutine通道的类型,这是不可能分辨的,因为它可以保存任何数据。


这就是我现在得到的:


线:


func StartController[T any](sender chan Packet[T]) {

    go runThread(sender)

}


func runThread[T any](sender chan Packet[T]) {

    fmt.Println("in thread")

    for true {

        data := <- sender


        fmt.Println(data)

    }

}

我的测试函数是这样的:


func main() {

    sender := make(chan Packet)


    StartController(sender)


    sender <- Packet[int]{

        Msg: Message[int]{

            Data: 1,

        },

    }


    sender <- Packet[string]{

        Msg: Message[string]{

            Data: "asd",

        },

    }


    for true {}

}

类型:


type Message[T any] struct {

    Data T

}


type Packet[T any] struct {

    Msg Message[T]

}

现在,由于以下原因,此代码无法编译


.\test.go:8:22: cannot use generic type Packet[T interface{}] without instantiation

有没有办法正确地做到这一点?


我正在考虑不使用泛型,而只使用接口{}作为类型,但这会使整个逻辑变得混乱,因为它需要解析(甚至可能是不可能的,因为数据可能相当复杂(嵌套结构))


萧十郎
浏览 75回答 1
1回答

小怪兽爱吃肉

这是使用泛型的错误方法。参数化类型(如)必须先使用具体类型参数进行实例化,然后才能使用它。给定一个已定义的 chan 类型:chan Ttype GenericChan[T any] chan T您仍然需要使用具体类型实例化它:c := make(GenericChan[int])这使得使用类型参数有点没有意义。我不知道你的背景是什么,但考虑一下泛型长期以来一直稳定的语言。例如,爪哇。并考虑典型的 Java 通用收集器 。您通常要做的是使用类型实例化它:List<T>var list = new ArrayList<String>();&nbsp;您在这里尝试做的是声明一个可以采用任何类型的通道。在Java中,可以包含任何类型的列表是什么?var list = new ArrayList<Object>();&nbsp;在围棋中,那无非是别的c := make(chan interface{})你可以用另一种方式来看待它:你如何期望这个通用的chan在接收操作上工作?c := make(GenericChan) // wrong syntax: instantiating without type paramc <- "a string"&nbsp; &nbsp; &nbsp; &nbsp; // let's pretend you can send anything into it// ...foo := <-c&nbsp;在这一点上,什么是?是 ?还是一个?你可以发送任何东西。这就是为什么像你的例子中的通用chan不能按照你的意图工作。它必须是,然后你类型断言收到的项目,就像你现在没有泛型一样。foostringintchan interface{}泛型的要点是编写使用任意类型的代码,同时保持类型安全:func receiveAny[T any](c chan T) T {&nbsp; &nbsp; return <-c}您可以使用 或 .chan intchan string
随时随地看视频慕课网APP

相关分类

Go
我要回答