日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
關(guān)于Go語(yǔ)言,你可能會(huì)討厭的五件事

關(guān)于 Go 語(yǔ)言,你有什么要吐槽的?

創(chuàng)新互聯(lián)主要從事網(wǎng)站建設(shè)、網(wǎng)站制作、網(wǎng)頁(yè)設(shè)計(jì)、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)吉利,10余年網(wǎng)站建設(shè)經(jīng)驗(yàn),價(jià)格優(yōu)惠、服務(wù)專業(yè),歡迎來(lái)電咨詢建站服務(wù):18982081108

近年來(lái),Go 從新出現(xiàn)的編程語(yǔ)言中脫穎而出。不過(guò)要把 Go 稱為“新晉者”似乎并不合適,因?yàn)楣雀柙缭?2009 年就推出了 Go,并于 2012 年發(fā)布了***個(gè)最終版(Go 1.0)。到現(xiàn)在為止,Go 已經(jīng)發(fā)展到了 1.10 版本,這個(gè)版本令人印象深刻,而且還在不斷添加新的特性。

為什么它被稱為 eGOtistic(自大狂)……

大家都知道,Go 在實(shí)現(xiàn)或語(yǔ)法方面喜歡“我行我素”。在英語(yǔ)中,這種情況被描述為“自以為是”。很多來(lái)自其他編程語(yǔ)言的概念在 Go 中并不存在,或者即使存在,它們的行為也變得“面目全非”。后一種情況可能會(huì)導(dǎo)致意想不到的錯(cuò)誤,甚至讓開(kāi)發(fā)人員感到疑惑。

嚴(yán)格的 Go 語(yǔ)法通常會(huì)讓開(kāi)發(fā)人員感到疲倦。Go 編譯器不允許出現(xiàn)未使用的導(dǎo)入和變量,并竭盡所能將它們攔截下來(lái),甚至讓花括號(hào)另起一行都不行。Go 強(qiáng)制使用相對(duì)固定且?guī)缀踅y(tǒng)一的編程風(fēng)格。只要 Go 編譯器不喜歡某些東西,到***都變成了編譯錯(cuò)誤。

Go 提供了非常嚴(yán)格的類型安全。因?yàn)樘^(guò)嚴(yán)格,我們甚至可以通過(guò)它來(lái)實(shí)現(xiàn)一些特殊效果和編程錯(cuò)誤,其中一些我們稍后會(huì)在文中討論。不過(guò),我們很少有必要在 Go 中顯式地聲明類型,因?yàn)轭愋屯ǔ?梢詮馁x值中獲得,也就是類型推斷。

我不是要提供問(wèn)答!

一年多以前,我開(kāi)始在工作中大量使用 Go。Go 算不上是我最喜歡的編程語(yǔ)言,但我承認(rèn),Go 在提升開(kāi)發(fā)效率方面起到了一定作用。事實(shí)上,我已經(jīng)使用 Go 完成了幾個(gè)小項(xiàng)目,主要是一些嵌入式應(yīng)用。Go Toolchain 的跨平臺(tái)編譯功能(編譯后可用于其他操作系統(tǒng)或 CPU 平臺(tái))非常棒,已經(jīng)***于它的競(jìng)爭(zhēng)對(duì)手。

現(xiàn)在讓我們來(lái)看看 Go 的一些比較特別的特性。入門 Go 其實(shí)很容易,可能只需要一個(gè)周末來(lái)了解它的基礎(chǔ)知識(shí)。但當(dāng)你開(kāi)始用 Go 做一些更復(fù)雜的事情時(shí),各種奇奇怪怪的事件開(kāi)始浮出水面。

有時(shí)候,這些特性非常奇怪,谷歌為此提供了問(wèn)題解答,用于解釋類似“為什么 X 的行為是這樣或者那樣的”這類問(wèn)題。Go 在很多方面都表現(xiàn)得與其他語(yǔ)言不太一樣,感覺(jué)好像程序員在某個(gè)時(shí)候一定會(huì)被某些陷阱絆倒一樣。gopher Slack 頻道已經(jīng)證實(shí)了這種情況的存在,其中就有這樣的描述:“現(xiàn)在你真的應(yīng)該好好了解一下 Go 了,因?yàn)槊總€(gè)開(kāi)發(fā)人員在他們的 Go 職業(yè)生涯中都會(huì)問(wèn)到這個(gè)問(wèn)題”。通常情況下,我們的直覺(jué)與 Go 的特性并不相符。例如,在谷歌的 C 語(yǔ)言變種中,公開(kāi)類型、函數(shù)、常量等都以大寫(xiě)字母作為開(kāi)頭來(lái)表示它們是公開(kāi)的,而標(biāo)識(shí)符開(kāi)頭的小寫(xiě)字母表示它們是私有的。

