golang錯題集

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

本文即Go語言的那些坑三。

不要對Go並發函數的執行時機做任何假設

請看下列的列子:

12345678910111213141516
import ("fmt""runtime""time")func main(){names := []string{"lily", "yoyo", "cersei", "rose", "annei"}for _, name := range names{go func(){fmt.Println(name)}()}runtime.GOMAXPROCS(1)runtime.Gosched()}

請問輸出什嗎?

答案:

12345
anneianneianneianneiannei

為什麼呢?是不是有點詫異?
輸出的都是“annei”,而“annei”又是“names”的最後一個元素,那麼也就是說程式列印出了最後一個元素的值,而name對於匿名函數來講又是一個外部的值。因此,我們可以做一個推斷:雖然每次迴圈都啟用了一個協程,但是這些協程都是引用了外部的變數,當協程建立完畢,再執行列印動作的時候,name的值已經不知道變為啥了,因為主函數協程也在跑,大家並行,但是在此由於names數組長度太小,當協程建立完畢後,主函數迴圈早已結束,所以,列印出來的都是遍曆的names最後的那一個元素“annei”。
如何證實以上的推斷呢?
其實很簡單,每次迴圈結束後,停頓一段時間,等待協程列印當前的name便可。

1234567891011121314151617
import ("fmt""runtime""time")func main(){names := []string{"lily", "yoyo", "cersei", "rose", "annei"}for _, name := range names{go func(){fmt.Println(name)}()time.Sleep(time.Second)}runtime.GOMAXPROCS(1)runtime.Gosched()}

列印結果:

12345
lilyyoyocerseiroseannei

以上我們得出一個結論,不要對“go函數”的執行時機做任何的假設,除非你確實能做出讓這種假設成為絕對事實的保證。

假設T類型的方法上接收器既有T類型的,又有*T指標類型的,那麼就不可以在不能定址的T值上調用*T接收器的方法

請看代碼,試問能正常編譯通過嗎?

1234567891011121314151617181920
import ("fmt")type Lili struct{Name string}func (Lili *Lili) fmtPointer(){fmt.Println("poniter")}func (Lili Lili) fmtReference(){fmt.Println("reference")}func main(){li := Lili{}li.fmtPointer()}

答案:

1
能正常編譯通過,並輸出"poniter"

感覺有點詫異,請接著看以下的代碼,試問能編譯通過?

12345678910111213141516171819
import ("fmt")type Lili struct{Name string}func (Lili *Lili) fmtPointer(){fmt.Println("poniter")}func (Lili Lili) fmtReference(){fmt.Println("reference")}func main(){Lili{}.fmtPointer()}

答案:

123
不能編譯通過。“cannot call pointer method on Lili literal”“cannot take the address of Lili literal”

是不是有點奇怪?這是為什麼呢?其實在第一個程式碼範例中,main主函數中的“li”是一個變數,li的雖然是類型Lili,但是li是可以定址的,&li的類型是Lili,因此可以調用Lili的方法。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.