Golang之nil的妙用

2021-09-25 06:18:43 字數 3824 閱讀 5082

在go語言中,布林型別的"0"(初始值)為false,數值型別的"0"為0,字串型別的"0"為空字串"",而指標/切片/對映/通道/函式和介面的"0"即為nil。

當你宣告乙個結構體變數並未初始化時,該結構體所有的域(field)都為"0"(初始值):

type person struct

var p person //person

這裡需要注意的是nil不是go語言的關鍵字,即下面的語句可以通過編譯,但是你不應該這麼做:

var

nil= errors.

new(

"my god"

)

和其他語言稍微不同的是,go語言的函式接收器(receiver)允許nil的存在,即下面的**可以編譯通過:

func

(p *person)

sayhi()

var p *person

p.sayhi()

// print "hi"

這個特性讓我們無需在每次呼叫方法前判斷指標是否為nil,如:

type node struct

func

(n *node)

sum(

)int

return n.value + s

}var n *node

if n !=

nil

而是在方法內判斷receiver是否nil,可以簡省不少**:

type node struct

func

(n *node)

sum(

)int

return n.value + n.next.

sum()}

var n *node

n.sum

()

nil切片是長度和容量都為0的切片,在使用中如果沒有必要,我們完全可以不初始化nil切片,因為nil切片也有切片的功能,如:

var ss [

]string

// nil切片

len(ss)

// 0

cap(ss)

// 0

for s :=

range ss // 迭代0次

ss[i]

// panic:index out of range

var ss [

]string

ss =

(ss,

"hello world"

)// ss ["hello world"]

nil對映是指未初始化的對映,其長度為0,可讀但不可寫,如:

var m map

[string

]string

len(m)

// 0

for key,value :=

range m // 迭代0次

value,ok := m[

"key"

]// "",false

m["key"]=

"value"

// panic: assignment to entry in nil map

nil對映用在唯讀的地方非常方便,假設有乙個建立get請求的函式:

如果你不想設定該請求的header,那你只需要傳入nil:

newget

("",nil

)

而不需傳入乙個空的對映,如:

nil通道是未初始化的通道,當嘗試寫入或者讀取時,會永久阻塞,且無法被close。如:

var c chan os.signal

c close

(c)// panic close of nil channel

在講nil通道的使用場景前,我們先看看關閉的通道的特性。關閉的通道無法傳送資料,接收資料時值為"0"、false,無法close:

var c chan os.signal

v, ok

c close

(c)// panic: close of nil channel

select

如果通道a或者b的其中乙個被關閉,即close(a)或者close(b),那麼,select會陷入死迴圈,不停地從關閉的通道中讀取到"0",false,不停地執行dosomething,最後你們的資料中心燒起來了…

nil通道就能阻止這種事情的發生,當我們希望乙個通道停止讀寫時,我們可以直接設定其為nil,如:

select

dosomething...

case v,ok :=

if!ok

dosomething...

}

這樣就能避免資料中心燒成狗了。

由於在go語言中,函式可以作為結構體的域(field)存在,所以必須為其設定乙個初始值,那就是nil:

type foo struct

nil函式可以用於懶載入或者執行預設操作,如:

func

newserver

(logger func

(string

,...

inte***ce))

logger

("init ... "

)}

nil介面最為常用的場景是作為乙個訊號,想必寫過很多go**的已經見過無數次了,如:

if err !=

nil

需要注意的是空指標並不等於空介面:

golang 介面與nil的判等

在golang中,nil只能賦值給指標 channel func inte ce map或slice型別的變數。如果未遵循這個規則,則會引發panic。nil不能賦值給結構體,編譯時會報錯 package main import fmt type man struct var man man nil...

golang 命令列cobra妙用

大型專案中少不了資料公升級,如果採用web服務,一來不夠安全,二來資料量大的時候也會出超時的情況。這時使用命令列是比較合適的方式了。web專案一般採用mvc模式,對於命令列有嗎?對於命令列則有command 命令 和flag 引數 golang自帶了flag包,不過功能不夠強大,這裡我們使用第三方包...

awk之NF的妙用

在awk中大家都知道nf的作用,它是乙個awk的內建變數,代表是每行的字段數量。常用的幾種方式我給大家慢慢到來。最多的就是在讀取每個字段內容 for i 1 i nf i 這個運用非常之多。我們看看高階的幾個高階用法 cat file a b c d 1 2 3 4 awk vofs nf 0 fi...