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