盡管如此,有關(guān) Go 的很多決策都是在郵件列表或提案文件中經(jīng)過(guò)了長(zhǎng)時(shí)間的討論,因此還是得到了肯定。然而,討論所使用的用例都非常特殊,以至于很多開(kāi)發(fā)人員仍然不清楚這與他們要解決的問(wèn)題究竟有什么關(guān)系。

我個(gè)人最喜歡的部分是 Go 沒(méi)有提供可重入鎖,即同一線程或 Goroutine(Coroutine 或 Green Thread 的變體)可遞歸獲取的鎖。如果不通過(guò) hack 的方式就無(wú)法自行實(shí)現(xiàn)這樣的功能,因?yàn)榫€程在 Go 中不可用,而 Goroutine 也并沒(méi)有提供可用于遞歸識(shí)別相同 Coroutine 的標(biāo)識(shí)符。

在這篇文章中,我想介紹 Go 的五個(gè)特性及其語(yǔ)法,這些特性都很隱晦。

1. 瘋狂的影子

讓我們從最簡(jiǎn)單的事情開(kāi)始:每個(gè)優(yōu)秀的開(kāi)發(fā)人員都聽(tīng)說(shuō)過(guò) Shadowing,它通常會(huì)發(fā)生在變量的上下文中。下面是只包含兩個(gè)作用域的簡(jiǎn)單示例:

 
 
 
  1. foo("foo") 
  2. func foo(var1 string) { 
  3.   for { 
  4.     var1 := "bar" 
  5.     fmt.Println(var1) 
  6.     break 
  7.   } 

我們通過(guò):=賦值符號(hào)創(chuàng)建了一個(gè)變量,并通過(guò)所賦的值(類型引用)來(lái)推斷變量的類型。在這里,它是一個(gè)字符串。因此,我們?cè)趦?nèi)部作用域(for 循環(huán))中創(chuàng)建了一個(gè)與函數(shù)參數(shù)名稱相同的變量。我們覆蓋(shadow)了輸入?yún)?shù),并輸出“bar”。

到現(xiàn)在為止還挺好。但是,在 Go 中,需要為其他包的屬性指定包名(即結(jié)構(gòu)體、方法、函數(shù)等),這個(gè)可以在提供 Println 函數(shù)的 fmt 包中看到。

所以我們對(duì)之前的例子稍微做一下重構(gòu):

 
 
 
  1. foo("foo") 
  2. func foo(var1 string) { 
  3.   for { 
  4.     fmt := "bar" 
  5.     fmt.Println(var1) 
  6.     break 
  7.   } 

這一次,我們遇到了編譯錯(cuò)誤,我們?cè)噲D在一個(gè)字符串上調(diào)用 Println 函數(shù)。但這種情況并不總是這么明顯。當(dāng)代碼突然停止編譯時(shí),即使只有幾行代碼也會(huì)給我們帶來(lái)“驚喜”。

