文章目录
变量
-
什么是变量
变量都是其程序的基本组成单位,可以把变量比喻成房牌号,通过门牌号就能找到房间。
-
变量的定义
- 声明变量或定义变量
- 变量赋值
- 变量使用
- 案例
package main import "fmt" func main() { //定义变量 var i int //赋值变量 i = 10 //使用变量 fmt.Println("i =", i) }
-
变量的声明
-
指定变量类型,声明后若不复制,使用默认值,如int的默认值是0,其他数据类型都是零值;
var i int fmt.Println("i =", i)
-
根据值自行判定变量类型(类型推导);
var num = 3.1415926 fmt.Println("num =", num)
-
省略var,=是赋值, :=是声明变量并赋值。注意 :=左侧变量不应该是已经声明过的,否则会编译错误
name := "alan" fmt.Println("name =", name) 等价于 var name string name = "alan"
多变量声明
var n1, n2, n3 int var n1, name, n3 = 1 “tom”, 1.0 n1, name, n3 := 1, “tom”, 1.0
全局变量的声明 - - - 简单理解为函数外定义声明
- 在Go中函数外部定义的变量就是全局变量
var name = "alan" var age = 18 func main(){ pass }
- 一次性声明
var ( name = "alan" age = 18 )
-
-
注意事项
-
变量在某个区域的数据值可以在同一类型范围内不断变化,但不能改变数据类型(强类型转换)
-
变量在同一作用域(在一个函数或代码块)内不能重名
-
Golang的变量如果没有赋初值, 编译器会使用默认值,比如int为0,string为空字符串等
-
变量三要素:变量名、值、数据类型,三者缺一不可。
-
基本数据类型
数值型(整型、浮点型)、字符型(单个字符)、布尔型、字符串(Go中归属为基本数据类型)、复数类型(complex64、complex128)、rune(int32别名,存中文字符串)
-
整数类型
整数类型就是用于存放整数值,一个字节为8位(bit),计算机采用二进制(0或1),即2^8表数范围。对于有符号:下图bit7为符号位,表示±,在整数里把±0归属于-,即-128~127
类型 有无符号 占用存储空间 表数范围 int8 有 1字节 −128∼127 int16 有 2字节 -215∼215-1 int32 有 4字节 -231∼231-1 int64 有 8字节 -263∼263-1 uint8 无 1字节 0∼255 uint16 无 2字节 0∼216-1 uint32 无 4字节 0∼232-1 uint64 无 8字节 0∼264-1 int 有 32位系统4个字节
64位系统8个字节-231∼231-1
-263∼263-1uint 无 32位系统4个字节
64位系统8个字节0∼232-1
0~264-1rune 有 与int32等价,表示一个unicode码,常用处理中文 -231∼231-1 byte 无 与uint8等价,存储字符选用 0∼255 注意事项
- Golang各证书类型分为有符号和无符号,int、uint的大小和系统有关
- Golang的整型默认声明为int型
- 查看某个变量的字节大小
unsafe.Sizeof(n1)
和数据类型fmt.Printf->%T
package main import ( //批量引入包 "fmt" "unsafe" ) func main() { //定义变量 var n int64 = 12 fmt.Printf("n的字符类型为%T,字节数为%d", n, unsafe.Sizeof(n)) }
- Golang程序中整型变量使用时,遵守保小不保大的原则,即:在保证程序正确运行下,尽量使用占用空间小的数据类型,比如年龄
uint8、byte
就行了 - bit是计算机中最小存储单位,byte是计算机中基本存储单元(1 byte=8 bit)
-
浮点型
浮点型用于存放小数,比如3.14、-1.9等,两种类型如下(没有double类型)。浮点数都是有符号的,浮点数的尾数部分可能丢失,造成精度损失。
- 浮点数=符号位+指数位+尾数位
- 单精度float32:4字节
- 双精度float64:8字节
注意事项
- float64的精度要比float32准确,如果我们要保存一个高精度数据,则应该选用float64;软件开发中也推荐使用float64,Golang的浮点型默认声明为float64类型
- Golang浮点类型有固定的范围和字段长度,不受具体操作系统的影响
package main import ( "fmt" "unsafe" ) func main() { //默认为float64 var num = 12.1 num2 := .123 fmt.Printf("num的字符类型为%T,字节数为%d\n", num, unsafe.Sizeof(num)) fmt.Printf("num2的字符类型为%T,字节数为%d\n", num2, unsafe.Sizeof(num2)) //科学计数法 num3 := 5.1234e2 // ? 5.1234 * 10^2 fmt.Println("num3=", num3) num4 := 5.1234e-2 // ? 5.1234 * 10^2 fmt.Println("num4=", num4) /* num的字符类型为float64,字节数为8 num2的字符类型为float64,字节数为8 num3= 512.34 num4= 0.051234 */ }
-
单个字符类型
字符串是一串固定长度的字符连接起来的字符序列。Go的字符串是由单个字节连接起来的,也就是说传统的字符串是由字符组成的,而Go的字符串不同,它是由字节组成的。
Golang中没有专门的字符类型,如果要存储单个字符(字母),一般使用 byte 来保存(ASCII码表)。注意,是单个字母,而汉字是3个字节。
package main import "fmt" func main() { //定义字符类型 var c1 byte = 's' var c2 byte = '0' //当我们直接输出byte值 即输出对应字符的ASCII码值 fmt.Println("c1 =", c1) fmt.Println("c2 =", c2) //如果需要输出对应字符 需要使用格式化输出 fmt.Printf("c1=%c c2=%c\n", c1, c1) //var c3 byte = '李' //一个汉字,三个字节,byte才一个字节,overflow溢出 var c3 int = '李' fmt.Printf("c3=%c c3对应码值=%d\n", c3, c3) }
注意事项
- 字符常量是用单引号(')括起来的单个字符,例如var c1 byte=‘a’,var c2 int=‘中’
- Go中允许使用转义字符 '来讲其后的字符转变为特殊字符型常量,比如var c3 char = ‘\n’,表示换行符
- Go语言的字符使用UTF-8编码,英文字母1个字节,汉字3个字节。如果想查询字对应的utf8编码,使用网址:查看字符编码(UTF-8)
- 在Go中,字符的本质是一个整数,直接输出时,是该符对应的UTF-8编码的码字
- 可以直接给某个变量赋一个数字,然后按格式化输出%c,会输出该数字对应的unicode字符
fmt.Printf("%c", 97) //a
- 字符类型可以进行运算,相当于一个整数,因为它都对应有Unicode编码
var n1 = 10 + 'a' // ? 10 + 97
字符类型本质探讨
- 字符型存储到计算机中,需要将字符对应的码值(整数)找出来
- 存储:字符 -> 对应码值 -> 二进制 -> 存储
- 读取:二进制 -> 码值 -> 字符 -> 读取
- 字符和码值的对应关系是通过字符编码表决定的,事先规定好的
- Go语言的编码都统一成utf-8,从而解决各种乱码问题
-
字符串类型
字符串是一串固定长度的字符连接起来的字符序列。Go字符串是由单个字节连接起来的。Go语言的字符串的字节使用UTF-8编码标识Unicode文本。
package main import "fmt" func main() { //定义字符串类型 var name = "我的名字叫Alan!" fmt.Printf("name=%s, 类型=%T", name, name) }
注意事项
- Go语言字符串的字符使用UTF-8编码标识Unicode文本,这样Golang统一使用UTF-8编码,中文乱码问题不在困扰我们。编码问题一直是C语言、Java、Python2常见问题
- 字符串一旦被赋值,字符串就不能修改,即Go中字符串是不可变的(原子性)
字符串两种表示形式
- 双引号:会识别转义字符
- 反引号:以字符串的原生形式输出,包括换行和特殊字符,可以实现防止攻击、输出源代码等效果
package main import "fmt" func main() { //双引号字符串 str1 := "Alan\nCSDN" fmt.Println(str1) //反引号字符串 `` str2 := ` package main import "fmt" func main() { //定义字符串类型 var name string = "我的名字叫Alan!" fmt.Println(name) } ` fmt.Println(str2) }
字符串拼接
- var str = “hello” + “world”
- str += “AlanLee”
-
布尔类型
布尔(bool)类型数据只允许取值true和false,用于表示真和假。它仅占1个字节,常用于逻辑运算。Go语言中bool类型不可以使用None、0、“”、{}、[]替代false,这和Python不同。
package main import "fmt" import "unsafe" func main() { //定义数据类型 var num = false fmt.Println("num =", num) //注意bool类型占用1个字节 只能取true或false fmt.Println("占用空间 =", unsafe.Sizeof(num)) }
-
数字类型之间转换
Golang和Java、C不同,Go在不同类型的变量之间赋值时需要显示转换。换句话说,Golang中数据类型不能自动转换。
- 强制转换基本语法
- T:数据类型,比如int32、int64、float64等
- v:需要转换的变量
package main import "fmt" func main() { //数据类型转换 var a int32 = 100 //整型->浮点型 //var b float32 = float32(a) var b = float32(a) var c int8 = int8(a) //低精度->高精度 var d int64 = int64(a) fmt.Printf("a=%v b=%v c=%v d=%v\n", a, b, c, d) fmt.Printf("a=%T b=%T c=%T d=%T\n", a, b, c, d) //浮点型->整型 var e float32 = 3.14 var f int32 = int32(e) fmt.Printf("e=%v f=%v\n", e, f) fmt.Printf("e=%T f=%T\n", e, f) }
注意事项
- 被转换的是变量存储的数据(即值),变量本身的数据类型并没有变化
- Go中数据类型的转换可以从表示范围小到表示范围大,也可以从范围大到范围小
- 在转换中,比如将 int64 转换成 int8(-128到127),编译时不会报错,只是转换的结果按溢出处理,和期待的结果不一样。因此在转换时,需要考虑范围。
- 数据类型不一致的运算错误,建议转换成相同的数据类型。
- 强制转换基本语法
-
数字类型和string转换
-
基本数据类型转换成string
- 方法1:fmt.Sprintf(“%参数”, 表达式)
package main import "fmt" func main() { //变量定义 var num1 int = 99 var num2 float64 = 3.14 var b bool = true var char byte = 'h' var str string //fmt.Sprintf转换 str = fmt.Sprintf("%d", num1) fmt.Printf("str type %T str=%q\n", str, str) str = fmt.Sprintf("%f", num2) fmt.Printf("str type %T str=%q\n", str, str) str = fmt.Sprintf("%t", b) fmt.Printf("str type %T str=%q\n", str, str) str = fmt.Sprintf("%c", char) fmt.Printf("str type %T str=%q\n", str, str) }
- 方法2:使用strconv包的函数,还有个Itoa函数
package main import "fmt" import "strconv" func main() { //变量定义 var num1 int = 99 var num2 float64 = 3.14 var b bool = true var num3 int64 = 4567 var str string //strconv.FormatInt 10进制 str = strconv.FormatInt(int64(num1), 10) fmt.Printf("str type %T str=%q\n", str, str) //strconv.FormatFloat(num2, 'f', 10, 64) //说明:'f'格式 10表示小数位保留10位 64表示小数float64 str = strconv.FormatFloat(num2, 'f', 10, 64) fmt.Printf("str type %T str=%q\n", str, str) str = strconv.FormatBool(b) fmt.Printf("str type %T str=%q\n", str, str) str = strconv.Itoa(int(num3)) fmt.Printf("str type %T str=%q\n", str, str) }
- 方法1:fmt.Sprintf(“%参数”, 表达式)
-
string类型转基本数据类型
使用strconv包的函数:FormatBool、
package main import "fmt" import "strconv" func main() { //变量定义 s1 := "true" s2 := "1" s3 := "0" s4 := "2" fmt.Println(strconv.ParseBool(s1)) //true <nil> fmt.Println(strconv.ParseBool(s2)) //true <nil> fmt.Println(strconv.ParseBool(s3)) //false <nil> fmt.Println(strconv.ParseBool(s4)) //false strconv.ParseBool: parsing "2": invalid syntax s5 := "-123" s6 := "0" s7 := "123.1" s8 := "abc" fmt.Println(strconv.ParseInt(s5, 10, 64)) //-123 <nil> fmt.Println(strconv.ParseInt(s5, 8, 64)) //-83 <nil> ps: -(1 * 8^2 + 2 * 8 + 3 * 1) fmt.Println(strconv.ParseInt(s6, 10, 64)) //0 <nil> fmt.Println(strconv.ParseInt(s7, 10, 64)) //0 strconv.ParseInt: parsing "123.1": invalid syntax fmt.Println(strconv.ParseInt(s8, 10, 64)) //0 strconv.ParseInt: parsing "abc": invalid syntax s9 := "12.1233" s10 := "12" s11 := "abc" fmt.Println(strconv.ParseFloat(s9, 64)) //-83 <nil> fmt.Println(strconv.ParseFloat(s10, 64)) //12 <nil> fmt.Println(strconv.ParseFloat(s11, 64)) //0 strconv.ParseFloat: parsing "abc": invalid syntax }
注意
- 在将String类型转换成基本数据类型时,要确保String类型能够转成有效的数据。比如把“123”转成一个整数,但不能把“hello”转成一个整数;如果这样Go直接将其转成0,其他类型也是同样的道理,float转成0、bool转成false。
-