变量的声明
注意区分方法变量和全局变量
全局变量的声明
全局变量的声明是跟函数同级的,也就是定义在函数外部的变量就是全局变量
package main
var n1 = 100
var n2 = 300
var str = "fafa"
func main() {
...
}
或者使用下面这种方式声明:
package main
var (
n1 = 100
n2 = 21
str = "212"
)
func main() {
...
}
方法(局部)变量的声明
声明单个变量
Golang 比较严格,定义的每个变量必须要使用,如果不使用,编译就通不过
- 第一种方式:指定变量类型和名称
# 定义一个 int 类型的变量 i,并给 i 赋值
var i int
i = 10
- 第二种方式:根据值自行判断类型
var num = 10.1
- 第三种方式:省略 var 关键字
str := "hello"
声明多个变量
- 声明多个变量后赋值
var n1, n2, n3 int
n1 = 1
n2 = 2
n3 =3
- 声明变量的同时赋值
var n1, name, n2 = 100, "time", 22
- 声明时可以省略 var 关键字
n1, name, n2 := 100, "time", 22
变量使用的注意事项
- 作用域内的数据值可以不断变化
- 变量在同一作用域内不能重名
- 变量=变量名+值+数据类型
- 定义的变量如果没有赋初值,会使用默认值
数据类型的使用
每一种数据都定义了明确的数据类型,并在内存中分配了不同大小的内存空间
整数类型
int 是有符号的整型,uint 是无符号的整型
类型 | 有无符号 | 占用存储空间 | 表示范围 |
---|---|---|---|
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-1 |
uint | 无 | 32位系统4个字节 64位系统8个字节 | 0 ~ 232-1 0 ~ 264-1 |
rune | 有 | 与int32一样 | -231 ~ 231-1 |
byte | 无 | 与uint8等价 | 0 ~ 255 |
Golang 中整型默认声明为 int 型
package main
import "fmt"
func main() {
i := 10
fmt.Printf("i 的类型为:%T", i)
}
# 输出
i 的类型为:int
查看变量的类型和占用空间大小,unsafe 包下的 Sizeof 查看变量占用字节数
fmt.Printf("i 的类型为:%T,占用的字节数为:%d", i, unsafe.Sizeof(i))
# 输出
i 的类型为:int,占用的字节数为:8
浮点类型
类型 | 占用存储空间 | 表示范围 |
---|---|---|
单精度float32 | 4字节 | -3.403E38 ~ 3.403E38 |
双精度float64 | 8字节 | -1.798E308 ~ 1.798E308 |
需要注意的是浮点型数据有可能会造成精度损失,float64表示的数的范围比float32大,但同样有可能会造成精度丢失
Golang 默认的浮点型为:float64 类型
func main() {
i := 9.99
fmt.Printf("i 的类型为:%T,占用的字节数为:%d", i, unsafe.Sizeof(i))
}
# 输出
i 的类型为:float64,占用的字节数为:8
字符类型
Golang 中没有专门的字符类型,如果要存储单个字符,一般使用 byte 存储,注意是单个字母,如果是单个汉字,由于 Golang 默认使用 UTF-8 编码,一个汉字由三个字节表示,不能使用 byte 存储
字符串是一串固定长度的字符连接起来的字符序列。Go 的字符串是由单个字节连接起来的。也就是说对于传统的字符串是由字符组成的,而 Go 的字符串是由字节组成的。
func main() {
var c1 byte = 'a'
// 这里不能使用 byte 存储汉字,byte 只能存储 0 ~ 255 的整型
var c2 int = '牛'
// 输出 牛 的 ascii 码
fmt.Printf("c1=%c", c1)
fmt.Printf("c2=%c 对相应的ascii码为:%d", c2, c2)
}
# 输出
c1=a
c2=牛 对相应的ascii码为:29275
注意事项:
- 字符的本质是一个整数,直接输出时,是该字符对应的 UTF-8 编码的码值。
- 也可以给某一个变量赋一个数字,格式化输出的时候输出 %c,会输出该数字的 unicode 字符
- 字符类型是可以运算的,相当于整数运算
布尔类型
bool 类型只占 1 字节,只能取 true 或者 false
字符串类型
Golang 的字符串是由单个字节连接起来的,使用 UTF-8 编码的 Unicode 字符集。一旦赋值,就不能修改了!!!
注意:字符串有两种赋值形式。
- 双引号,会识别转义字符
- 反引号,以字符串原生形式输出,包括换行和特殊字符
# 会识别转义字符
str := "ab\navx"
# 原样输出
str2 := `
fksldjf
sdfasdfjlksdf
sdfasjkl
sdfasdf
`
总结
以上就是 Golang 的默认数据类型,默认情况下不赋值的话是会有默认值的,默认值如下:
数据类型 | 默认值 |
---|---|
整型 | 0 |
浮点型 | 0 |
字符串 | “” |
布尔类型 | false |
基本数据类型的转换
Golang 和 Java/c 不同,Go 在不同类型的变量之间赋值时需要显式转换。也就是说 Golang 中数据类型不能自动转换。
- 基本语法
表达式 T(v) 将值 v 转换为类型 T
T:就是数据类型,比如 int32, int64, float32 等等
v:就是需要转换的变量.
var i int = 12
f := float32(i)
u := uint8(f)
注意:Golang 中高低精度可以互转,但有高精度转为低精度时,如果溢出,按溢出处理,并不会是我们想要的结果。另外转换的是数据的值,数据本身的数据类型并没有发生变化!!!
基本数据类型和 string 的转换
查看文档:Golang 标准库文档
- 基本数据类型转 string
方式一、使用 fmt.Sprintf(“%参数”, 表达式)
参数需要和表达式的数据类型相匹配,返回值是转换后的字符串。文档中有关于参数的详细列举
var i int = 12
str:= fmt.Sprintf("%d", i)
fmt.Printf("str 类型为:%T", str)
# 输出
str 类型为:string
方式二、使用 strconv 包的函数
var i int = 12
# 第二位标识要转换的 int 类型的数是十进制的还是二进制的还是别的,这里 12 是十进制,所以填 10
str2 := strconv.FormatInt(int64(i), 10)
方式三、也是工作中常用的:Itoa,具体用法可以查看文档,strconv 包下的函数
var i int = 12
str2 := strconv.Itoa(i)
- string 类型转基本数据类型
使用 strconv 包中的函数,比如:
func ParseInt(s string, base int, bitSize int) (i int64, err error)
str := "123456"
f, _ := strconv.ParseFloat(str, 64)
fmt.Printf("f 类型为:%T", f)
# 输出
f 类型为:float64
注意事项:在把 string 转换为基本数据类型时,要确保 string 类型能够转换成有效的数据,比如不能把 ”hello“ 转成一个整数,如果这样做,Golang 直接将其转成 0,其他情况也是一样,都会默认赋默认值
值类型和引用类型
-
值类型
包括:基本数据类型 int、float、bool、string;数组、结构体struct
声明一个值类型的变量,变量直接存储的是值,内存通常在栈
上分配 -
引用类型
包括:指针、切片slice、map、管道channel、interface
声明一个引用类型的变量,变量存储的是一个地址,这个地址对应的内存空间中存储的才是具体的值,内存通常在堆
上分配,当没有任何变量引用这个地址的时候,该地址对应的内存空间会被 GC 回收