更新系列
Go语言头秃之路(一)
Go语言头秃之路(二)
Go语言头秃之路(三)
Go语言头秃之路(四)
Go语言头秃之路(五)
Go语言头秃之路(六)
Go语言头秃之路(七)
先导
-
指针
指针变量只能接收地址值,不能接收其他的值类型(包括int/float/bool/string/数组/结构体)
赋值的变量类型必须和指针类型相同,指针类型形式为 *数据类型(如 *int/*float32)
指针类型的数据在赋值之前,需要使用new()创建内存空间。否则赋值会报错,因为此时是nil
(Python中None是全局唯一的,所有None值变量都指向同一内存空间;而go语言的nil值变量指向的内存空间不同)var p *int fmt.Println(p) // nil *p = 2 // 这里会报错 p = new(int) *p = 3 // 无误
new函数返回的是地址值,make函数返回的是对应数据类型(如map)的实例。
-
标识符
_
为空标识符,用于占位。
标识符命名规则:- 包名和文件夹名保持一致
- 变量名、函数名、常量名采用驼峰法
- 首字母大写可以被其他包访问(公有),首字母小写只能在本包使用(私有)
-
数据类型转换 strconv
strconv.Atoi() 字符串转int,有两个返回值
strconv.Itoa() int转字符串Parse类函数用于转换字符串为给定类型的值:ParseBool()、ParseFloat()、ParseInt()、ParseUint()
注意:下面函数的返回值都是64位(即使指定32位也照样返回64位)b, err := strconv.ParseBool("true") f, err := strconv.ParseFloat("3.1415", 64) i, err := strconv.ParseInt("-42", 10, 64) u, err := strconv.ParseUint("42", 10, 64)
将给定类型格式化为string类型:FormatBool()、FormatFloat()、FormatInt()、FormatUint()
s := strconv.FormatBool(true) s := strconv.FormatFloat(3.1415, 'E', -1, 64) s := strconv.FormatInt(-42, 16) //表示将-42转换为16进制数,转换的结果为-2a。 s := strconv.FormatUint(42, 16)
字符串操作:
strings.Contains(msg, “a”) :判断msg中是否包含a
strings.Count(msg, “a”) :统计msg中a出现的次数
strings.HasPrefix(msg, “a”) :判断msg是否以a开头
strings.HasSuffix(msg, “a”) :判断msg是否以a结尾
strings.ToUpper(msg):所有字母大写
strings.ToLower(msg):所有字母小写
strings.Compare(str1, str2):比较的是ASCII码值,如果前值大于后值返回1,小于返回-1,等于返回0
strings.TrimLeft(msg, “h”):从左将匹配的字符串去掉
strings.TrimRight:从右将匹配的字符串去掉
strings.Trim:左右两边同时将匹配的字符串去掉
strings.Split(msg, " "): 以空格切分字符串,返回数组
strings.Join(strArr, “+”):字符串拼接
strings.Replace(msg, old_str, new_str, n):字符串替换,最后参数n为替换次数(从左到右)
- 数组
- 数组定义中括号内必须指定数组长度,不写长度时定义的是
切片
- 数组只能查改,不能增删
- 在函数中使用数组作为参数传递的方式是值传递
// 给数组第1个数赋值为100,其余使用零值
testArr := [5]int{1:100}
// 不指定数组长度使用...
testArr2 := [...]int{1:100}
// 数组查改
testArr[1] = 101
fmt.Println(testArr[0])
go语言的切片是指向源数据的,因此一方改变会影响另一方。
- map
相当于python中的dictm := make(map[string]string) // 增/改 m["name"] = "fone" // 删,key不存在时不报错 delete(m, "age") // 遍历 for k, v := range m { fmt.Println(k, v) } // 查 name, ok := m["myname"] if ok { fmt.Println("ok") fmt.Println(name) } else { fmt.Println("no") }
- 算数运算符
- 如果运算的数都是整数,那么运算结果会去掉小数部分,只保留整数部分
饭粒:10/4=2 - 如果需要保留小数部分,则需要用浮点数参与运算(为了防止精度缺失一般都需要把被除数加上小数点.0)
饭粒:10.0/4=2.5 - 取模运算公式:a%b = a-a/bb
饭粒:-10%-3=-10-(-10)/(-3)(-3) - ++ 和 – 只能独立使用,不能放在任何语句中,并且只能放在变量后面
如a=i++或–i会报错 - 关系运算(单一条件)和逻辑运算(多条件与或非)结果都是bool,要么是true,要么是false
短路原则:逻辑与中第一个条件false则不判断第二个条件结果置为false;逻辑或中第一个条件为true则第二个条件不判断结果置为true - 赋值运算符
二进制相关赋值运算:
经典两值交换最简单方法:a,b=b,a - 位运算
号外:
二进制数前缀是0b;八进制数前缀是0;十六进制前缀是0x
二进制转八进制:将二进制数中从右到左每3位一组转成十进制后拼起来就是对应的八进制;
二进制转十六进制:将二进制数中从右到左每4位一组转成十进制后拼起来就是对应的十六进制;(反向转同理)
对于有符号数:
1. 二进制的最高位是符号位:0表示正数、1表示负数
2. 正数的原码反码补码都一样(饭粒1的各种码:00000001)
3. 负数的反码=原码符号位不变,其他位取反(0->1,1->0)
负数的补码=反码+1
饭粒-1原码:10000001,反码:11111110,补码11111111
4. 0的反码和补码都是0
5.在计算机运算的时候,都是以补码的方式来运算
正文:
先将所有数转化为二进制数
按位与&:两位都是1结果为1,否则为0
按位或|:两位都是0结果为0,否则为1
按位异或^:两位不相等结果为1, 否则为0
饭粒:带负数的位运算(先将负数转换为补码和正数补码位运算,结果是补码,再转换为源码才是真正结果)
右移运算符>>:低位溢出,符号位不变,并用符号位补
溢出的高位
左移运算符<<:符号位不变,低位补0var a int = 1 >> 2 var b int = -1 >> 2 var c int = 1 << 2 var d int = -1 << 2 // 结果依次为0 -1 4 -4
- 其他
- 引用类型:指针、slice切片、map、管道channel、interface等,存储的是地址,通常在堆区分配空间,没有变量引用时由GC回收。
值类型包括int/float/bool/string/数组/结构体,数据直接存储值,通常在栈区分配空间。 - 系统保留关键字,不能用于自定义标识符(25个)
预定义标识符(36个)