Go 沒有空、null 或 undefined 這類變數值概念。 沒有明確初始值的變數,會預設為其型別對應的零值。
布林、數值型別和字串等基本型別的零值,分別是 false、0 和 ""。
識別字 nil 代表零,是較複雜型別的零值,例如指標、函式、介面、切片、通道和映射。
下表列出 Go 各型別的零值。
| 型別 | 零值 |
|---|---|
| 布林 | false |
| 數值 | 0 |
| 字串 | "" |
| 指標 | nil |
| 函式 | nil |
| 介面 | nil |
| 切片 | nil |
| 通道 | nil |
| 映射 | nil |
你可能注意到上表沒有列出結構型別。 這是因為結構型別的零值取決於它的欄位。 當結構的所有欄位都設為各自的零值時,這個結構也就會被設為它的零值。
你的工作是為即將到來的人口普查準備這座城市的 IT 系統。具體來說,你要負責撰寫處理普查員資料的程式。
當取得居民的資訊時,程式必須能夠在系統中建立新的居民。此外,你還要撰寫一些函式,用來確認居民的資料中包含必要的資訊,以及刪除居民的資料。最後,你要統計居民人數,提供準確的人口普查數字。
當普查員收集居民的資訊時,他們需要把居民的姓名、年齡和地址輸入系統,藉此登記該居民。
實作NewResident函式,它接受三個引數:
這個函式應該回傳一個指向Resident結構的指標,該結構用來保存這些資訊。
name := "Matthew Sanabria"
age := 29
address := map[string]string{"street": "Main St."}
NewResident(name, age, address)
// => &{Matthew Sanabria 29 map[street:Main St.]}
居民可能不太願意向普查員提供個人資料。在這種情況下,就必須判斷居民是否提供了必要的資訊,才能被計入人口普查。
若要被計入普查,居民提供的姓名必須是非零值,而且地址中street鍵的值也必須是非零值。其他所有資訊,例如居民的年齡,都不是必填的。實作HasRequiredInfo方法,它會回傳布林值,指出該居民是否已提供必要的資訊。
name := "Matthew Sanabria"
age := 0
address := make(map[string]string)
resident := NewResident(name, age, address)
resident.HasRequiredInfo()
// => false
人生變化很快,錯誤也在所難免。居民可能搬離這座城市。普查員在收集資料時也可能出錯。在這些情況下,必須能夠刪除居民的資料,讓他們不會被計入普查。
實作Delete方法,把居民的所有欄位都設為零值。
name := "Matthew Sanabria"
age := 29
address := map[string]string{"street": "Main St."}
resident := NewResident(name, age, address)
fmt.Println(resident)
// Output: &{Matthew Sanabria 29 map[street:Main St.]}
resident.Delete()
fmt.Println(resident)
// Output: &{ 0 map[]}
現在系統已經支援人口普查資料,是時候進行普查並統計居民人數了!
實作Count函式,它接受一個引數:
Resident結構的指標所組成的切片。這個函式應該回傳一個整數,指出有多少居民被計入人口普查。居民只有在提供普查員必要資訊的情況下,才能被計入。
name1 := "Matthew Sanabria"
age1 := 29
address1 := map[string]string{"street": "Main St."}
resident1 := NewResident(name1, age1, address1)
name2 := "Rob Pike"
age2 := 0
address2 := make(map[string]string)
resident2 := NewResident(name2, age2, address2)
residents := []*Resident{resident1, resident2}
Count(residents)
// => 1