標籤:

go語言在變數創建前為什麼要聲明?

大家好, 我對go語言變數創建前要聲明這一語法感到疑惑, 因為我看不到其意義所在,比如創建一個map的語法如下:

var personDB map[string] string // 聲明變數personDB

personDB = make(map[string] string) // 創建變數personDB

既然創建變數的語法裡面已經有了創建這個map需要的全部信息了, 為什麼還要有一句聲明呢?請大家指點一下.(PS, 我知道有個 := 可以直接聲明並創建, 但是我疑惑的是上面的聲明語句存在的必要性是什麼?)


go 的變數在聲明時也會初始化,不同的類型有不同的初始化值。bool 類型初始化為 false,int 初始化為 0,string 初始化為 ""。實現上就是變數內存全部清零。

map 類型也同理,聲明時會初始化。但是,map 類型的初始化值並不是一個空 map,而是 nil。所以需要用 make 函數來創建一個 map。

chan、func、slice、pointer、interface 等類型的初始化值都是 nil。

下面的程序,聲明了 m1 和 m2 兩個變數,但實際只創建了一個 map 對象。兩個變數都指向同一個 map:

package main

func main() {

var m1 map[bool]bool
m1 = make(map[bool]bool)

var m2 map[bool]bool
m2 = m1

_ = m2
}


有幾種情形:

1. 考慮下面的代碼

if ... {

a = ...

} else {

a = ...

}

這時候就不能準確判斷a是什麼類型,a的作用域是外面還是大括弧裡面了。

2. 考慮下面的代碼

err= some(a)

由於重載特性,這時候調用哪個some可能是要根據a的類型來判斷的,就必須要先聲明a的類型

綜上,必須提供一種明確指定變數類型和作用域,而不是隱式指定的方式。


對不起,你問的我看不懂,不好意思。


有C/C++經驗應該很好理解,要知道Go就是互聯網或者新時代的C

類似map,slice等類型,雖然是內置類型,其實並不是簡單類型.只是內置的class(可以這樣理解).

var personDB map[string] string

相當於C++中的 (map[string] string )* personDB = ptr_null;

顯然你不能personDB 直接使用,他只是個聲明,佔4byte/8byte內存,存放0的一個這麼內存位址.

personDB = make(map[string] string)

相當於C++中的personDB =new ( make(map[string] string));

這樣分配了class instance內存並指向了personDB,這時personDB 就可以引用分配內存中的數據(class field),也可call class method.由RT(如果有vt)和鏈接器定位鏈接最終調用代碼方法的地址.

GO也是這種思路,只不過細節和編譯器實現上的差異.當然在語法層面上做得看上去更舒服而已.比如new變成了內置分配原語make等

如果問題是為什麼要多怎麼一個聲明,直接聲明後編譯器自動分配內存不是很好嗎?這就牽涉到C/C++的設計邏輯,原因有很多,其中比較重要的是一條就是讓你充分控制且分配是個耗時(相比起聲明),所以要程序員手動明確控制.多了一種選擇.

當然你要一步完成完全可以合併聲明和初始化.

personDB := make(map[string] string)


推薦閱讀:

有哪些可以在500-1000行以內實現的Go語言項目?
有哪些不錯的golang開源項目?

TAG:Go語言 |