在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...