Go語(yǔ)言變量初始化的實(shí)現(xiàn)示例
引言
在Go語(yǔ)言中,變量的初始化是編寫程序時(shí)經(jīng)常遇到的重要操作之一。
通過正確地初始化變量,我們可以確保程序的正確性和可讀性,并且能夠避免一些常見的錯(cuò)誤。
Go語(yǔ)言提供了多種初始化變量的方法,包括使用var關(guān)鍵字、短變量聲明以及在聲明時(shí)提供初始值等方式。
本文將介紹如何在Go語(yǔ)言中進(jìn)行變量的初始化,并提供一些示例以更好地理解這些概念。
舉例
在Go語(yǔ)言中,變量的初始化可以使用var關(guān)鍵字或短變量聲明,并且可以同時(shí)聲明和初始化變量。下面是一些示例:
1.使用var關(guān)鍵字聲明和初始化變量:
var x int = 10 var str string = "Hello, world!"
2.使用短變量聲明方式:
x := 10 str := "Hello, world!"
3.多個(gè)變量同時(shí)聲明和初始化:
var a, b, c int = 1, 2, 3 var str1, str2 string = "foo", "bar"
4.如果聲明變量時(shí)未提供初始值,則變量會(huì)被初始化為其類型的零值:
var num int // num被初始化為0 var str string // str被初始化為空字符串""
5.在函數(shù)內(nèi)部,可以使用短變量聲明的方式初始化變量:
func main() { x := 10 str := "Hello, world!" fmt.Println(x, str) }
在Go中,變量的初始化是一種常見且重要的操作,它使得代碼更加清晰易懂,并且有助于避免潛在的錯(cuò)誤。
多個(gè)變量同時(shí)賦值
在Go語(yǔ)言中,可以使用多個(gè)變量同時(shí)進(jìn)行賦值。這可以通過使用簡(jiǎn)短變量聲明(short variable declaration)或使用賦值語(yǔ)句來實(shí)現(xiàn)。
1.使用簡(jiǎn)短變量聲明方式:
x, y := 10, 20 str1, str2 := "Hello", "World"
2.使用賦值語(yǔ)句同時(shí)給多個(gè)變量賦值:
var a, b int a, b = 10, 20
3.交換兩個(gè)變量的值:
x, y := 10, 20 x, y = y, x // 交換x和y的值
4.同時(shí)聲明和賦值多個(gè)變量:
var ( name = "John" age = 30 email = "john@example.com" )
Go 語(yǔ)言還提供了兩個(gè)專門用于數(shù)據(jù)初始化的內(nèi)建函數(shù) new 和 make。
1. 內(nèi)建函數(shù) new
new 函數(shù)用于為值分配內(nèi)存。與其他編程語(yǔ)言(如 Java)中的 new 不同的是,它并不會(huì)去初始化分配到的內(nèi)存,而只會(huì)清零它。因此調(diào)用表達(dá)式 new(T) 被求值時(shí),所做的是為 T 類型的新值分配并清零一塊內(nèi)存空間,然后將這塊內(nèi)存空間的地址作為結(jié)果返回。而這個(gè)結(jié)果就是指向這個(gè)新的 T 類型值的指針值。它的類型為 *T。實(shí)際上這個(gè) new 函數(shù)返回的 *T 類型值總會(huì)指向一個(gè) T 類型的零值。
例如,調(diào)用表達(dá)式 new(string) 的求值結(jié)果指向的是一個(gè) string 類型的零值 "",而調(diào)用表達(dá)式 new([3]int) 的求值結(jié)果指向的則是一個(gè) [3]int 類型的零值 [3]int{0, 0, 0}。
正因?yàn)橛羞@種干凈的內(nèi)存分配策略,使得我們可以在用內(nèi)建函數(shù) new 創(chuàng)建某個(gè)數(shù)據(jù)類型的新值之后立刻就可以拿來使用,而不用擔(dān)心在這個(gè)值中會(huì)遺留某些初始化的痕跡。
下面我們以標(biāo)準(zhǔn)庫(kù)代碼包 bytes 中的結(jié)構(gòu)體類型 Buffer 為例介紹以下:
bytes.Buffer 是一個(gè)尺寸可變的字節(jié)緩沖區(qū)。它的零值就是一個(gè)立即可用的空緩沖區(qū)。因此,調(diào)用表達(dá)式 new(bytes.Buffer) 的求值結(jié)果就是一個(gè)指向一個(gè)空緩沖區(qū)的指針值。然后,我們就可以立即在這個(gè)緩沖區(qū)上進(jìn)行讀寫操作了。
標(biāo)準(zhǔn)庫(kù)代碼包 sync 中的結(jié)構(gòu)體類型 Mutex 也是一個(gè)可以 new 后即用的數(shù)據(jù)類型。它的零值就是一個(gè)處于未鎖定狀態(tài)的互斥量。
內(nèi)建函數(shù) new 的這種特性為我們提供了一個(gè)關(guān)于自定義數(shù)據(jù)類型的可參考的設(shè)計(jì)規(guī)則:
例如,在我們自定義一個(gè)結(jié)構(gòu)體類型的時(shí)候就要考慮到,在其中的每個(gè)字段的值都分別為對(duì)應(yīng)類型的零值的時(shí)候,這個(gè)結(jié)構(gòu)體值就應(yīng)該已經(jīng)處于可用的狀態(tài)。這樣,我們?cè)?new 它的時(shí)候就能夠得到一個(gè)立即可用的值的指針值,而不需要再做額外的初始化。
當(dāng)然,在感覺一個(gè)類型的零值還無法讓它變得可用的時(shí)候,我們可以使用相應(yīng)的字面量來達(dá)到分配內(nèi)存空間并初始化值的目的。
前面我們已經(jīng)講過,我們可以在字面量中靈活的指定新值中的每一個(gè)元素的值。但是要注意,字面量所代表的是該類型的值,而不是指向該類型值的指針值。 因此,我們?cè)趯⑺鼈兣c調(diào)用 new 函數(shù)的調(diào)用表達(dá)式做等價(jià)替換的時(shí)候,還需要在字面量的前面加入取址操作符 & 以表示指向該類型值的指針值。
2. 內(nèi)建函數(shù) make
與 new 不同的是,make 函數(shù)只能被用于創(chuàng)建 切片類型、字典類型 和 通道類型 的值,并返回一個(gè)已被初始化的(即非零值的)的對(duì)應(yīng)類型的值。
那 make 函數(shù)為啥要這樣做呢?
在之前的博文中我們介紹過,這 3 個(gè)復(fù)合類型都是引用類型。在它們的每一個(gè)值的內(nèi)部都會(huì)保持著一個(gè)對(duì)某個(gè)底層數(shù)據(jù)結(jié)構(gòu)值的引用。如果不對(duì)它們的值進(jìn)行初始化,那么其中的這種引用關(guān)系是不會(huì)被建立起來的,同時(shí)相關(guān)的內(nèi)部值也會(huì)不正確。在這種情況下,該類型的值也就不能夠被使用,因?yàn)樗鼈兪遣煌暾模€處于未就緒的狀態(tài)。這就意味著,在創(chuàng)建這 3 個(gè)引用類型的值的時(shí)候,必須將內(nèi)存空間分配和數(shù)據(jù)初始化這兩個(gè)步驟綁定在一起。也正是為了保證這些值的可用性,切片類型、字典類型 和 通道類型的零值都是 nil,不是那個(gè)未被初始化的值。因此,當(dāng)我們 new 這 3 個(gè)引用類型并想創(chuàng)建它們的值的時(shí)候,得到的卻是一個(gè)指向空值 nil 的指針值。
除此之外,內(nèi)建函數(shù) make 所接受的參數(shù)也與 new 函數(shù)有所不同。make 函數(shù)除了會(huì)接受一個(gè)表示目標(biāo)類型的類型字面量之外,還會(huì)接受一個(gè)或兩個(gè)額外的參數(shù)。
對(duì)于 切片類型 來說,我們可以在把新值的長(zhǎng)度和容量也傳遞給 make 函數(shù)。例如:
// 調(diào)用表達(dá)式創(chuàng)建了一個(gè)新的 []int 類型的值,這個(gè)值的長(zhǎng)度為10、容量為100 make([]int, 10, 100)
當(dāng)然,我們也可以省略掉最后一個(gè)參數(shù),即不指定新值的容量。這種情況下,該值的容量會(huì)與其長(zhǎng)度一致。示例如下:
// 變量s的類型是[]int的,而長(zhǎng)度和容量都是10。 s := make([]int,10)
在使用 make 函數(shù)初始化一個(gè)切片值的過程中,該值會(huì)引用一個(gè)長(zhǎng)度與其容量相同且元素類型與其元素類型一致的數(shù)組值。這個(gè)數(shù)組值就是該切片值的底層數(shù)組。該數(shù)組值中的每個(gè)元素都是當(dāng)前元素類型的零值。但是,切片值只會(huì)展現(xiàn)出數(shù)量與其長(zhǎng)度相同的元素。因此,調(diào)用表達(dá)式 make([]int,10,100) 所創(chuàng)建并初始化的值就是 []int{0 0 0 0 0 0 0 0 0 0}。
我們?cè)谑褂?make 函數(shù)創(chuàng)建字典類型的值的時(shí)候,也可以指定其底層數(shù)據(jù)結(jié)構(gòu)的長(zhǎng)度。但是,該字典值只會(huì)展示出我們明確放入的鍵值對(duì)。例如:
// 調(diào)用如下表達(dá)式,所創(chuàng)建和初始化的值會(huì)是 map[string]int make(map[string]int,100) // 也可以忽略掉那個(gè)用于表示底層數(shù)據(jù)結(jié)構(gòu)長(zhǎng)度的參數(shù) make(map[ string]int)
雖然我們也可以忽略掉那個(gè)用于表示底層數(shù)據(jù)結(jié)構(gòu)長(zhǎng)度的參數(shù) ,但是還是建議:
應(yīng)該在性能敏感的應(yīng)用場(chǎng)景下,根據(jù)這個(gè)字典值可能包含的鍵值對(duì)的數(shù)量以及放入它們的時(shí)間,仔細(xì)地設(shè)置該長(zhǎng)度參數(shù)。
最后我們簡(jiǎn)單介紹以下對(duì)于 通道類型(Channel) 的值的數(shù)據(jù)初始化。到此目前為止,我們還沒有對(duì)通道類型進(jìn)行過任何說明。不過,在后續(xù)的博文中,我們會(huì)詳細(xì)講解這個(gè)特殊的引用類型。
// 使用make函數(shù)創(chuàng)建一個(gè)通道類型的值 make(chan int, 10)
其中的第一個(gè)參數(shù)表示的是 通道的類型,而第二個(gè)參數(shù)則表示該 通道的長(zhǎng)度。與字典類型相同,第二個(gè)參數(shù)也可以被忽略掉。不過忽略它的含義卻與針對(duì)字典類型的情況有著很大的不同,這些我們會(huì)在后面的博文中專門講解。
注意: make 函數(shù)只能被應(yīng)用在引用類型的值的創(chuàng)建上。并且,它的結(jié)果是第一個(gè)參數(shù)所代表的類型的值,而不是指向這個(gè)值的指針值。
如果我們想要獲得該指針值的話,只能在調(diào)用 make 函數(shù)的表達(dá)式的求值結(jié)果之上應(yīng)用取址操作符 &,像這樣:
m := make(map[string]int, 100) mp := &m
到目前為止,我們已經(jīng)介紹了 3 種創(chuàng)建值的的方法:
- 使用 字面量
- 調(diào)用內(nèi)建函數(shù) new
- 調(diào)用內(nèi)建函數(shù) make
它們適用于不同的應(yīng)用場(chǎng)景。當(dāng)然,在某些應(yīng)用場(chǎng)景中、我們可以有多種選擇:
- 在創(chuàng)建一個(gè)切片類型的值的時(shí)候,我們既可以使用字面量也可以使用 make 函數(shù)。這種選擇的結(jié)果往往取決于我們是否需要定制切片值中的某個(gè)或某些元素值。
- 如果我們能夠保證一個(gè)結(jié)構(gòu)體類型的值在其中字段的值均為零值的情況下就能夠處于可用狀態(tài)的話,那么僅使用 new 函數(shù)來初始化它與使用字面量進(jìn)行初始化是基本等價(jià)的。不過要注意,這兩種方法產(chǎn)生的結(jié)果的類型是不同的。
總結(jié)
通過本文的介紹,相信已經(jīng)了解了在Go語(yǔ)言中進(jìn)行變量初始化的基本方法和注意事項(xiàng)。
無論是使用var關(guān)鍵字聲明和初始化變量,還是通過短變量聲明方式,都可以輕松地初始化變量并開始編寫Go程序。
在編寫代碼時(shí),始終確保正確地初始化變量是非常重要的,這有助于代碼的清晰度和可維護(hù)性。
到此這篇關(guān)于Go語(yǔ)言變量初始化的實(shí)現(xiàn)示例的文章就介紹到這了,更多相關(guān)Go語(yǔ)言變量初始化內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
golang 如何實(shí)現(xiàn)HTTP代理和反向代理
這篇文章主要介紹了golang 實(shí)現(xiàn)HTTP代理和反向代理的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-05-05Golang學(xué)習(xí)筆記(四):array、slice、map
這篇文章主要介紹了Golang學(xué)習(xí)筆記(四):array、slice、map,本文分別講解了這3個(gè)類型的聲明&賦值、元素訪問、其它操作,需要的朋友可以參考下2015-05-057分鐘讀懂Go的臨時(shí)對(duì)象池pool以及其應(yīng)用場(chǎng)景
這篇文章主要給大家介紹了關(guān)于如何通過7分鐘讀懂Go的臨時(shí)對(duì)象池pool以及其應(yīng)用場(chǎng)景的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或使用Go具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起看看吧2018-11-11Go語(yǔ)言Http?Server框架實(shí)現(xiàn)一個(gè)簡(jiǎn)單的httpServer
這篇文章主要為大家介紹了Go語(yǔ)言Http?Server框架實(shí)現(xiàn)一個(gè)簡(jiǎn)單的httpServer抽象,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04