<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                ## 題目 對已經關閉的的 chan 進行讀寫,會怎么樣?為什么? ## 回答 * 讀已經關閉的 chan 能一直讀到東西,但是讀到的內容根據通道內關閉前是否有元素而不同。 * 如果 chan 關閉前,buffer 內有元素還未讀 , 會正確讀到 chan 內的值,且返回的第二個 bool 值(是否讀成功)為 true。 * 如果 chan 關閉前,buffer 內有元素已經被讀完,chan 內無值,接下來所有接收的值都會非阻塞直接成功,返回 channel 元素的零值,但是第二個 bool 值一直為 false。 * 寫已經關閉的 chan 會 panic ## 示例 ### 1\. 寫已經關閉的 chan ~~~go func main(){ c := make(chan int,3) close(c) c <- 1 } //輸出結果 panic: send on closed channel goroutine 1 [running] main.main() ... ~~~ * 注意這個 send on closed channel,待會會提到。 ### 2\. 讀已經關閉的 chan ~~~go package main import "fmt" func main() { fmt.Println("以下是數值的chan") ci:=make(chan int,3) ci<-1 close(ci) num,ok := <- ci fmt.Printf("讀chan的協程結束,num=%v, ok=%v\n",num,ok) num1,ok1 := <-ci fmt.Printf("再讀chan的協程結束,num=%v, ok=%v\n",num1,ok1) num2,ok2 := <-ci fmt.Printf("再再讀chan的協程結束,num=%v, ok=%v\n",num2,ok2) fmt.Println("以下是字符串chan") cs := make(chan string,3) cs <- "aaa" close(cs) str,ok := <- cs fmt.Printf("讀chan的協程結束,str=%v, ok=%v\n",str,ok) str1,ok1 := <-cs fmt.Printf("再讀chan的協程結束,str=%v, ok=%v\n",str1,ok1) str2,ok2 := <-cs fmt.Printf("再再讀chan的協程結束,str=%v, ok=%v\n",str2,ok2) fmt.Println("以下是結構體chan") type MyStruct struct{ Name string } cstruct := make(chan MyStruct,3) cstruct <- MyStruct{Name: "haha"} close(cstruct) stru,ok := <- cstruct fmt.Printf("讀chan的協程結束,stru=%v, ok=%v\n",stru,ok) stru1,ok1 := <-cs fmt.Printf("再讀chan的協程結束,stru=%v, ok=%v\n",stru1,ok1) stru2,ok2 := <-cs fmt.Printf("再再讀chan的協程結束,stru=%v, ok=%v\n",stru2,ok2) } ~~~ 輸出結果 ~~~shell 以下是數值的chan 讀chan的協程結束,num=1, ok=true 再讀chan的協程結束,num=0, ok=false 再再讀chan的協程結束,num=0, ok=false 以下是字符串chan 讀chan的協程結束,str=aaa, ok=true 再讀chan的協程結束,str=, ok=false 再再讀chan的協程結束,str=, ok=false 以下是結構體chan 讀chan的協程結束,stru={haha}, ok=true 再讀chan的協程結束,stru=, ok=false 再再讀chan的協程結束,stru=, ok=false ~~~ ## 多問一句 ### 1\. 為什么寫已經關閉的`chan`就會`panic`呢? ~~~go //在 src/runtime/chan.go func chansend(c *hchan,ep unsafe.Pointer,block bool,callerpc uintptr) bool { //省略其他 if c.closed != 0 { unlock(&c.lock) panic(plainError("send on closed channel")) } //省略其他 } ~~~ * 當`c.closed != 0`則為通道關閉,此時執行寫,源碼提示直接`panic`,輸出的內容就是上面提到的`"send on closed channel"`。 ### 2\. 為什么讀已關閉的 chan 會一直能讀到值? ~~~go func chanrecv(c *hchan,ep unsafe.Pointer,block bool) (selected,received bool) { //省略部分邏輯 lock(&c.lock) //當chan被關閉了,而且緩存為空時 //ep 是指 val,ok := <-c 里的val地址 if c.closed != 0 && c.qcount == 0 { if receenabled { raceacquire(c.raceaddr()) } unlock(&c.lock) //如果接受之的地址不空,那接收值將獲得一個該值類型的零值 //typedmemclr 會根據類型清理響應的內存 //這就解釋了上面代碼為什么關閉的chan 會返回對應類型的零值 if ep != null { typedmemclr(c.elemtype,ep) } //返回兩個參數 selected,received // 第二個采納數就是 val,ok := <- c 里的 ok //也就解釋了為什么讀關閉的chan會一直返回false return true,false } } ~~~ * `c.closed != 0 && c.qcount == 0`指通道已經關閉,且緩存為空的情況下(已經讀完了之前寫到通道里的值) * 如果接收值的地址`ep`不為空 * 那接收值將獲得是一個該類型的零值 * `typedmemclr`會根據類型清理相應地址的內存 * 這就解釋了上面代碼為什么關閉的 chan 會返回對應類型的零值
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看