第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

為什么通道的通道方向變化不能兼容?

為什么通道的通道方向變化不能兼容?

Go
慕工程0101907 2021-07-07 16:57:51
我喜歡編程提供盡可能嚴格的接口,以避免錯誤的使用,因為它是明確的和自我記錄的。所以,當用戶應該單向使用時,我喜歡提供定向通道,但當然,在內(nèi)部我有一個雙向通道副本。分配以下作品:var internal chan intvar external <-chan intexternal = internal但是現(xiàn)在我想向用戶提供一個<-chan chan<- int類型(在函數(shù)的返回中),但以下方法不起作用:var internal chan chan intvar external <-chan chan<- intexternal = internal // this fails我有兩個問題:究竟為什么這不起作用?所以,我可以聲明一個<-chan chan<-類型的變量,但是......不能在任何實際意義上使用這樣的類型?(因為即使有定向通道,它們也是用于編排雙向通道的 AFAIK,并且由于不可能進行分配,因此不能以這種方式使用)
查看完整描述

3 回答

?
慕容森

TA貢獻1853條經(jīng)驗 獲得超18個贊

這不起作用的原因

規(guī)范說明了有關通道可分配性的內(nèi)容:


[通道] 值x可分配給類型變量T(“x 可分配給 T”)[當]x是雙向通道值,T是通道類型,x的類型V并T具有相同的元素類型,并且至少有一個V或T不是命名類型。


這正是您所經(jīng)歷的:


chan (chan int)以<- chan (chan int)作品

chan (chan int)對<- chan (chan<- int)不

原因是元素類型(chan關鍵字之后的)不相等。


我可以申報但不能使用嗎?

您可以使用它,但不能以您想要的方式使用。不可能按照您的方式分配變量,但通過更正元素類型,您確實可以使用它:


var internal chan chan<- int

var external <-chan chan<- int

external = internal

如果你只有你的chan chan int類型,你需要復制你的值(播放示例):


var internal chan chan int

var internalCopy chan chan<- int


go func() { for e := range internal { internalCopy <- e } }()


var external <-chan chan<- int

external = internalCopy


查看完整回答
反對 回復 2021-07-12
?
慕運維8079593

TA貢獻1876條經(jīng)驗 獲得超5個贊

這種情況有點類似于在具有用戶級泛型的語言中遇到的協(xié)變和逆變問題。在 Go 中使用泛型類型的內(nèi)部等價物(它們被稱為“復合類型”)時,您也可以遇到它。例如:


type A struct{}


// All `B`s are convertible to `A`s

type B A

甚至:


type A interface{}

// B embeds A

type B interface{ A }


var b B

// This works without problem

var a A = A(b)

但請考慮以下情況:


var bs []B

var as []A = ([]A)(bs)

在這里,編譯失敗并顯示錯誤cannot use bs (type []B) as type []A in assignment。盡管 anyB可以轉換為等效的A,但這不適用于[]Band []A(或chan Band chan A、 or map[string]Band map[string]A、 or func(a A)andfunc(b B)或在其定義中使用As 和Bs 的任何其他泛型類型)。盡管類型可以相互轉換,但它們并不相同,這些generics在 Go 中的工作方式來自規(guī)范:


每個類型 T 都有一個底層類型:如果 T 是預先聲明的類型或類型文字,則對應的底層類型是 T 本身。否則,T 的基礎類型是 T 在其類型聲明中引用的類型的基礎類型。


type T1 string

type T2 T1

type T3 []T1

type T4 T3

字符串、T1 和 T2 的基礎類型是字符串。[]T1、T3 和 T4 的基礎類型是 []T1。


請注意,這里的基礎類型[]T1是[]T1,而不是[]string。這意味著[]T2will的基礎類型是[]T2,not []stringor []T1,這使得它們之間的轉換變得不可能。


基本上,您正在嘗試執(zhí)行以下操作:


var internal chan Type1

var external <-chan Type2

external = internal

這是失敗Type1和Type2兩種不同的類型,至于類型系統(tǒng)而言。


協(xié)變和逆變是非常困難的問題,因為維基百科文章的長度或在 Java 或 C# 中解開有界泛型層所花費的任何時間都會告訴您。這是泛型如此難以實現(xiàn)并引發(fā)如此多爭論的原因之一。


您可以通過在只讀和讀/寫通道之間的別名上更深一層來獲得所需的行為,就像您在第一個示例中對internal/external通道所做的一樣:


package main


import "fmt"


// This has the correct signature you wanted

func ExportedFunction(c <-chan (chan<- int)) {

    // Sends 1 to the channel it receives

    (<-c)<- 1

}


func main() {

    // Note that this is a READ/WRITE channel of WRITE-ONLY channels

    // so that the types are correct

    internal := make(chan (chan<- int))

    var external <-chan (chan<- int)

    // This works because the type of elements in the channel is the same

    external = internal


    // This channel is internal, so it is READ/WRITE

    internal2 := make(chan int)


    // This is typically called externally

    go ExportedFunction(external)


    fmt.Println("Sending channel...")

    // The type of internal makes the receiving end of internal/external

    // see a WRITE-ONLY channel

    internal <- internal2

    fmt.Println("We received:")

    fmt.Println(<-internal2)

}

同樣的事情在操場上。


基本上與您的第一個示例相同,除了您必須在“讀/寫”與“僅讀(或寫)”別名中更深入一層。


查看完整回答
反對 回復 2021-07-12
  • 3 回答
  • 0 關注
  • 210 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網(wǎng)微信公眾號