Golang第二章:Printf参数、变量、标识符、运算符
开发中注意点
Golang程序中整形变量使用时,遵守保小不保大原则,因此应尽量使用空间小的变量
Printf参数
变量使用的三种方式
1. 指定变量类型,声明后若不赋值,使用默认值
2. 根据值自行判断变量类型(类型推导)
3. 省略var,注意 := 左侧的变量不应该是已经声明过的,否则会导致编译错误
package main import "fmt" // 1.定义全局变量方式1 var G1 = 100 var G2 = "TEST" var G3 = 5.55 // 2.定义全局变量方式2 var ( G4 = 300 G5 = "AS" G6 = 7.5 ) func main() { // 1.指定变量类型,声明后若不赋值,int使用默认值0,String使用空串 var i int // 2.根据值自行判断变量类型(类型推导) var num1 = 5.11 // 3.省略var,注意 := 左侧的变量不应该是已经声明过的,否则会导致编译错误 num2 := 6 // 1.一次性声明多个变量 var n1, n2, n3 int // 2. 一次性声明多个变量方式2 var n4, n5, n6 = 100, "tom", 5.11 // 3. 一次性声明多个变量方式3 n7, n8, n9 := 4, "bobo", 5.55 }
变量的数据类型
值类型与引用类型
值类型:变量直接存储值,内存通常在栈中分配
引用类型:变量存储的是地址,内存通常在堆上分配,当没有任何变量引用这个地址时,将会被GC回收
基本数据类型默认值
基本数据转换
1. Go在不同类型变量之间不能自由转换,必须使用显式转换
2. 数据类型转换可以从范围小->范围大,也可以从范围大->范围小,编译不会报错
3. 范围大到范围小时,转换的结果会按溢出处理
package main import "fmt" import "strconv" func main() { // 同类型转换 var i int32 = 1002222222 var n1 float32 = float32(i) var n2 int8 = int8(i) var n3 int64 = int64(i) // 低精度转高精度 fmt.Printf("i=%v n1=%v n2=%v n3=%v\n", i, n1, n2, n3) // 其它类型转string var num1 int = 99 var num2 float64 = 23.456 var b bool = true var myChar byte = 'h' var str1 string var str2 string var str3 string var str4 string str1 = fmt.Sprintf("%d", num1) fmt.Printf("str type %T %q\n", str1, str1) str2 = fmt.Sprintf("%f", num2) fmt.Printf("str type %T %q\n", str2, str2) str3 = fmt.Sprintf("%t", b) fmt.Printf("str type %T %q\n", str3, str3) str4 = fmt.Sprintf("%c", myChar) fmt.Printf("str type %T %q\n", str4, str4) // 其它类型转string var num3 int = 99 var num4 float64 = 23.456 var num5 int = 87 var b2 bool = false var str5 string var str6 string var str7 string var str8 string str5 = strconv.FormatInt(int64(num3), 10) fmt.Printf("str5 %T %q\n", str5, str5) str8 = strconv.Itoa(int(num5)) fmt.Printf("str8 %T %q\n", str8, str8) // 'f':通常格式,10表示小数保留10位,64表示这个小数是float64 str6 = strconv.FormatFloat(num4, 'f', 10, 64) fmt.Printf("str6 %T %q\n", str6, str6) str7 = strconv.FormatBool(b2) fmt.Printf("str7 %T %q\n", str7, str7) // string转其它类型 var str9 string = "true" var b3 bool // strconv.ParseBool(str)返回两个值(value Bool, err error), 因为不想要第二个值,所以用_忽略 b3, _ = strconv.ParseBool(str9) fmt.Printf("b3 %T %v\n", b3, b3) var str10 string = "12351" var num6 int64 var num7 int32 num6, _ = strconv.ParseInt(str10, 10, 64) num7 = int32(num6) fmt.Printf("num6 %T %v\nnum7 %T %v\n", num6, num6, num7, num7) var str11 string = "12351.23" var num8 float64 num8, _ = strconv.ParseFloat(str11, 64) fmt.Printf("num8 %T %v\n", num8, num8) }
查看变量的占用字节大小和数据类型
package main import "fmt" import "unsafe" func main() { // 查看变量的占用字节大小和数据类型 var n2 int64 = 100 fmt.Printf("n2类型为%T 占用的字节为 %d", n2, unsafe.Sizeof(n2)) }
整数类型
浮点类型
字符类型
在Go中,字符的本质是一个整数(因此可以参与运算),直接输出时,是该字符对应的UTF-8编码的码值
package main import "fmt" func main() { var c1 byte = 'a' var c2 byte = '0' var c3 int = '呗' fmt.Println("c1=", c1, " c2=", c2) fmt.Printf("c1=%c,c2=%c\n", c1, c2) fmt.Printf("c3=%d, c3=%c", c3, c3) }
存取流程
存:字符->UTF-8码值->二进制->存储
取:二进制->UTF-8码值->字符->读取
字符串类型
Go的字符串组成不同,是由字节组成的。
package main import "fmt" func main() { // 字符串拼接需要将+号放上一行 var address string = "北京长城\n110" + "hehehe" + " ddd" fmt.Println(address) // 当要输出一堆内容时,可用`` var str string = ` package main import "fmt" func main() { var address string = "北京长城\n110" fmt.Println(address) ` fmt.Println(str) }
string是不可变的,也就是说不能通过str[0] = 'z'方式来修改字符串;如果需要修改字符串,可以先将string -> []byte 或者 [] rune -> 修改 -> 重写转成string
str := "hello@atguigu" // 使用切片获取到 atguigu slice := str[6:] fmt.Println("slice=", slice) // 修改string // 我们转成[]byte后,可以处理英文和数字,但是不能处理中文,原因是[] byte按字节处理 // arr1 := []byte(str) // 若遇中文,需将string转成[]rune,因为[]rune是按字符处理处理 arr1 := []rune(str) arr1[0] = '中' str = string(arr1) fmt.Println("str=", str)
字符串数组拼接优化
+= 连接原字符串、空格和下个参数, 产生新字符串, 并把它赋值给 s 。 s 原来的内容已经不再使用,将在适当时机对它进行垃圾回收。
如果连接涉及的数据量很大,这种方式代价高昂。一种简单且高效的解决方案是使 用 strings 包的 Join 函数。
import ( "fmt" "strings" ) func main() { // 繁琐方法 str := [5]string{"aaa", "bbb", "ccc", "ddd", "eee"} s, sep := "", " " for _, val := range str { s += val + sep sep = " " } fmt.Println(s) // 优化方法 sep2 := " " fmt.Println(strings.Join(str[0:], sep2)) }
布尔类型
指针类型
标识符
标识符命名注意事项
运算符
++和--只能独立使用,不能赋值,且只有如i++、i--,没有++i,--i
算术运算符-除法
package main import ( "fmt" ) func main() { var n1 float32 = 10 / 4 var n2 float32 = 10.0 / 4 fmt.Println(n1) // 2 fmt.Println(n2) // 2.5 }