变量
变量的定义以及初始化
var username string
username = "张三"
fmt.Println(username) //张三
var username1 string = "张三"
fmt.Println(username1) //张三
var username2 = "张三"
fmt.Println(username2) //张三
一次定义多个变量
同一种数据类型
var a1, a2 string
a1 = "a1" //a1
a2 = "a2" //a2
fmt.Println(a1, a2)
不同数据类型
var (
username4 string
age int
sex string
)
username4 = "张三"
age = 20
sex = "男"
fmt.Println(username4, age, sex)
var (
username5 = "张三"
age2 = 20
)
fmt.Println(username5, age2)
短变量声明方式
a, b, c := 12, 13, "C"
fmt.Println(a, b, c)
fmt.Printf("a类型:%T b类型:%T c类型:%T", a, b, c)
匿名变量
func getUserinfo() (string, int) {
return "zhangsan", 10
}
返回2个值
var username7, age23 = getUserinfo()
fmt.Println(username7, age23)
返回一个值报错
var username7 = getUserinfo()
fmt.Println(username7)
只想要一个返回值时,可以使用匿名
var username7, _ = getUserinfo()
fmt.Println(username7)
var _, age23 = getUserinfo()
fmt.Println(age23) //10
常量
不可修改
const A = "aa"
A = "BB"
fmt.Println(A)
const (
A = "A"
B = "B"
)
fmt.Println(A, B)
const (
n1 = iota
n2
n3
n4
)
fmt.Println(n1, n2, n3, n4) //0 1 2 3
整型
var num int = 10
num = 22
fmt.Printf("num=%v 类型%T", num, num) //num=22 类型int
int8的范围演示
var num1 int8 = 98
fmt.Printf("num=%v 类型:%T", num1, num1)
var num2 int8 = 130 //constant 130 overflows int8
fmt.Printf("num=%v 类型:%T", num2, num2)
var num int16 = 130
fmt.Printf("num=%v 类型:%T", num, num)
变量占用的字节数
var a int8 = 15
fmt.Println(unsafe.Sizeof(a)) //1个字节
var b int32 = 15
fmt.Println(unsafe.Sizeof(b)) // 4个字节
int类型转换
var a1 int32 = 10
var a2 int64 = 21
fmt.Println(int64(a1) + a2) //把a1转换成64位
fmt.Println(a1 + int32(a2)) //把a2转换成32位
以不同进制的方式输出
num := 12
fmt.Printf("num=%v\n", num) //%v 原样输出 // num=12
fmt.Printf("num=%d\n", num) //%d 表示10进制输出 // num=12
fmt.Printf("num=%b\n", num) //%b 表示二进制输出 // num=1100
fmt.Printf("num=%o\n", num) //%o 表示八进制输出 // num=14
fmt.Printf("num=%x\n", num) //%x 表示16进制输出 // num=14
浮点型
定义float类型
var a float32 = 3.12
fmt.Printf("值:%v--%f,类型%T\n", a, a, a)
//值:3.12--3.120000,类型float32
fmt.Println(unsafe.Sizeof(a))
//4
var b float64 = 3.12
fmt.Printf("值:%v--%f,类型%T\n", b, b, b)
//值:3.12--3.120000,类型float64
fmt.Println(unsafe.Sizeof(b))
//8
保留小数点后面几位
var c float64 = 3.1415925535
fmt.Printf("%v--%f--%.2f--%.4f", c, c, c, c)
// 3.1415925535--3.141593--3.14--3.1416
精度丢失问题
var f4 float64 = 1129.6
fmt.Println(f4 * 100) //112959.99999999999
m1 := 8.2
m2 := 3.8
fmt.Println(m1 - m2) //4.3999999999999995
int类型转换成float类型
a := 10
b := float64(a)
fmt.Printf("a的类型是%T,b的类型是%T", a, b)
//a的类型是int,b的类型是float64
var a1 float32 = 23.4
a2 := float64(a1)
fmt.Printf("a1的类型是%T,a2的类型是%T", a1, a2)
//a1的类型是float32,a2的类型是float64
float类型转换成int类型 不建议这样做,精度丢失问题
var c1 float32 = 23.45
c2 := int(c1)
fmt.Printf("c2的值:%v c2的类型:%T", c2, c2)
//c2的值:23 c2的类型:int
bool 布尔
- 布尔类型变量的默认值为false。
- Go 语言中不允许将整型强制转换为布尔型.
- 布尔型无法参与数值运算,也无法与其他类型进行转换
var flag = true
fmt.Printf("%v--%T", flag, flag) //true--bool
var b bool
fmt.Printf("%v", b) //false
在if里判断
//正确写法
var f1 = false
if f1 { //正确写法
fmt.Printf("true")
} else {
fmt.Printf("false")
}
//错误写法
var a = 1
if a { //错误写法
fmt.Printf("true")
}
var s = "this is str"
if s { //错误写法
fmt.Printf("true")
}
不同类型变量的默认值
int型变量的默认值为0
var i int
fmt.Printf("%v", i) //0
float型变量的默认值为0
var f float32
fmt.Printf("%v", f) //0
string型变量的默认值为空
var s string
fmt.Printf("%v", s)
// 布尔类型变量的默认值为false
// var b bool
// fmt.Printf("%v", b)
字符串
基本操作
定义string类型
var str1 string = "你好golang"
var str2 = "你好 go"
str3 := "你好golang"
fmt.Printf("%v--%T\n", str1, str1)
fmt.Printf("%v--%T\n", str2, str2)
fmt.Printf("%v--%T\n", str3, str3)
字符串转义符
换行
str1 := "this \nis str" //换行
fmt.Println(str1)
this
is str
输出反斜杠
str2 := "C:\\Go\\bin" //C:\Go\bin 输出反斜杠
fmt.Println(str2)
str3 := "C:Go\"bin"
fmt.Println(str3)
C:\Go\bin
C:Go"bin
多行字符串
str1 := `a
this is str
this is str
this is str111
this is str
this is str
`
fmt.Println(str1)
a
this is str
this is str
this is str111
this is str
this is str
字符串方法
len(str) 求长度
var str1 = "aaaa" //长度4
fmt.Println(len(str1)) //4
- 或者 fmt.Sprintf拼接字符串
str1 := "你好"
str2 := "golang"
str3 := str1 + str2
fmt.Println(str3) //你好golang
str1 := "你好"
str2 := "golang"
str3 := fmt.Sprintf("%v%v", str1, str2)
fmt.Println(str3) //你好golang
strings.Split 分割字符串
var str1 = "123-456-789"
arr := strings.Split(str1, "-")
fmt.Println(arr) //[123 456 789]
strings.join 把切片链接成字符串
arr := []string{"php", "java", "golang"}
str3 := strings.Join(arr, "-")
fmt.Printf("%v - %T", str3, str3) //php-java-golang - string
判断是否包含
str1 := "this is str"
str2 := "thisxxx"
flag := strings.Contains(str1, str2)
fmt.Println(flag) //false
前缀/后缀判断
str1 := "this is str"
str2 := "this"
flag := strings.HasPrefix(str1, str2)
fmt.Println(flag) //true
str1 := "this is str"
str2 := "str"
flag := strings.HasSuffix(str1, str2)
fmt.Println(flag) //false
strings.Index(),strings.LastIndex() 子串出现的位置 查找不到返回-1
str1 := "this is str"
str2 := "is"
num := strings.Index(str1, str2)
print(num) //返回2
str1 := "this is str"
str2 := "is"
num := strings.LastIndex(str1, str2)
print(num) //返回5
str1 := "this is str"
str2 := "xxx"
num := strings.Index(str1, str2)
print(num) //-1 查找不到返回-1
byte 和 rune 类型
组成每个字符串的元素叫做“字符”,可以通过遍历字符串元素获得字符。 字符用单引号(’) 包裹起来
字节(byte):是计算机中 数据处理 的基本单位,习惯上用大写 B 来表示,1B(byte,字节) = 8bit(位)
字符是指计算机中使用的字母、数字、字和符号
定义字符
var a = 'a'
var b = 'b'
fmt.Printf("值:%v 类型:%T\n", a, a) //值:97 类型:int32
fmt.Printf("值:%v 类型:%T", b, b)
// 值:97 类型:int32
// 值:98 类型:int32
原样输出字符%c
var a = 'a'
fmt.Printf("值:%c 类型:%T", a, a)
// 值:a 类型:int32
定义一个字符串输出字符串里面的字符
var str = "this"
fmt.Printf("值:%v 原样输出%c 类型:%T", str[2], str[2], str[2])
// 值:105 原样输出i 类型:uint8
一个汉子占用 3 个字节 一个字母占用一个字节
var str = "this" //占用4个字节
fmt.Println(len(str)) //4
var str = "你好go" //8
fmt.Println(len(str)) //8
通过循环输出字符串里面的字符
s := "你好 golang"
for i := 0; i < len(s); i++ { //byte
fmt.Printf("%v(%c)", s[i], s[i])
}
//228(ä)189(½)160( )229(å)165(¥)189(½)32( )103(g)111(o)108(l)97(a)110(n)103(g)
s1 := "你好 golang"
for _, v := range s1 { //rune
fmt.Printf("%v(%c) ", v, v)
}
//20320(你) 22909(好) 32( ) 103(g) 111(o) 108(l) 97(a) 110(n) 103(g)
修改字符串
byte只能修改英文 rune能修改英文和中文或者其他复合字符
s1 := "big"
byteStr := []byte(s1)
byteStr[0] = 'p'
fmt.Println(string(byteStr)) //pig
s1 := "你好golang" //有中文用rune
runeStr := []rune(s1)
runeStr[0] = '大'
fmt.Println(string(runeStr)) //大好golang
数据类型转换
Go 语言中只有强制类型转换,没有隐式类型转换
数值类型之间的相互转换
数值类型包括:整形和浮点型
整型和整型之间的转换
var a int8 = 20
var b int16 = 40
// fmt.Println(a + b) //报错 nvalid operation: a + b (mismatched types float32 and float64)
fmt.Println(int16(a) + b) //60
浮点型和浮点型之间的转换
var a float32 = 20
var b float64 = 40
// fmt.Println(a + b) //nvalid operation: a + b (mismatched types float32 and float64)
fmt.Println(float64(a) + b)
整型和浮点型之间的转换
转换的时候建议从低位转换成高位,高位转换成低位的时候如果转换不成功就会溢出,和我们想的结果不一样。
var a float32 = 20.23
var b int = 40
fmt.Println(a + float32(b)) //60.23
转换成 String 类型
mt.Sprintf()
Sprintf 使用中需要注意转换的格式 int 为%d float 为%f bool 为%t byte 为%c
var i int = 20
var f float64 = 12.456
var t bool = true
var b byte = 'a'
str1 := fmt.Sprintf("%d", i)
fmt.Printf("值:%v 类型:%T\n", str1, str1)
//值:20 类型:string
str2 := fmt.Sprintf("%.2f", f)
fmt.Printf("值:%v 类型:%T\n", str2, str2)
//值:12.46 类型:string
str3 := fmt.Sprintf("%t", t)
fmt.Printf("值:%v 类型:%T\n", str3, str3)
//值:true 类型:string
str4 := fmt.Sprintf("%c", b)
fmt.Printf("值:%v 类型:%T\n", str4, str4)
//值:a 类型:string
strconv
FormatInt
参数1:int64 的数值
参数2:传值int类型的进制
var i int = 20
str1 := strconv.FormatInt(int64(i), 10)
fmt.Printf("值:%v 类型:%T\n", str1, str1)
//值:20 类型:string
var f float32 = 20.231313
str2 := strconv.FormatFloat(float64(f), 'f', 4, 32)
fmt.Printf("值:%v 类型:%T\n", str2, str2
string类型转换成整型
str := "123456"
/*
ParseInt
参数1:string数据
参数2:进制
参数3:位数 32 64 16
*/
num, _ := strconv.ParseInt(str, 10, 64)
fmt.Printf("%v--%T", num, num) //123456--int64
/*
ParseFloat
参数1:string数据
参数2:位数 32 64
*/
str := "123456.333"
// str := "123456.333xxxx"
num, _ := strconv.ParseFloat(str, 64)
fmt.Printf("%v--%T", num, num) //123456.333--float64
流程控制
if
基本写法
age := 30
if age > 18 {
fmt.Println("成年人")
} else {
fmt.Println("不是成年人")
}
特殊写法
//当前区域内是全局变量
age := 30
if age > 20 {
fmt.Println("成年人", age)
}
fmt.Println(age)
//局部变量
if age2 := 34; age2 > 20 {
fmt.Println("成年人", age2)
}
fmt.Println(age2) // undefined: age
for
基本写法
for i := 1; i <= 5; i++ {
fmt.Println(i)
}
初始语句可以被忽略,但是初始语句后的分号必须要写
i := 1
for ; i <= 5; i++ {
fmt.Println(i)
}
初始语句和结束语句都可以省略
i := 1
for i <= 5 {
fmt.Println(i)
i++
}
for range
类似js中的forEach
字符串
var str = "你好golang"
for k, v := range str {
fmt.Printf("%v-%c,", k, v)
}
//0-你,3-好,6-g,7-o,8-l,9-a,10-n,11-g,
数组
var arr = []string{"php", "java", "node", "golang"}
for i := 0; i < len(arr); i++ {
fmt.Printf("%v,", arr[i])
}
//php,java,node,golang
for _, val := range arr {
fmt.Printf(val)
}
//php,java,node,golang
switch case
基本使用
var extname = ".css"
switch extname {
case ".html":
fmt.Println("text/html")
break
case ".css":
fmt.Println("text/css")
break
case ".js":
fmt.Println("text/javascript")
break
default:
fmt.Println("找不到此后缀")
}
局部变量
switch score := "D"; score {
case "A", "B", "C":
fmt.Println("及格")
case "D":
fmt.Println("不及格")
}
一个分支可以有多个值,多个 case 值中间使用英文逗号分隔
var n = 8
switch n {
case 1, 3, 5, 7, 9:
fmt.Println("奇数")
break //golang中break可以写也可以不写
case 2, 4, 6, 8, 10:
fmt.Println("偶数")
break
}
分支还可以使用表达式
var age = 18
switch {
case age < 24:
fmt.Println("好好学习")
case age >= 24 && age <= 60:
fmt.Println("好好赚钱")
case age > 60:
fmt.Println("注意身体")
default:
fmt.Println("输入错误")
}
switch 的穿透 fallthrought
var age = 30
switch {
case age < 24:
fmt.Println("好好学习")
case age >= 24 && age <= 60:
fmt.Println("好好赚钱")
fallthrough
case age > 60:
fmt.Println("注意身体")
default:
fmt.Println("输入错误")
}
//好好赚钱
//注意身体
break
for i := 1; i <= 10; i++ {
if i == 2 {
break
}
fmt.Println(i)
}
fmt.Println("继续执行")
//1
//继续执行
continue
for i := 1; i <= 5; i++ {
if i == 3 {
continue
}
fmt.Println(i)
}
goto
var n = 30
if n > 24 {
fmt.Println("成年人")
goto lable3
}
fmt.Println("aaa")
fmt.Println("bbb")
lable3:
fmt.Println("ccc")
fmt.Println("ddd")
成年人
ccc
ddd
数组
数组的长度是类型的一部分
var arr1 [3]int
var arr2 [4]int
var strArr [3]string
fmt.Printf("arr1:%T arr2:%T strArr:%T", arr1, arr2, strArr)
//arr1:[3]int arr2:[4]int strArr:[3]string
数组的初始化
第一种方法
var arr1 [3]int
arr1[0] = 23
arr1[1] = 10
arr1[2] = 24
fmt.Println(arr1) //[23 10 24]
// var strArr [3]string
// strArr[0] = "php"
// strArr[1] = "java"
// strArr[2] = "golang"
// // strArr[3] = "js" //out of bounds for 3-element array
// fmt.Println(strArr) //[php java golang]
第二种方法
var arr1 = [3]int{23, 34, 5}
fmt.Println(arr1) //[23 34 5]
var arr2 = [3]string{"php", "nodejs", "golnag"}
fmt.Println(arr2) //[php nodejs golnag]
arr3 := [3]string{"php", "nodejs", "golnag"}
fmt.Println(arr3) //[php nodejs golnag]
第三种方法
一般情况下我们可以让编译器 根据初始值的个数自行推断数组的长度
var arr1 = [...]int{12, 2324, 32435, 353, 535, 3535}
fmt.Println(arr1) //[12 2324 32435 353 535 3535]
fmt.Println(len(arr1)) //len()打印数组的长度 6
第四种方法
用指定索引值的方式来初始化数组
arr := [...]int{0: 1, 1: 10, 2: 20, 5: 50}
fmt.Println(len(arr)) //6
fmt.Println(arr) //[1 10 20 0 0 50]
改变数组里面的值
arr1 := [...]string{"php", "nodejs", "golnag", "js"}
arr1[0] = "phper"
fmt.Println(arr1)
数组的循环遍历
var arr = [3]int{23, 34, 5}
for i := 0; i < len(arr); i++ {
fmt.Println(arr[i])
}
arr2 := [...]string{"php", "nodejs", "golnag", "js"}
for k, v := range arr2 {
fmt.Printf("key:%v value:%v\n", k, v)
}
数组是值类型
值类型 :改变变量副本值的时候,不会改变变量本身的值 引用类型:改变变量副本值的时候,会改变变量本身的值
var arr1 = [...]int{1, 2, 3}
arr2 := arr1
arr1[0] = 11
fmt.Println(arr1)
fmt.Println(arr2)
二维数组
var arr = [3]int{1, 2, 3} //一维数组
fmt.Println(arr)
//二维数组
var arr = [3][2]string{
{"北京", "上海"},
{"广州", "深圳"},
{"成都", "重庆"},
}
fmt.Println(arr[0]) //[北京 上海]
fmt.Println(arr[0][1]) //上海
不限定个数的二维数组
var arr = [...][2]string{
{"北京", "上海"},
{"广州", "深圳"},
{"成都", "重庆"},
{"成都", "重庆"},
{"成都", "重庆"},
}
fmt.Println(arr)
遍历二维数组
var arr = [3][2]string{
{"北京", "上海"},
{"广州", "深圳"},
{"成都", "重庆"},
}
for _, v1 := range arr {
for _, v2 := range v1 {
fmt.Println(v2)
}
}
//北京
上海
广州
深圳
成都
重庆
切片
切片的声明 初始化
与数组相比不写长度
var arr1 []int
fmt.Printf("%v - %T - 长度:%v\n", arr1, arr1, len(arr1))
//[] - []int - 长度:0
var arr2 = []int{1, 2, 34, 45}
fmt.Printf("%v - %T - 长度:%v\n", arr2, arr2, len(arr2))
//[1 2 34 45] - []int - 长度:4
var arr3 = []int{1: 2, 2: 4, 5: 6}
fmt.Printf("%v - %T - 长度:%v", arr3, arr3, len(arr3))
//[0 2 4 0 0 6] - []int - 长度:6
切片的默认值就是nil
var arr1 []int
var arr2 = []int{1, 2, 34, 45}
fmt.Println(arr1) //[]
fmt.Println(arr1 == nil) //true golnag中申明切片以后 切片的默认值就是nil
fmt.Println(arr2 == nil) //false
切片的循环遍历
var strSlice = []string{"php", "java", "nodejs", "golang"}
for i := 0; i < len(strSlice); i++ {
fmt.Println(strSlice[i])
}
//php
java
nodejs
golang
var strSlice = []string{"php", "java", "nodejs", "golang"}
for k, v := range strSlice {
fmt.Println(k, v)
}
//0 php
1 java
2 nodejs
3 golang
基于数组定义切片
a := [5]int{55, 56, 57, 58, 59} //数组
b := a[:] //获取数组里面的所有值
fmt.Printf("%v-%T\n", b, b)
//[55 56 57 58 59]-[]int
a := [5]int{55, 56, 57, 58, 59} //数组
c := a[1:4]
fmt.Printf("%v-%T\n", c, c) //[56 57 58]-[]int
a := [5]int{55, 56, 57, 58, 59} //数组
d := a[2:]
fmt.Printf("%v-%T\n", d, d) //[57, 58, 59]
a := [5]int{55, 56, 57, 58, 59} //数组
e := a[:3] //表示获取第三个下标前面的数据
fmt.Printf("%v-%T\n", e, e) //[55, 56, 57]
基于切片定义切片
a := []string{"北京", "上海", "广州", "深圳", "成都", "重庆"}
b := a[1:]
fmt.Printf("%v-%T\n", b, b) //[上海 广州 深圳 成都 重庆]
切片的长度和容量
长度:切片的长度就是它所包含的元素个数 容量:切片的容量是从它的第一个元素开始数,到其底层数组元素末尾的个数
s := []int{2, 3, 5, 7, 11, 13}
fmt.Printf("长度%d 容量%d\n", len(s), cap(s)) //长度6 容量6
s := []int{2, 3, 5, 7, 11, 13}
a := s[2:] //5, 7, 11, 13
fmt.Printf("长度%d 容量%d\n", len(a), cap(a)) //长度4 容量4
s := []int{2, 3, 5, 7, 11, 13}
b := s[1:3] //3, 5
fmt.Printf("长度%d 容量%d\n", len(b), cap(b)) //长度2 容量5
s := []int{2, 3, 5, 7, 11, 13}
c := s[:3] //2, 3, 5
fmt.Printf("长度%d 容量%d\n", len(c), cap(c)) //长度3 容量6
make()函数创建一个切片
make([]T, size, cap)
var sliceA = make([]int, 4, 8)
fmt.Println(sliceA) //[0 0 0 0]
fmt.Printf("%d--%d", len(sliceA), cap(sliceA)) //4--8
edit编辑切片
var sliceA = make([]int, 4, 8)
fmt.Println(sliceA) //[0 0 0 0]
sliceA[0] = 10
sliceA[1] = 12
sliceA[2] = 40
sliceA[3] = 30
fmt.Println(sliceA) //[10 12 40 30]
sliceB := []string{"php", "java", "go"}
sliceB[2] = "golang"
fmt.Println(sliceB) //[php java golang]
var sliceC []int
fmt.Printf("%v -- %v--%v", sliceC, len(sliceC), cap(sliceC)) //[] -- 0--0
sliceC[0] = 1 //报错
fmt.Println(sliceC)
append 切片动态添加元素
var sliceA []int
sliceA = append(sliceA, 12)
sliceA = append(sliceA, 24)
fmt.Printf("%v - %v--%v", sliceA, len(sliceA), cap(sliceA)) //[12 24] - 2--2
var sliceA []int
sliceA = append(sliceA, 12, 23, 35, 465)
fmt.Printf("%v - %v--%v", sliceA, len(sliceA), cap(sliceA)) //[12 23 35 465] - 4--4
append 合并切片
sliceA := []string{"php", "java"}
sliceB := []string{"nodejs", "go"}
sliceA = append(sliceA, sliceB...)
fmt.Println(sliceA) //[php java nodejs go]
copy
切片就是引用数据类型
sliceA := []int{1, 2, 3, 45}
sliceB := sliceA
sliceB[0] = 11
fmt.Println(sliceA) //[11 2 3 45]
fmt.Println(sliceB) //[11 2 3 45]
sliceA := []int{1, 2, 3, 45}
sliceB := make([]int, 4, 4)
copy(sliceB, sliceA)
fmt.Println(sliceA) //[1 2 3 45]
fmt.Println(sliceB) //[1 2 3 45]
sliceB[0] = 111
fmt.Println(sliceA) //[1 2 3 45]
fmt.Println(sliceB) //[111 2 3 45]
delete
删除32
a := []int{30, 31, 32, 33, 34, 35, 36, 37}
a = append(a[:2], a[3:]...)
fmt.Println(a)
删除35, 36
sliceB := []int{30, 31, 32, 33, 34, 35, 36, 37}
sliceB = append(sliceB[:5], sliceB[7:]...)
fmt.Println(sliceB)
切片是引用类型
s1 := make([]int, 3) //[0 0 0]
s2 := s1 //将 s1 直接赋值给 s2,s1 和 s2
s2[0] = 100
fmt.Println(s1) //[100 0 0]
fmt.Println(s2) //[100 0 0]
指针
变量的内存地址
var a int = 10
fmt.Printf("a的值:%v a的类型%T a的地址%p", a, a, &a) //a的值:10 a的类型int a的地址0xc0000100a8
指针变量
每一个变量都有自己的内存地址
var a = 10
var p = &a //p指针变量 p的类型 *int(指针类型)
fmt.Printf("a的值:%v a的类型%T a的地址%p\n", a, a, &a)
//a的值:10 a的类型int a的地址0xc000014090
fmt.Printf("p的值:%v p的类型%T p的地址%p", p, p, &p)
//p的值:0xc000014090 p的类型*int p的地址0xc000006028
指针获取变量
a := 10
p := &a //p指针变量 类型 *int
fmt.Println(p) //a的地址 0xc0000100a8
fmt.Println(*p) //*p 表示打印a对应的值 10
*p = 30 //改变p这个变量对应的内存地址的值
fmt.Println(a) //30
函数传指针参,改变变量的值
func fn1(x int) {
x = 10
}
func fn2(x *int) {
*x = 40
}
func main() {
var a = 5
fn1(a)
fmt.Println(a) //5
fn2(&a)
fmt.Println(a) //40
}
make分配内存
map
var userinfo map[string]string
userinfo["username"] = "张三"
fmt.Println(userinfo) //报错
var userinfo = make(map[string]string)
userinfo["username"] = "张三"
fmt.Println(userinfo)
切片
var a []int
a[0] = 1
fmt.Println(a) //报错
var a = make([]int, 4, 4)
a[0] = 1
fmt.Println(a)
指针也是引用数据类型
map
定义
var userinfo = make(map[string]string)
userinfo["username"] = "张三"
userinfo["age"] = "20"
userinfo["sex"] = "男"
fmt.Println(userinfo)
fmt.Println(userinfo["username"])
var userinfo = map[string]string{
"username": "张三",
"age": "20",
"sex": "男",
}
fmt.Println(userinfo)
userinfo := map[string]string{
"username": "张三",
"age": "20",
"sex": "男",
}
fmt.Println(userinfo)
遍历
userinfo := map[string]string{
"username": "张三",
"age": "20",
"sex": "男",
}
for k, v := range userinfo {
fmt.Printf("key:%v value:%v\n", k, v)
}
//key:username value:张三
key:age value:20
key:sex value:男
修改
var userinfo = map[string]string{
"username": "张三",
"age": "20",
}
userinfo["username"] = "李四"
fmt.Println(userinfo)
获取 查找
var userinfo = map[string]string{
"username": "张三",
"age": "20",
}
fmt.Println(userinfo["username"]) //获取
v, ok := userinfo["age"]
fmt.Println(v, ok) //20 true
v, ok := userinfo["xxxxx"]
fmt.Println(v, ok) // 空 和 false
删除
var userinfo = map[string]string{
"username": "张三",
"age": "20",
"sex": "男",
"height": "180cm",
}
fmt.Println(userinfo) //map[age:20 height:180cm sex:男 username:张三]
delete(userinfo, "sex")
fmt.Println(userinfo) //map[age:20 height:180cm username:张三]
map类型的切片
var userinfo = make(map[string][]string)
userinfo["hobby"] = []string{
"吃饭",
"睡觉",
"敲代码",
}
userinfo["work"] = []string{
"php",
"golang",
"前端",
}
for _, v := range userinfo {
// fmt.Println(k, v)
for _, value := range v {
fmt.Println(value)
}
}
吃饭
睡觉
敲代码
php
golang
前端
map是引用类型
var userinfo1 = make(map[string]string)
userinfo1["username"] = "张三"
userinfo1["age"] = "20"
userinfo2 := userinfo1
userinfo2["username"] = "李四"
fmt.Println(userinfo1)
fmt.Println(userinfo2)
map升序
map1 := make(map[int]int, 10)
map1[10] = 100
map1[1] = 13
map1[4] = 56
map1[8] = 90
map1[11] = 100
map1[2] = 13
var keySlice []int
for key, _ := range map1 {
keySlice = append(keySlice, key)
}
fmt.Println(keySlice) //[11 10 4 8 2 1]
// // 让key进行升序排序
sort.Ints(keySlice)
fmt.Println(keySlice) //[1 2 4 8 10 11]
map统计字符次数
var str = "how do you do"
var strSlice = strings.Split(str, " ")
fmt.Println(strSlice)
var strMap = make(map[string]int)
for _, v := range strSlice {
strMap[v]++
}
fmt.Println(strMap) //map[do:2 how:1 you:1]