我目前正在嘗試通過通道將資料發送到 goroutine,然后該 goroutine 將進一步處理它。我的問題是我希望頻道能夠使用任何型別。為此,我正在研究 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
有沒有辦法正確地做到這一點?
我正在考慮不使用泛型而只使用 interface{} 作為型別,但這會使整個邏輯變得混亂,因為它需要決議(甚至可能不可能,因為資料可能相當復雜(嵌套結構))
uj5u.com熱心網友回復:
這是使用泛型的錯誤方式。
引數化型別,例如chan T必須先用具體的型別引數實體化,然后才能使用它。給定評論中建議的已定義 chan 型別:
type GenericChan[T any] chan T
您仍然需要使用具體型別實體化它:
c := make(GenericChan[int])
這使得使用型別引數有點沒有實際意義。
我不知道你的背景是什么,但考慮一下泛型長期以來一直穩定存在的語言。例如爪哇。并考慮典型的 Java 泛型收集器List<T>。你通常做的是用一個型別實體化它:
var list = new ArrayList<String>();
您在這里嘗試做的是宣告一個可以采用任何型別的通道。在 Java 中,可以容納任何型別的串列是什么?
var list = new ArrayList<Object>();
而在 Go 中,這只不過是
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
此時是foo什么?是string嗎?還是int? 您可以將任何內容發送到其中。這就是為什么像您的示例中的通用 chan 無法按您的預期作業。它必須是chan interface{},然后您像現在沒有泛型一樣鍵入斷言接收到的專案。
泛型的重點是撰寫使用任意型別的代碼,同時保持型別安全:
func receiveAny[T any](c chan T) T {
return <-c
}
您可以使用 achan int或 a呼叫它chan string。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/311154.html
上一篇:通用編碼型別
