<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>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                不要對Go并發函數的執行時機做任何假設 請看下列的列子: ~~~ 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() } ~~~ 請問輸出什么? 答案: ~~~ annei annei annei annei annei ~~~ 為什么呢?是不是有點詫異? 輸出的都是“annei”,而“annei”又是“names”的最后一個元素,那么也就是說程序打印出了最后一個元素的值,而name對于匿名函數來講又是一個外部的值。因此,我們可以做一個推斷:雖然每次循環都啟用了一個協程,但是這些協程都是引用了外部的變量,當協程創建完畢,再執行打印動作的時候,name的值已經不知道變為啥了,因為主函數協程也在跑,大家并行,但是在此由于names數組長度太小,當協程創建完畢后,主函數循環早已結束,所以,打印出來的都是遍歷的names最后的那一個元素“annei”。 如何證實以上的推斷呢? 其實很簡單,每次循環結束后,停頓一段時間,等待協程打印當前的name便可。 ~~~ 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() } ~~~ 打印結果: ~~~ lily yoyo cersei rose annei ~~~ 以上我們得出一個結論,不要對“go函數”的執行時機做任何的假設,除非你確實能做出讓這種假設成為絕對事實的保證。 假設T類型的方法上接收器既有T類型的,又有*T指針類型的,那么就不可以在不能尋址的T值上調用*T接收器的方法 請看代碼,試問能正常編譯通過嗎? ~~~ 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() } ~~~ 答案: 能正常編譯通過,并輸出"poniter" 感覺有點詫異,請接著看以下的代碼,試問能編譯通過? ~~~ 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() } ~~~ 答案: 不能編譯通過。 ~~~ “cannot call pointer method on Lili literal” “cannot take the address of Lili literal” ~~~ 是不是有點奇怪?這是為什么呢?其實在第一個代碼示例中,main主函數中的“li”是一個變量,li的雖然是類型Lili,但是li是可以尋址的,&li的類型是*Lili,因此可以調用*Lili的方法。 一個包含nil指針的接口不是nil接口 請看下列代碼,試問返回什么 ~~~ import ( "bytes" "fmt" "io" ) const debug = true func main(){ var buf *bytes.Buffer if debug{ buf = new(bytes.Buffer) } f(buf) } func f(out io.Writer){ if out != nil{ fmt.Println("surprise!") } } ~~~ 答案是輸出:surprise。 ok,讓我們吧debug開關關掉,及debug的值變為false。那么輸出什么呢?是不是什么都不輸出? ~~~ import ( "bytes" "fmt" "io" ) const debug = false func main(){ var buf *bytes.Buffer if debug{ buf = new(bytes.Buffer) } f(buf) } func f(out io.Writer){ if out != nil{ fmt.Println("surprise!") } } ~~~ 答案是:依然輸出surprise。 這是為什么呢? 這就牽扯到一個概念了,是關于接口值的。概念上講一個接口的值分為兩部分:一部分是類型,一部分是類型對應的值,他們分別叫:動態類型和動態值。類型系統是針對編譯型語言的,類型是編譯期的概念,因此類型不是一個值。 在上述代碼中,給f函數的out參數賦了一個*bytes.Buffer的空指針,所以out的動態值是nil。然而它的動態類型是bytes.Buffer,意思是:“A non-nil interface containing a nil pointer”,所以“out!=nil”的結果依然是true。 但是,對于直接的``bytes.Buffer``類型的判空不會出現此問題。 ~~~ import ( "bytes" "fmt" ) func main(){ var buf *bytes.Buffer if buf == nil{ fmt.Println("right") } } ~~~ 還是輸出: right 只有 接口指針 傳入函數的接口參數時,才會出現以上的坑。 修改起來也很方便,把*bytes.Buffer改為bytes.Buffer就好了。 ~~~ import ( "bytes" "fmt" "io" ) const debug = false func main(){ var buf bytes.Buffer //原來是var buf *bytes.Buffer if debug{ buf = new(bytes.Buffer) } f(buf) } func f(out io.Writer){ if out != nil{ fmt.Println("surprise!") } } ~~~ 將map轉化為json字符串的時候,json字符串中的順序和map賦值順序無關 請看下列代碼,請問輸出什么?若為json字符串,則json字符串中key的順序是什么? ~~~ func main() { params := make(map[string]string) params["id"] = "1" params["id1"] = "3" params["controller"] = "sections" data, _ := json.Marshal(params) fmt.Println(string(data)) } ~~~ 答案:輸出{"controller":"sections","id":"1","id1":"3"} 利用Golang自帶的json轉換包轉換,會將map中key的順序改為字母順序,而不是map的賦值順序。map這個結構哪怕利用for range遍歷的時候,其中的key也是無序的,可以理解為map就是個無序的結構,和php中的array要區分開來 Json反序列化數字到interface{}類型的值中,默認解析為float64類型 請看以下程序,程序想要輸出json數據中整型id加上3的值,請問程序會報錯嗎? ~~~ func main(){ jsonStr := `{"id":1058,"name":"RyuGou"}` var jsonData map[string]interface{} json.Unmarshal([]byte(jsonStr), &jsonData) sum := jsonData["id"].(int) + 3 fmt.Println(sum) } ~~~ 答案是會報錯,輸出結果為: ~~~ panic: interface conversion: interface {} is float64, not int ~~~ 使用 Golang 解析 JSON 格式數據時,若以 interface{} 接收數據,則會按照下列規則進行解析: ~~~ bool, for JSON booleans float64, for JSON numbers string, for JSON strings []interface{}, for JSON arrays map[string]interface{}, for JSON objects nil for JSON null ~~~ 應該改為: ~~~ func main(){ jsonStr := `{"id":1058,"name":"RyuGou"}` var jsonData map[string]interface{} json.Unmarshal([]byte(jsonStr), &jsonData) sum := int(jsonData["id"].(float64)) + 3 fmt.Println(sum) } ~~~ 即使在有多個變量、且有的變量存在有的變量不存在、且這些變量共同賦值的情況下,也不可以使用:=來給全局變量賦值 :=往往是用來聲明局部變量的,在多個變量賦值且有的值存在的情況下,:=也可以用來賦值使用,例如: ~~~ msgStr := "hello wolrd" msgStr, err := "hello", errors.New("xxx")//err并不存在 ~~~ 但是,假如全局變量也使用類似的方式賦值,就會出現問題,請看下列代碼,試問能編譯通過嗎? ~~~ var varTest string func test(){ varTest, err := function() fmt.Println(err.Error()) } func function()(string, error){ return "hello world", errors.New("error") } func main(){ test() } ~~~ 答案是:通不過。輸出: varTest declared and not used 但是如果改成如下代碼,就可以通過: ~~~ var varTest string func test(){ err := errors.New("error") varTest, err = function() fmt.Println(err.Error()) } func function()(string, error){ return "hello world", errors.New("error") } func main(){ test() } ~~~ 輸出: error 這是什么原因呢? 答案其實很簡單,在test方法中,如果使用varTest, err := function()這種方式的話,相當于在函數中又定義了一個和全局變量varTest名字相同的局部變量,而這個局部變量又沒有使用,所以會編譯不通過。
                  <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>

                              哎呀哎呀视频在线观看