【8.0】Go语言基础之可变函数参数、map的使用
【一】可变长参数
【1】任意长度的指定类型的参数
package main
import "fmt"
func main() {
// 可变长参数
// 调用函数
foo(1, 2, 3, 4, 5, 6)
// 这是接收到的 参数 a :>>>> [1 2 3 4 5 6]
// 这是接收到的 参数 a 的类型 :>>>> []int
}
// 可以接收任意长度的 int 类型参数
func foo(a ...int) { // 可以接收任意长度参数,但是类型必须一致
fmt.Println("这是接收到的 参数 a :>>>> ", a)
fmt.Printf("这是接收到的 参数 a 的类型 :>>>> %T", a) // 切片类型
}
【2】任意长度的任意类型的参数
package main
import "fmt"
func main() {
// 可变长参数
// 调用函数
foo(1, 2, 3, 4, 5, 6, "dream")
// 这是接收到的 参数 a :>>>> [1 2 3 4 5 6 dream]
// 这是接收到的 参数 a 的类型 :>>>> []interface {}
}
// 可以接收任意长度的 任意 类型参数
func foo(a ...interface{}) { // 可以接收任意长度参数,但是类型必须一致
fmt.Println("这是接收到的 参数 a :>>>> ", a)
fmt.Printf("这是接收到的 参数 a 的类型 :>>>> %T", a) // 空接口类型
}
【3】切片类型的参数传入
package main
import "fmt"
func main() {
// 可变长参数
// 调用函数
// 定义切片类型
a := []int{1, 2, 3, 4, 5}
foo(a...) // 相当于将切片 a 打散传入
// 这是接收到的 参数 a :>>>> [1 2 3 4 5]
// 这是接收到的 参数 a 的类型 :>>>> []int
}
// 可以接收任意长度的 int 类型参数
func foo(a ...int) { // 可以接收任意长度参数,但是类型必须一致
fmt.Println("这是接收到的 参数 a :>>>> ", a)
fmt.Printf("这是接收到的 参数 a 的类型 :>>>> %T", a) // 切片类型
}
【二】map类型
- map 是在 Go 中将值(value)与键(key)关联的内置类型。通过相应的键可以获取到值(字典类型)
- key值只能用数字,字符串,布尔,key值也固定
- value值可以任意,但是go中value值必须都一致
【1】定义map
package main
import "fmt"
// map 的 使用
func main() {
// [1] map 的定义
// 定义map类型 : key 为 string 类型 ; value 为 int 类型
var m map[string]int
// 只定义,没有初始化
fmt.Println("这是创建的 map :>>>> ", m) // 这是创建的 map :>>>> map[]
if m == nil {
fmt.Println("map 类型的 0 值 为 nil")
}
// map 类型的 0 值 为 nil
}
【2】初始化map
(1)方式1
package main
import "fmt"
// map 的 使用
func main() {
// [1] map 的定义
// 定义map类型 : key 为 string 类型 ; value 为 int 类型
// 初始化 map
var m map[string]int = make(map[string]int)
fmt.Println("这是创建的 map :>>>> ", m) // 这是创建的 map :>>>> map[]
if m == nil {
fmt.Println("map 类型的 0 值 为 nil")
} else {
fmt.Println("map 类型的 0 值 不是 nil")
}
// map 类型的 0 值 不是 nil
}
(2)方式2
package main
import "fmt"
// map 的 使用
func main() {
// [1] map 的定义
// 定义map类型 : key 为 string 类型 ; value 为 int 类型
// 初始化 map
var m map[string]int = map[string]int{"name": 1, "value": 1}
fmt.Println("这是创建的 map :>>>> ", m) // 这是创建的 map :>>>> map[name:1 value:1]
}
(3)方式3
package main
import "fmt"
// map 的 使用
func main() {
// [1] map 的定义
// 定义map类型 : key 为 string 类型 ; value 为 int 类型
// 初始化 map
m := map[string]int{"name": 1, "value": 1}
fmt.Println("这是创建的 map :>>>> ", m) // 这是创建的 map :>>>> map[name:1 value:1]
}
【3】map的使用
(1)取值和赋值
package main
import "fmt"
// map 的 使用
func main() {
// [1] map 的使用 : 取值 / 赋值
// 定义map类型 : key 为 string 类型 ; value 为 int 类型
// 初始化 map
m := map[string]int{"name": 1, "value": 1}
fmt.Println("这是创建的 map :>>>> ", m) // 这是创建的 map :>>>> map[name:1 value:1]
// 取值 , 赋值
// 根据 key 取值
fmt.Println("根据 key 取值 :>>>> ", m["name"]) // 根据 key 取值 :>>>> 1
// 赋值
m["value"] = 9
fmt.Println("这是修改后的 map :>>>> ", m) // 这是修改后的 map :>>>> map[name:1 value:9]
// 赋值不存在会新增
m["age"] = 18
fmt.Println("这是修改后的 map :>>>> ", m) // 这是修改后的 map :>>>> map[age:18 name:1 value:9]
// map 可以无限制的添加值 , 前提是内存够用
// 取值不存在的值 --- 不会报错 , 但是会取出 value 为 int 类型 的 0 值
fmt.Println("根据 key 取值 :>>>> ", m["gender"]) // 根据 key 取值 :>>>> 0
// 当某个值 存进去 为 0 值 (不存在也是 0 值 )
fmt.Println("根据 key(不存在) 取值 :>>>> ", m["gender"]) // 根据 key(不存在) 取值 :>>>> 0
m["sex"] = 0
fmt.Println("根据 key(赋 0 值) 取值 :>>>> ", m["sex"]) // 根据 key(赋 0 值) 取值 :>>>> 0
// 根据 key 取 value , 判断 value 是否存在
_, ok := m["school"] // 可以使用两个值来接收,第二个值为布尔值,如果 ok 为 true ,说明存在,否则不存在
fmt.Println("根据 key(不存在) 取值 :>>>> ", ok) // 根据 key(不存在) 取值 :>>>> false
m["school"] = 999
_, okk := m["school"]
fmt.Println("根据 key(存在) 取值 :>>>> ", okk) // 根据 key(存在) 取值 :>>>> true
}
(2)判断value值是否存在
- 见上
(3)删除值
package main
import "fmt"
// map 的 使用
func main() {
// [1] map 的使用 : 取值 / 赋值
// 定义map类型 : key 为 string 类型 ; value 为 int 类型
// 初始化 map
m := map[string]int{"name": 1, "value": 1}
fmt.Println("这是创建的 map :>>>> ", m) // 这是创建的 map :>>>> map[name:1 value:1]
// 删除存在值
delete(m, "name") // 只能根据 key 删除
fmt.Println("这是删除后的 map :>>>> ", m) // 这是删除后的 map :>>>> map[value:1]
// 删除不存在的值
delete(m, "school") // 本来就没有 对应的 value 值 ,所以删除完还是没有
fmt.Println("这是删除后的 map :>>>> ", m) // 这是删除后的 map :>>>> map[value:1]
}
【4】map的长度
package main
import "fmt"
// map 的 使用
func main() {
// [1] map 的使用 : 取值 / 赋值
// 定义map类型 : key 为 string 类型 ; value 为 int 类型
// 初始化 map
m := map[string]int{"name": 1, "value": 1}
fmt.Println("这是创建的 map :>>>> ", m) // 这是创建的 map :>>>> map[name:1 value:1]
// map 的 长度 : 总共有多少个元素
fmt.Println("map 的长度 :>>>> ", len(m)) // map 的长度 :>>>> 2
// 没有容量,但是可以无限扩容,前提是内存足够大
}
【5】map类型的零值
- map是引用类型,零值是 nil,引用类型一定要初始化,值类型不需要初始化就有零值
package main
import "fmt"
// map 的 使用
func main() {
// [1] map 的使用 : 取值 / 赋值
// 定义map类型 : key 为 string 类型 ; value 为 int 类型
// 初始化 map
m := map[string]int{"name": 1, "value": 1}
fmt.Println("这是创建的 map :>>>> ", m) // 这是创建的 map :>>>> map[name:1 value:1]
// map是引用类型,零值是 nil,引用类型一定要初始化,值类型不需要初始化就有零值
// 当参数传递 : 原来的 map 会被修改 (引用传递)
// 调用函数foo
fmt.Println("这是调用函数之前的 m :>>>> ", m) // 这是调用函数之前的 m :>>>> map[name:1 value:1]
bar(m) // 这是函数内部的 m :>>>> map[name:1 value:999]
fmt.Println("这是调用函数之后的 m :>>>> ", m) // 这是调用函数之后的 m :>>>> map[name:1 value:999]
}
func bar(m map[string]int) {
m["value"] = 999
fmt.Println("这是函数内部的 m :>>>> ", m)
}
【6】map类型之间不能 ==
操作
package main
import "fmt"
// map 的 使用
func main() {
// [1] map 的使用 : 取值 / 赋值
// 定义map类型 : key 为 string 类型 ; value 为 int 类型
// 初始化 map
m := map[string]int{"name": 1, "value": 1}
n := map[string]int{"name": 1, "value": 1}
fmt.Println("这是创建的 map :>>>> ", m) // 这是创建的 map :>>>> map[name:1 value:1]
fmt.Println("这是创建的 map :>>>> ", n) // 这是创建的 map :>>>> map[name:1 value:1]
// map是引用类型,零值是 nil,引用类型一定要初始化,值类型不需要初始化就有零值
// map 之间不能使用 == 操作符判断,== 只能用来检查 map 是否为 nil
// fmt.Println(m==n) // Invalid operation: m==n (the operator == is not defined on map[string]int)
// 引用类型不能比较 ,值类型能比较
a := [3]int{4, 5, 6}
b := [3]int{4, 6, 6}
c := [4]int{4, 6, 6}
fmt.Println(a)
fmt.Println(b)
fmt.Println(c)
fmt.Println(a == b) // 长度不一样,不是同一个类型
//fmt.Println(a == c) // Invalid operation: a==c (mismatched types [3]int and [4]int)
}
【补充】各种数据类型的零值
package main
import "fmt"
// map 的 使用
func main() {
// 补充 :数字 字符串 布尔 切片 数组 map 类型的 0 值
// 数字 字符串 布尔 数组 ----> 值类型 (有自己的零值 0 "" false 元素类型的零值)
// 切片 map ----> 引用类型 (零值 是 nil)
var a int
fmt.Println("数字类型的 0 值为 :>>>> ", a) // 数字类型的 0 值为 :>>>> 0
var b float32
fmt.Println("浮点类型的 0 值为 :>>>> ", b) // 浮点类型的 0 值为 :>>>> 0
var n bool
fmt.Println("布尔类型的 0 值为 :>>>> ", n) // 布尔类型的 0 值为 :>>>> false
var c string
fmt.Println("字符串类型的 0 值为 :>>>> ", c) // 字符串类型的 0 值为 :>>>>
var d []int
fmt.Println("数组类型的 0 值为 :>>>> ", d) // 数组类型的 0 值为 :>>>> []
var e [][]int
fmt.Println("切片类型的 0 值为 :>>>> ", e) // 切片类型的 0 值为 :>>>> []
var m map[int]string
fmt.Println("map类型的 0 值为 :>>>> ", m) // map类型的 0 值为 :>>>> map[]
}
本文来自博客园,作者:Chimengmeng,转载请注明原文链接:https://www.cnblogs.com/dream-ze/p/17826368.html