可變參數函數
可變參數函數是一種參數個數可變的函數。
如果函數最後一個參數被記作 ...T ,這時函數可以接受任意個 T 類型參數作為最後一個參數。
隻有函數的最後一個參數才允許是可變的。
package main
import (
"fmt"
)
func find(num int, nums ...int) {
fmt.Printf("type of nums is %T\n", nums)
found := false
for i, v := range nums {
if v == num {
fmt.Println(num, "found at index", i, "in", nums)
found = true
}
}
if !found {
fmt.Println(num, "not found in ", nums)
}
fmt.Printf("\n")
}
func main() {
find(89, 89, 90, 95)
find(87)
}
可變參數函數的
工作原理是把可變參數轉換為一個新的切片
。
是以以上代碼中這三個參數被編譯器轉換為一個 int 類型切片 int []int{89, 90, 95} 然後被傳入 find函數。
在上面代碼中,find 函數僅有一個參數時,我們沒有給可變參數 nums ...int 傳入任何參數。這也是合法的,在這種情況下 nums 是一個長度和容量為 0 的 nil 切片。
給可變參數函數傳入切片
直接給可變參數函數傳入切片,這種情況下無法通過編譯,編譯器報出錯誤
main.go:23: cannot use nums (type []int) as type int in argument to find 。
在上邊的代碼中可以看到,這些可變參數會被轉換為 int 類型切片然後再傳入 find 函數中,而如果傳入的已經是一個 int 類型切片,
編譯器試圖在 nums 基礎上再建立一個切片,像下面這樣:
nums := []int{89, 90, 95}
find(89, []int{nums})
這顯然是錯誤的。
如果非要直接傳入切片,有一個可以直接将切片傳入可變參數函數的文法糖,你可以在在切片後加上 ... 字尾。如果這樣做,切片将直接傳入函數,不再建立新的切片。
func main() {
nums := []int{89, 90, 95}
find(89, nums...)
}
易錯點1
看下邊代碼:
package main
import (
"fmt"
)
func change(s ...string) {
s[0] = "Go"
}
func main() {
welcome := []string{"hello", "world"}
change(welcome...)
fmt.Println(welcome)
}
如果使用了 ... ,welcome 切片本身會作為參數直接傳入,不需要再建立一個新的切片。這樣參數 welcome 将作為參數傳入 change 函數
在 change 函數中,切片的第一個元素被替換成 Go,這樣程式産生了下面的輸出值:
[Go world]
易錯點2
繼續看代碼:
package main
import (
"fmt"
)
func change(s ...string) {
s[0] = "Go"
s = append(s, "playground")
fmt.Println(s)
}
func main() {
welcome := []string{"hello", "world"}
change(welcome...)
fmt.Println(welcome)
}
運作結果:
[Go world playground]
[Go world]
在最初的時候有一句話:GO 語言的參數傳遞都是 值傳遞。
這裡就是考究的對這句話的了解。 還有就是對slice的了解。
slice 包含 3部分: 長度、容量和指向數組第零個元素的指針 所謂的值傳遞怎麼了解呢,就是傳遞slice 的時候,把這三個值拷一個副本,傳遞過去。注意:指針作為值拷貝的副本,指向的是同一個位址,是以修改位址的内容時,原slice也就随之改變。 反之,對拷貝slice副本的修改,如:append,改變的是副本的len、cap,原slice的len、cap并不受影響。
Maps
- map 是在 Go 中将鍵(key)與值(value)關聯的内置類型。通過相應的鍵可以擷取到值。
//建立 map 的文法。
make(map[type of key]type of value)
//建立了一個名為 personSalary 的 map,鍵是 string 類型,而值是 int 類型。
personSalary := make(map[string]int)
map 的零值是 nil。如果你想添加元素到 nil map 中,會觸發運作時 panic。是以 map 必須使用 make 函數初始化。
package main
import (
"fmt"
)
func main() {
var personSalary map[string]int
if personSalary == nil {
fmt.Println("map is nil. Going to make one.")
personSalary = make(map[string]int)
}
}
給map添加元素
這裡map添加元素和python中dict很像,直接指派便可:
func main() {
var personSalary map[string]int
if personSalary == nil {
fmt.Println("map is nil. Going to make one.")
personSalary = make(map[string]int)
}
personSalary["num"] = 2
personSalary["age"] = 24
fmt.Println(personSalary)
}
你也可以在聲明的時候初始化 map:
package main
import (
"fmt"
)
func main() {
personSalary := map[string]int{
"steve": 12000,
"jamie": 15000,
}
personSalary["mike"] = 9000
employee := "jamie"
fmt.Println("Salary of", employee, "is", personSalary[employee])
}
如果擷取一個不存在的元素,map 會傳回該元素類型的零值。
例如:在 personSalary 這個 map 裡,如果我們擷取一個不存在的元素,會傳回 int 類型的零值 0。
map中擷取不包含指定key時,不會産生運作錯誤。
判斷map中是否存在指定的key
value, ok := parMap["g"]
如果存在,ok=ture,value=對應的其值
如果不存在,ok=false,value=該map值得類型的零值
func main() {
parMap := map[string]int{
"name":2,
"age":22,
}
fmt.Println(parMap)
value, ok := parMap["g"]
fmt.Println(value, ok)
}
周遊map
使用for := range周遊
for value, key := range parMap
package main
import (
"fmt"
)
func main() {
personSalary := map[string]int{
"steve": 12000,
"jamie": 15000,
}
personSalary["mike"] = 9000
fmt.Println("All items of a map")
for key, value := range personSalary {
fmt.Printf("personSalary[%s] = %d\n", key, value)
}
}
有一點很重要,當使用 for range 周遊 map 時,不保證每次執行程式擷取的元素順序相同。
删除map中的key
删除
map
中
key
的文法是
delete(map, key)。這個函數沒有傳回值。
package main
import (
"fmt"
)
func main() {
personSalary := map[string]int{
"steve": 12000,
"jamie": 15000,
}
personSalary["mike"] = 9000
fmt.Println("map before deletion", personSalary)
delete(personSalary, "steve")
fmt.Println("map after deletion", personSalary)
}
擷取map的長度
使用len()函數擷取map的長度
len(personSalary)
注意:
Map是引用類型,和 slices 類似。當 map 被指派為一個新變量的時候,它們指向同一個内部資料結構。是以,改變其中一個變量,就會影響到另一變量。
當 map 作為函數參數傳遞時也會發生同樣的情況。函數中對 map 的任何修改,對于外部的調用都是可見的。
map 之間不能使用 == 操作符判斷,== 隻能用來檢查 map 是否為 nil。會報錯: invalid operation: map1 == map2 (map can only be compared to nil)。
如果文章對您有幫助,記得點個贊,後續持續更新ing~~~