1. 程式人生 > >Go語言的冷知識

Go語言的冷知識

append, map, len不是關鍵字

他們其實還是類庫功能, 都在buildin包裡的, 系統預設給你做了個

  1. import(
  2. . "buildin"
  3. )

將buildin的包內容都對映到全域性而已, 其實你也可以用自己的包這麼做

列印的另一種寫法

想跟指令碼一樣除錯列印資料麼?

  1. println("hello world")

無需包含任何包, 因為它在buildin包裡

iota不是黑科技

這是在buildin包裡的定義

  1. // iota is a predeclared identifier representing the untyped integer ordinal
  2. // number of the current const specification in a (usually parenthesized)
  3. // const declaration. It is zero-indexed.
  4. const iota = 0 // Untyped int.

其實go是有泛型概念的

想想map和陣列的定義 
只是泛型沒有開放給使用者用而已(只許XX放火,不許XX點燈)

map是支援多個key的, 而且很方便

還在為多個key轉id的複雜演算法而頭疼麼?

  1. type myKey struct{
  2. number int
  3. str string
  4. }
  5. func main(){
  6. t := map[ myKey] int {
  7. myKey{ 2, "world"}: 1,
  8. }
  9. fmt.Println(t[myKey
    {2, "world"}])
  10. }
  11. 輸出: 1

列舉是可以轉成string的

預設定義一個列舉

  1. type MyConst int
  2. const (
  3. MyConst_A MyConst = iota
  4. MyConst_B MyConst = iota
  5. )
  6. func main(){
  7. fmt.Println(MyConst_A)
  8. }

輸出: 0 
如果我們想自動化輸出MyConst_A字串時 
就需要使用golang的一個工具鏈:golang.org/x/tools/cmd/stringer 
將其下載, 編譯成可執行工具後, 對程式碼進行生成 
生成的程式碼會多出一個xx_string.go 
裡面就是列舉的String()string 函式

臨時轉換一個介面並呼叫的方法

  1. type love struct{
  2. }
  3. func (self*love)foo(){
  4. fmt.Println("love")
  5. }
  6. func main(){
  7. var chaos interface{} = new(love)
  8. chaos.(interface{
  9. foo()
  10. }).foo()
  11. }

Golang的receiver實際上就是this的變種實現

  1. func( self*MyStruct) foo( p int ){
  2. }

寫不慣receiver的寫法? 如果這樣改下呢?

  1. func foo( self *MyStruct, p int ){
  2. }

所以為什麼說Golang還是一個C語言嘛

關於記憶體分配…

  • new 傳入Type型別, 返回*Type型別
  • make 可以在分配陣列時設定預分配大小, new不可以
  • make 能分配陣列,map, 但不能分配結構體和原始型別
  • new 能分配陣列, map, 結構體和原始型別等的所有型別
  • &Type等效於new
  • 切片不需要分配記憶體(make,new), 直接宣告就可以了…

Golang的反射無法通過一個型別名, 建立其例項

C#有Assembly概念, 可以在一個Assembly裡搜尋, 建立例項

Golang是靜態型別語言, 如果需要, 只能註冊你需要建立的結構體, 然後將註冊好的map用於建立

Golang可以替換Python來進行復雜的工具流程處理

如果你需要跨平臺的工具流程處理, 對Python不熟悉, 可以使用

  1. go run yourcode.go 引數1 引數2

方式來進行工具處理 
覺得慢, 可以編譯成可執行檔案

這樣做的好處: 如果有些類庫本身就是go寫的, Python想使用是很麻煩的, 而Golang來寫則輕而易舉

例子: 通過go的protobuf庫, 對一些檔案進行處理

Golang可以自動持有方法的接收者例項

  1. type myType struct{
  2. }
  3. func (self*myType) foo( p int){
  4. fmt.Println("hello", p )
  5. }
  6. func main(){
  7. var callback func( int )
  8. ins := new(myType)
  9. callback = ins.foo
  10. callback( 100 )
  11. }

做過lua的C++程式碼繫結的童鞋都清楚: lua只支援外部靜態或者全域性函式呼叫 
如果要進行C++類成員函式呼叫時, 要自己處理this和成員函式 
這種技巧因為早起編譯器的虛表不同平臺實現細節不統一需要專門處理 
後面跨平臺虛表統一後, 類成員函式的呼叫寫法也是很噁心複雜的 
但是Golang的小白式用法, 直接吊打C++, 甚至C#複雜的delegate

LiteIDE篇: 多開祕籍

  • 找到 選單->檢視->選項->通用->儲存->儲存設定到本地ini檔案

  • 關閉LiteIDE

  • 複製LiteIDE整個目錄, 命名資料夾為你的工程名

  • 每個工程所在的LiteIDE的配置將是獨立的, 不會互相干擾

LiteIDE篇: 測試程式也是可以除錯的

別以為程式一定要是main開始的才可以除錯

Golang的測試程式雖然都是一個個Test開頭的函式,但執行go test時, 還是有main入口

在LiteIDE中, 可以在 除錯->開始除錯測試程式裡進行測試程式除錯

LiteIDE篇: 在Windows上可以輸出linux可執行檔案

go的工具鏈預設支援交叉編譯 
在LiteIDE中, 可以通過切換輸出平臺, 輸出不同平臺的可執行檔案