如果結(jié)構(gòu)體發(fā)生重疊,就會(huì)很麻煩。讓我們舉一個(gè)奇怪的例子:

 
 
 
  1. type task struct { 
  2.  
  3. func main() { 
  4.   task := &task{} 

我們創(chuàng)建了一個(gè)叫作 task 的結(jié)構(gòu)體和它的一個(gè)實(shí)例。我們有意使用小寫(xiě) task 作為結(jié)構(gòu)體的名稱,因?yàn)槿缜八?,Go 使用***個(gè)字母來(lái)確定可見(jiàn)性,所以 task 在這里是私有的。

到目前為止,它看起來(lái)很不錯(cuò),Go 編譯了我們創(chuàng)建的 task。但是,當(dāng)我們嘗試添加另一行代碼時(shí),情況突然發(fā)生了變化。

 
 
 
  1. type task struct { 
  2.  
  3. func main() { 
  4.   task := &task{} 
  5.   task = &task{} 

現(xiàn)在無(wú)法通過(guò)編譯,并顯示 task 不是一個(gè)類型。此時(shí),Go 分不清類型和變量之間的區(qū)別。也許有人會(huì)說(shuō),在 JavaScript 中,變量 task 可以是對(duì)類型的引用,但這在 Go 中是不可能的,因?yàn)轭愋筒豢梢宰鳛橹蒂x給變量。

現(xiàn)在的問(wèn)題是:這算不算是悲?。恳话銇?lái)說(shuō)不算,但它卻經(jīng)常在我沒(méi)有意識(shí)到的情況下發(fā)生。后面可能還會(huì)有一些代碼嘗試訪問(wèn)相同名稱的結(jié)構(gòu)體或包,而每次都需要花幾分鐘時(shí)間才能找到問(wèn)題所在。

說(shuō)到類型問(wèn)題,讓我們看看另外一個(gè)例子。

2. 類型還是無(wú)類型,這是個(gè)問(wèn)題!

我們已經(jīng)知道如何創(chuàng)建結(jié)構(gòu)體和函數(shù)。有時(shí)候,我們會(huì)偶爾“重命名”一下類型,比如:type handle int ,這將創(chuàng)建一個(gè)叫作 handle 的類型,它的行為類似 int。通常,這個(gè)特性被稱為類型別名。你可能也想到過(guò)這個(gè)特性,但不是在 Go 中。不過(guò)從 Go 1.9 開(kāi)始,已經(jīng)完全支持這個(gè)特性了。

讓我們看看可以用 Go 做哪些好玩的事情:

 
 
 
  1. type handle int 
  2.  
  3. func main() { 
  4.   var var1 int = 1 
  5.   var var2 handle = 2 
  6.   types(var1) 
  7.   types(var2) 
  8.  
  9. func types(val interface{}) { 
  10.   switch v := val.(type) { 
  11.   case int: 
  12.     fmt.Println(fmt.Sprintf("I am an int: %d", v)) 
  13.   case handle: 
  14.     fmt.Println(fmt.Sprintf("I am an handle: %d", v)) 
  15.   } 
  16.  
  17. I am an int: 1 
  18. I am an handle: 2 

在這個(gè)例子中,我們使用了 Go 的幾個(gè)非??岬奶匦?。switch-type-case 語(yǔ)句是一種類型模式匹配,類似于 Java 的 instanceof 或 JavaScript 的 typeof。我們把 interface{}與 Java 中的 Object 等同起來(lái),因?yàn)樗且粋€(gè)空的接口,每個(gè) Go 類都會(huì)自動(dòng)實(shí)現(xiàn)它。

有趣的是,Java 開(kāi)發(fā)人員希望handle也是一個(gè)int,這樣就會(huì)匹配到***個(gè) case。但事實(shí)并非如此,因?yàn)槊嫦驅(qū)ο笾械念愋屠^承在 Go 中并不適用。

另一種可能的情況是,handle 是 int 的別名,就像 C/C++ 中的typedef一樣,但事實(shí)也并非如此。Go 編譯器會(huì)創(chuàng)建一個(gè)新的 TypeSpec,可以說(shuō)是原始類型的克隆。因此,它們之間是完全獨(dú)立的。

不過(guò),從 Go 1.9 開(kāi)始,支持真正的類型別名。下面的例子只稍微做了點(diǎn)修改。

 
 
 
  1. type handle = int 
  2.  
  3. func main() { 
  4.   var var1 int = 1 
  5.   var var2 handle = 2 
  6.   types(var1) 
  7.   types(var2) 
  8.  
  9. func types(val interface{}) { 
  10.   switch v := val.(type) { 
  11.   case int: 
  12.     fmt.Println(fmt.Sprintf("I am an int: %d", v)) 
  13.   } 
  14.   switch v := val.(type) { 
  15.   case handle: 
  16.     fmt.Println(fmt.Sprintf("I am an handle: %d", v)) 
  17.   } 
  18.  
  19. I am an int: 1 
  20. I am an int: 2 
  21. I am an handle: 1 
  22. I am an handle: 2 

你有沒(méi)有注意到它們的區(qū)別?實(shí)際上,我們現(xiàn)在不使用type handle int,而是使用type handle=int為int創(chuàng)建一個(gè)額外的名稱(別名),即handle。這意味著 switch 語(yǔ)句也必須做出修改,因?yàn)檫@個(gè)時(shí)候,int 和 handle 對(duì)于編譯器來(lái)說(shuō)是完全相同的類型,除非你有另一個(gè) double case,否則會(huì)出現(xiàn)編譯錯(cuò)誤。由于類型別名實(shí)在 Go 1.9 中引入的,很多人會(huì)認(rèn)為上述的類型克隆就是類別別名。

為了方便演示,讓我們定義一個(gè)名為Callable的類型,它由一個(gè)沒(méi)有參數(shù)和返回值的簡(jiǎn)單函數(shù)組成。

type Callable func()

現(xiàn)在創(chuàng)建一個(gè)相應(yīng)的函數(shù)。

 
 
 
  1. func main() { 
  2.   myCallable := func() { 
  3.     fmt.Println("callable") 
  4.   } 
  5.   test(myCallable) 
  6.  
  7. func test(callable Callable) { 
  8.   callable() 

看,很簡(jiǎn)單。由于 Go 的類型推斷機(jī)制,編譯器自動(dòng)識(shí)別出myCallable應(yīng)該對(duì)應(yīng)Callable的函數(shù)簽名。編譯器因此能夠隱式地將myCallable轉(zhuǎn)換為Callable。隨后,myCallable被傳遞給test函數(shù)。這是執(zhí)行隱式轉(zhuǎn)換的少數(shù)例外之一,通常情況下,所有形式的轉(zhuǎn)換必須全部明確地指出。

現(xiàn)在我們已經(jīng)到了不得不使用Reflection的地步。與其他語(yǔ)言一樣,Reflection提供了在運(yùn)行時(shí)分析或改變行為的能力。類型信息通常被用于根據(jù)值的數(shù)據(jù)類型來(lái)改變運(yùn)行時(shí)行為。

 
 
 
  1. type Callable func() 
  2.  
  3. func main() { 
  4.   callable1 := func() { 
  5.     fmt.Println("callable1") 
  6.   } 
  7.  
  8.   var callable2 Callable 
  9.   callable2 = func() { 
  10.     fmt.Println("callable2") 
  11.   } 
  12.  
  13.   test(callable1) 
  14.   test(callable2) 
  15.  
  16. func test(val interface{}) { 
  17.   switch v := val.(type) { 
  18.   case func(): 
  19.     v() 
  20.   default: 
  21.     fmt.Println("wrong type") 
  22.   } 
  23.  
  24. callable1 
  25. wrong type 

callable1現(xiàn)在是函數(shù)類型func(),而callable2被顯式聲明為Callable。 Callable是一個(gè)單獨(dú)的TypeSpec,因此與func()的類型不一樣。這兩種情況現(xiàn)在都必須由我們的Reflection處理程序單獨(dú)攔截處理。不過(guò)這些問(wèn)題可以通過(guò)在 Go 1.9 中引入的類型別名來(lái)解決。

type Callable=func()

3. 懶惰是囊地鼠的天性!

Go 語(yǔ)言萌萌噠的 logo 囊地鼠生性懶散,選這個(gè) logo 也是有一定的代表意義的。

我最喜歡的 Go 特性之一是惰性求值(Lazy Evaluation),即延遲執(zhí)行代碼。自從 Java 推出 Stream API 以來(lái),Java 開(kāi)發(fā)人員對(duì)該特性也所了解。

我們來(lái)看看下面的代碼片段:

 
 
 
  1. func main() { 
  2.   functions := make([]func(), 3) 
  3.     for i := 0; i < 3; i++ { 
  4.       functions[i] = func() { 
  5.       fmt.Println(fmt.Sprintf("iterator value: %d", i)) 
  6.       } 
  7.     } 
  8.  
  9.   functions[0]() 
  10.   functions[1]() 
  11.   functions[2]() 

這里有一個(gè)包含三個(gè)元素的數(shù)組、一個(gè)循環(huán)和閉包,而結(jié)果會(huì)是什么?

 
 
 
  1. iterator value: 3 
  2. iterator value: 3 
  3. iterator value: 3 

我們會(huì)認(rèn)為是 0,1,2,但實(shí)際上卻是 3,3,3。沒(méi)錯(cuò)!

在其他編程語(yǔ)言(如 Java)中,在創(chuàng)建閉包時(shí)會(huì)捕獲變量的值,而 Go 僅捕獲指向變量本身的指針。問(wèn)題是,在迭代期間,變量的值不斷變化。循環(huán)完成后,我們執(zhí)行閉包,只看到***的值。我們知道我們只擁有指針,所以也就可以理解這種行為,但確實(shí)不是很直觀。

如果我們想保存這個(gè)值,需要知道在創(chuàng)建閉包時(shí)如何計(jì)算這個(gè)值。

 
 
 
  1. func main() { 
  2.   functions := make([]func(), 3) 
  3.   for i := 0; i < 3; i++ { 
  4.     functions[i] = func(y int) func() { 
  5.       return func() { 
  6.         fmt.Println(fmt.Sprintf("iterator value: %d", y)) 
  7.       } 
  8.     }(i) 
  9.   } 
  10.  
  11.   functions[0]() 
  12.   functions[1]() 
  13.   functions[2]() 

我們創(chuàng)建了一個(gè)臨時(shí)函數(shù),它將變量作為參數(shù)并返回閉包。我們立即調(diào)用這個(gè)函數(shù)。由于在調(diào)用外部函數(shù)時(shí)必須先計(jì)算變量的值,所以內(nèi)部閉包就可以捕獲到正確的值。我們得到的是 0,1,2。

在寫(xiě)這篇文章不久之前,我找到了另一種方式。我們可以在循環(huán)中創(chuàng)建一個(gè)具有相同名稱的變量,并為其分配實(shí)際值。這樣也可以捕獲到變量的值,因?yàn)檫@個(gè)方法在循環(huán)的每次迭代中都會(huì)創(chuàng)建一個(gè)新的變量(因此是一個(gè)新的指針)。

 
 
 
  1. func main() { 
  2.   functions := make([]func(), 3) 
  3.   for i := 0; i < 3; i++ { 
  4.     i := i // Trick mit neuer Variable 
  5.     functions[i] = func() { 
  6.       fmt.Println(fmt.Sprintf("iterator value: %d", i)) 
  7.     } 
  8.   } 
  9.  
  10.   functions[0]() 
  11.   functions[1]() 
  12.   functions[2]() 

從執(zhí)行速度來(lái)看,懶求值通常是一個(gè)有趣的話題。畢竟,我可以在不使用它的情況下創(chuàng)建閉包。既然這樣,為什么還要求值?在我看來(lái),這也是非常不直觀的。

4. 我們是不是都有點(diǎn)像囊地鼠?

我們已經(jīng)知道,Go 中的interface{}就像 Java 中的Object——Go 中的每個(gè)類型都會(huì)自動(dòng)實(shí)現(xiàn)這個(gè)空接口。不過(guò),自動(dòng)實(shí)現(xiàn)接口不僅適用于空接口,每一個(gè)實(shí)現(xiàn)了某個(gè)接口所有方法的結(jié)構(gòu)體或類型也會(huì)自動(dòng)實(shí)現(xiàn)這個(gè)接口。

為了更好地說(shuō)明這個(gè)問(wèn)題,讓我們來(lái)看看下面的例子:

 
 
 
  1. type Sortable interface { 
  2.   Sort(other Sortable) 

定義了這個(gè)方法的結(jié)構(gòu)體會(huì)自動(dòng)成為 Sortable。

 
 
 
  1. type MyStruct struct{} 
  2. func (m MyStruct) Sort(other Sortable){} 

除了接收器類型的語(yǔ)法,它用于將函數(shù)綁定到類型(在本例中為結(jié)構(gòu)體),我們已經(jīng)實(shí)現(xiàn)了Sortable接口的所有方法。我們現(xiàn)在是一個(gè) Sortable!

var sortable Sortable = &MyStruct{}

自動(dòng)實(shí)現(xiàn)接口乍一看似乎很有用,但這樣會(huì)讓事情變得復(fù)雜,特別是在大型應(yīng)用中,如果有幾個(gè)接口擁有相同的方法,那么就會(huì)點(diǎn)讓人摸不著頭腦。開(kāi)發(fā)者實(shí)際想要實(shí)現(xiàn)哪個(gè)接口?或許他們應(yīng)該在代碼的注釋中寫(xiě)清楚!

Go 還有一個(gè)解決方案用于確保一個(gè)類型實(shí)現(xiàn)了一個(gè)接口,就像 Java 的implements關(guān)鍵字一樣,這實(shí)在是太簡(jiǎn)單了。

 
 
 
  1. type MyStruct struct{} 
  2. func (m MyStruct) Sort(other Sortable){} 
  3. var _ Sortable = MyStruct{} 
  4. var _ Sortable = (*MyStruct)(nil) 

5. nil 和 nothing

現(xiàn)在我們都知道,“null”和“nil”之間有很大的差別,但可能不是所有人都知道,“nothing”并不總是意味著“什么都沒(méi)有”。為了證明這點(diǎn),我們定義了自己的錯(cuò)誤類型(異常)。

 
 
 
  1. type MyError string 
  2. func (m MyError) Error() string { 
  3.   return string(m) 

我們創(chuàng)建了一個(gè)新的類型,它是從字符串類型克隆過(guò)來(lái)的。我們只是想要一個(gè)錯(cuò)誤消息,所以這樣做就足夠了。要實(shí)現(xiàn)error接口(是的,小寫(xiě),理論上它不應(yīng)該是公開(kāi)的,但 Go 無(wú)所不能),就必須實(shí)現(xiàn)Error方法。

接下來(lái),我們需要另一個(gè)總是返回 Nil 的函數(shù)。

 
 
 
  1. func test(v bool) error { 
  2.   var e *MyError = nil 
  3.   if v { 
  4.     return nil 
  5.   } 
  6.   return e 

無(wú)論我們傳進(jìn)去的是true還是false,這個(gè)函數(shù)總是返回nil,是這樣的嗎?c`

 
 
 
  1. func main() { 
  2.   fmt.Println(nil == test(true)) 
  3.   fmt.Println(nil == test(false)) 
  4.  
  5. true 
  6. false 

在返回e時(shí),*MyError指針指向接口error的一個(gè)實(shí)例,它不是nil!這樣合邏輯嗎?當(dāng)你知道接口在 Go 中的表示方式,你就會(huì)知道這是合乎邏輯的。

在 Go 內(nèi)部,接口是一個(gè)結(jié)構(gòu)體,包含了實(shí)際目標(biāo)實(shí)例(這里為nil)和接口類型(在這里是error),而且根據(jù) Go 語(yǔ)言規(guī)范,只有在這個(gè)結(jié)構(gòu)體的兩個(gè)值都為nil時(shí),接口實(shí)例才為nil。因此,如果真想要返回nil,那就顯式地返回吧。

特別之處

還有一點(diǎn)是值得一提的,如前所述,Go 根據(jù)名稱來(lái)推斷出類型和功能的可見(jiàn)性。如果***個(gè)字母是大寫(xiě)字母(如Foo),則該函數(shù)或類型是公開(kāi)的,如果***個(gè)字母是小寫(xiě)字母(如foo),那么就是私有的。不過(guò),在 Java 中有 private,而在 Go 中只有package-private。

一般來(lái)說(shuō),除了在 Go 中使用駝峰式命名法,我們都可以使用這種可見(jiàn)性規(guī)則,無(wú)論是函數(shù)、結(jié)構(gòu)體還是常量,但我們的 IDE 有語(yǔ)法突出顯示,所以誰(shuí)會(huì)在乎這個(gè)!

有趣的是,Go 支持 Unicode 的標(biāo)識(shí)符。因此,日本語(yǔ)(Nihongo 是日語(yǔ)的意思)是完全合法的標(biāo)識(shí)符,但通常被認(rèn)為是私有的。為什么?因?yàn)槿瘴淖址麤](méi)有大寫(xiě)字母。

“GO 斯拉”發(fā)來(lái)問(wèn)候

某種程度上,Go 是一門非常獨(dú)特的語(yǔ)言。在日常工作中,你可以享受 Go 帶來(lái)的樂(lè)趣。如果你已經(jīng)知道我們?cè)谶@里所提到的陷阱(還有更多),那么即使開(kāi)發(fā)再大型的應(yīng)用程序也不成問(wèn)題。盡管如此,還是會(huì)不斷出現(xiàn)各種提醒,說(shuō)這門語(yǔ)言有問(wèn)題。

Go 在近幾年發(fā)生了很多事情,除了增加新特性,Go 2 中還列出了很多需要改進(jìn)的地方,包括一些語(yǔ)法和運(yùn)行時(shí)行為的不一致性。不過(guò) Go 2 的推出時(shí)間還不得而知,還沒(méi)有清晰的路線圖。

如果你想要用 Go,那么就用吧,盡管存在很多坑。不過(guò)你要為此做好準(zhǔn)備:有時(shí)候你會(huì)感到困惑,需要長(zhǎng)時(shí)間的調(diào)試,或通過(guò)閱讀 FAQ 或訪問(wèn) Gopher Slack 頻道來(lái)解決問(wèn)題。


分享名稱:關(guān)于Go語(yǔ)言,你可能會(huì)討厭的五件事
轉(zhuǎn)載來(lái)于:http://www.dlmjj.cn/article/ccsodpe.html