Go变量与类型简明指南
变量
var 关键字进行声明变量
一个变量的声明
声明一个变量,并指定类型,不立即赋值。
变量会被自动初始化为其类型的 “零值” (例如,数值为 0
,字符串为 ""
,布尔值为 false
,指针为 nil
)。
这个go语言进行声明后直接回进行转化成“零值”还是非常灵性的,避免的C/C++ 基本数据类型定义出来不进行赋值时随机值的情况。
package main
import "fmt"//一个变量的声明定义
func test1(){fmt.Println("声明赋值分开进行")//var 进行声明变量 var count int//变量的赋值count=18//变量的数用fmt.Println("count=",count)fmt.Println("-----------------------------")fmt.Println("声明赋值放到一起")//声明+赋值var num int = 19//变量的数用fmt.Println("num=",num)fmt.Println("-----------------------------")
}func main(){test1()
}
多个变量的声明
package main
import "fmt"//一个变量的声明定义
func test1(){fmt.Println("声明赋值分开进行")//var 进行声明变量 var count int//变量的赋值count=18//变量的数用fmt.Println("count=",count)fmt.Println("-----------------------------")fmt.Println("声明赋值放到一起")//声明+赋值var num int = 19//变量的数用fmt.Println("num=",num)fmt.Println("-----------------------------")
}//多个变量的声明定义
func test2(){var (count int = 30num int = 31)fmt.Println("count=",count)fmt.Println("num=",num)fmt.Println("-----------------------------")
}
func main(){test1()test2()
}
var支持的类型推断
var是可以进行类型推断的,也就是说在定义变量的时候如果使用的是var关键字,是不用进行声明类型的,var是很聪明的,即使我们不写他也能根据后面的赋值来进行推断。
这就很像C++中的auto ,但是auto还是没有var智能,因为auto只能一次声明定义推断一种变量类型。
//var支持的类型判断
func test3(){var (count = 30num = 31name = "xiao ying")fmt.Println("count=",count)fmt.Println("num=",num)fmt.Println("name=",name)fmt.Println("-----------------------------")
}
使用:=短变量声明操作符
这是 Go 语言中非常常用且 idiomatic (符合语言习惯) 的一种方式。它只能在函数内部使用。
:=
操作符会做两件事:
- 声明一个新的变量。
- 初始化这个变量。
它会自动进行类型推断,所以你不需要写类型。
还有一个非常重要的点
:=
的一个重要特点:
在一个 :=
声明中,左侧至少要有一个是新声明的变量,才可以使用 :=
。
package mainimport "fmt"// 注意::= 不能用在函数外部
// a := 10 // 这行会编译错误func main() {// 等同于 var name string = "ys"name := "ys"// 等同于 var age int = 30age := 30// 等同于 var isStudent bool = trueisStudent := truefmt.Printf("Name: %s, Age: %d, IsStudent: %v\n", name, age, isStudent)// 输出: Name: ys, Age: 30, IsStudent: true// 也可以同时声明和初始化多个变量// err 是一个新变量,conn 不是(假设之前已声明),这时可以用 :=conn, err := connectToDB() // 这是一个非常常见的用法
}
数据类型
基本数据类
整数类型
整数类型故名思意就是用于存放整数值的,整数类型又分为 有符号整数、无符号整数以及其他整数类型
有符号整数类型
类型 | 有无符号 | 占用存储空间 | 表数范围 |
---|---|---|---|
int8 | 有 | 1字节 | -2⁷ ~ 2⁷-1 (-128 ~ 127) |
int16 | 有 | 2字节 | -2¹⁵ ~ 2¹⁵-1 (-32768 ~ 32767) |
int32 | 有 | 4字节 | -2³¹ ~ 2³¹-1 (-2147483648 ~ 2147483647) |
int64 | 有 | 8字节 | -2⁶³ ~ 2⁶³-1 |
无符号整数类型
类型 | 有无符号 | 占用存储空间 | 表数范围 |
---|---|---|---|
uint8 | 无 | 1字节 | 0 ~ 255 |
uint16 | 无 | 2字节 | 0 ~ 2¹⁶-1 |
uint32 | 无 | 4字节 | 0 ~ 2³¹-1* |
uint64 | 无 | 8字节 | 0 ~ 2⁶³-1* |
其他整数类型
类型 | 有无符号 | 占用存储空间 | 表数范围 |
---|---|---|---|
int | 有 | 32位系统-4字节 | -2³¹ ~ 2³¹-1 |
uint | 无 | 32位系统-4字节 | 0 ~ 2³²-1 |
rune | 有 | 等价int32 | -2³¹ ~ 2³¹-1 |
byte | 无 | 等价uint8 | 0 ~ 255 |
上面这么多整型,在实际的开发中我们应该如何进行选择呢?
golang中的思想是保小不保大,在程序运行的过程中尽量使用小的数据类型。
浮点类型
浮点数的组成是 符号位+指数位+尾数位
类型 | 存储空间 | 总位数 | 指数位数 | 尾数位数 | 最大指数(约) |
---|---|---|---|---|---|
float32 | 4字节 | 32 | 8 | 23 | 2¹²⁷ |
float64 | 8字节 | 64 | 11 | 52 | 2¹⁰²³ |
注意:
①存储空间是由底层内存决定的不是由操作系统决定的
②尾数只是一个大概,容易出现精度损失
字符类型
特别说明:
- golang 中是不存在专门的字符类型的,而是通过ASCII值来进行代表对应的字符的,golang中是使用UTF8编码。
- 但是通常使用 byte 来进行存储字符,因为byte类型代表的范围是0~255,实际ASCII表中的字符只有0~127 完全可以进行覆盖。
package main
import "fmt"func main(){var c1 byte = 'a'fmt.Println(c1)var c2 byte = '}'fmt.Println(c2)fmt.Println(c1+20)var c3 byte = 'a'fmt.Printf("c4对应的字符为:%c",c3)//var c4 byte = '中'//fmt.Println(c4)}
通过上面的现象我们可以验证我们的结论,字符的本质就是ASCII值
如果将注释掉的代码进行放开,则会出现报错
汉字字符,底层对应的是Unicode码值
对应的码值为20013,byte类型溢出,能存储的范围:可以用int
总结:Golang的字符对应的使用的是UTF-8编码(Unicode是对应的字符集,UTF-8是Unicode的其中的一种编码方案)
转义字符
转义符 | 含义 | Unicode值 |
---|---|---|
| 退格 (backspace) |
|
| 换行 |
|
| 回车 |
|
| 制表符 (tab) |
|
| 双引号 |
|
| 单引号 |
|
| 反斜杠 |
|
布尔类型
布尔类型也叫bool类型,bool类型数据只允许取值true和false
布尔类型占1个字节。
字符串类型
package main
import "fmt"
func main(){//1.定义一个字符串:var s1 string = "你好全面拥抱Golang"fmt.Println(s1)//2.字符串是不可变的:指的是字符串一旦定义好,其中的字符的值不能改变var s2 string = "abc"//s2 = "def"//s2[0] = 't'fmt.Println(s2)//3.字符串的表示形式://(1)如果字符串中没有特殊字符,字符串的表示形式用双引号//var s3 string = "asdfasdfasdf"//(2)如果字符串中有特殊字符,字符串的表示形式用反引号 ``var s4 string = `package mainimport "fmt"func main(){//测试布尔类型的数值:var flag01 bool = truefmt.Println(flag01)var flag02 bool = falsefmt.Println(flag02)var flag03 bool = 5 < 9fmt.Println(flag03)}`fmt.Println(s4)//4.字符串的拼接效果:var s5 string = "abc" + "def"s5 += "hijk"fmt.Println(s5)//当一个字符串过长的时候:注意:+保留在上一行的最后var s6 string = "abc" + "def" + "abc" + "def" + "abc" + "def" + "abc" +"def"+ "abc" + "def" + "abc" + "def"+ "abc" + "def" + "abc" + "def"+"abc" + "def" + "abc" + "def"+ "abc" + "def" + "abc" + "def"+ "abc" +"def" + "abc" + "def"+ "abc" + "def" + "abc" + "def"+ "abc" + "def" + "abc" + "def"+ "abc" + "def"fmt.Println(s6)
}
复杂数据类型
指针
学习指针必须首先进行了解一下内存
指针中存放的就是变量的地址,指向对应的变量
package main
import("fmt"
)
func main(){var age int = 18//&符号+变量 就可以获取这个变量内存的地址fmt.Println(&age) //0xc0000a2058//定义一个指针变量://var代表要声明一个变量//ptr 指针变量的名字//ptr对应的类型是:*int 是一个指针类型 (可以理解为 指向int类型的指针)//&age就是一个地址,是ptr变量的具体的值var ptr *int = &agefmt.Println(ptr)fmt.Println("ptr本身这个存储空间的地址为:",&ptr)//想获取ptr这个指针或者这个地址指向的那个数据:fmt.Printf("ptr指向的数值为:%v",*ptr) //ptr指向的数值为:18
}
对应的内存