为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
萧十郎 2022-10-04 19:26:38
我目前正在尝试通过通道将数据发送到戈鲁廷,然后戈鲁廷将进一步处理它。我的问题是,我希望频道能够与任何类型一起使用。为此,我正在研究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有没有办法正确地做到这一点?我正在考虑不使用泛型,而只使用接口{}作为类型,但这会使整个逻辑变得混乱,因为它需要解析(甚至可能是不可能的,因为数据可能相当复杂(嵌套结构))
查看完整描述

1 回答

?
小怪兽爱吃肉

TA贡献1852条经验 获得超1个赞

这是使用泛型的错误方法。


参数化类型(如)必须先使用具体类型参数进行实例化,然后才能使用它。给定一个已定义的 chan 类型:chan T


type GenericChan[T any] chan T

您仍然需要使用具体类型实例化它:


c := make(GenericChan[int])

这使得使用类型参数有点没有意义。


我不知道你的背景是什么,但考虑一下泛型长期以来一直稳定的语言。例如,爪哇。并考虑典型的 Java 通用收集器 。您通常要做的是使用类型实例化它:List<T>


var list = new ArrayList<String>(); 

您在这里尝试做的是声明一个可以采用任何类型的通道。在Java中,可以包含任何类型的列表是什么?


var list = new ArrayList<Object>(); 

在围棋中,那无非是别的


c := make(chan interface{})

你可以用另一种方式来看待它:你如何期望这个通用的chan在接收操作上工作?


c := make(GenericChan) // wrong syntax: instantiating without type param

c <- "a string"        // let's pretend you can send anything into it


// ...


foo := <-c 

在这一点上,什么是?是 ?还是一个?你可以发送任何东西。这就是为什么像你的例子中的通用chan不能按照你的意图工作。它必须是,然后你类型断言收到的项目,就像你现在没有泛型一样。foostringintchan interface{}


泛型的要点是编写使用任意类型的代码,同时保持类型安全:


func receiveAny[T any](c chan T) T {

    return <-c

}

您可以使用 或 .chan intchan string


查看完整回答
反对 回复 2022-10-04
  • 1 回答
  • 0 关注
  • 74 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号