目录
-
- [1. 基本类型](#1. 基本类型)
- [2. 常量](#2. 常量)
- [3. 变量](#3. 变量)
-
- [3.1 变量声明](#3.1 变量声明)
- [3.2 自定义类型、类型别名](#3.2 自定义类型、类型别名)
- [3.3 类型推导](#3.3 类型推导)
- [3.4 类型断言](#3.4 类型断言)
- [3.5 类型转换](#3.5 类型转换)
1. 基本类型
-
支持八进制、十六进制,以及科学记数法
-
零值:只做了声明,但未做初始化的变量被给予的缺省值。每个类型的零值都会依据该类型的特性而被设定。
-
单引号(''):定义一个字符;返回rune类型,也就是码点字面量(Unicode code point)。
-
双引号(""):定义字符串
-
反引号(``):通常使用于字符串换行、正则表达式
-
byte
是uint8
的别名,代表ASCII码的一个字符;rune
是int32
别名,代表一个UTF-8字符
类型 | 长度(字节) | 零值 | 说明 | |
---|---|---|---|---|
布尔值 | bool | 1 | false | true|false |
整型 | int, uint | 4或8 | 0 | 与操作系统位数相同(32或64位) |
整型 | int8(byte), uint8 | 1 | 0 | 取值:-128 ~ 127, 0 ~ 255;byte是uint8 的别名 |
整型 | int16, uint16 | 2 | 0 | 取值:$-32768 ~ 32767, 0 ~ 65535 |
整型 | int32, uint32(rune) | 3 | 0 | 取值:-2\^{31} ~ 2\^{31}-1, 0 ~ 2\^{32}-1;rune是int32 的别名 |
整型 | int64, uint64 | 4 | 0 | |
浮点 | float32 | 4 | 0.0 | |
浮点 | float64 | 8 | 0.0 | |
复数 | complex64 | 8 | ||
复数 | complex128 | 16 | ||
字符串 | string | "" | UTF-8 字符串 | |
结构体 | struct | 值类型 | ||
引用类型 | slice | nil | 切片:[n]Type | |
引用类型 | map | nil | 字典:[Type]Type{} | |
引用类型 | chan | nil | 管道 | |
接口 | interface(any) | nil | interface{} | |
函数 | func | nil |
2. 常量
常量是恒定不变的,常量定义时必须赋值;常量只会在编译期间存在,不存储内存中,不可被寻址。
iota
iota
是Go语言的常量计数器,只能在常量的表达式中使用。iota
在const
关键字出现时将被重置为0。const
中每新增一行常量声明将使iota
计数一次(iota可理解为const语句块中的行索引)。- 使用iota能简化定义,在定义枚举时很有用。
go
package main
import "fmt"
// 常量是恒定不变的,常量定义时必须赋值。
const Pi = 3.14
// 多个常量一起声明
const (
str = "string"
i = 100
)
// const 同时声明多个变量,如果省略了值,则上一行的值(或表达式)相同
const (
n1 = 100 // 100
n2 // 100
n3 // 100
)
// 常量声明使用iota,每新增一行计数一次
const (
m1 = iota // 0, 索引由0开始
m2 // 1
_ // 2 即使忽略,iota同样计数
n4 = 200 // 200 插队声明, iota同样计数
n5 // 200 使用省略值规则
m3 = iota // 5 重新使用iota规则
m4 // 6
)
// 多个iota定义在一行(缺省值和iota结合)
const (
a, b = iota + 1, iota + 2 //1,2 iota = 0
c, d //2,3 iota = 1,iota + 1 = 2, iota + 2 = 3
e, f //3,4 iota = 2,iota + 1 = 3, iota + 2 = 4
)
func main() {
fmt.Println(n1, n2, n3, n4, n5) // 100 100 100 200 200
fmt.Println(m1, m2, m3, m4) // 0 1 5 6
fmt.Println(a, b, c, d, e, f) // 1 2 2 3 3 4
}
3. 变量
3.1 变量声明
-
Go语言的变量声明后必须使用
-
变量声明时会自动被初始化成其类型的默认值
go
// 声明格式:var name Type
var i int64
var (
x int64
y float64
)
// 初始化
var i1 int64 = 1
var name, age = "小猫", 1
// 短变量声明
s := "Short var"
// 变量重声明
// 1. 不支持单个变量重声明;
// 2. 当有新的变量和已被声明的变量同时声明时,允许使用:=重声明已有变量,
// 3. 重声明时,变量类型不可改变
i, j := 10, 100 // 存在新的变量j
// 4. 变量重声明是在某一个代码块内,并不包含它的任何子代码块。
if true {
i := "Set string type" // 子代码块中i为新的字符串变量(重名变量)
}
// 匿名变量(_),用于忽略多个返回值中的某些值
x, _ := "X", 100
println(x)
3.2 自定义类型、类型别名
自定义类型:通过Type
关键字定义,是定义一个全新的类型。
类型别名:使用"="定义,type TypeAlias = Type
,TypeAlias只是Type的别名,本质上属于同一个类型。
- 潜在类型:某个类型其本质上是哪种类型。
- 内置基本类型:
uint8
别名byte
、int32
别名rune
、interface{}
别名any
。
go
type AString = string
var s AString = "Alisa"
fmt.Printf("%T \n", s) // string
type BString string
bs := BString("New Type")
fmt.Printf("%T \n", bs) // main.BString
// 1. 潜在类型相同的不同类型之间可以进行类型转换。
s = AString(bs)
// 2. 对于集合类的类型[]string与[]BString的潜在类型不同,分别为[]string和[]BString。
s1 := []string{"a", "a", "a", "a"}
s2 := []BString{"b", "b", "b", "b"}
fmt.Printf("%T %T \n", s1, s2) // []string []main.BString
// 3. 即时两个不同类型的潜在类型相同,他们的值也不能进行判等或比较,他们的变量之间也不能赋值。
s = bs // 报错: cannot use bs (variable of type BString) as type string in assignment
3.3 类型推导
也叫隐式类型转换。有时候我们会将变量的类型省略,这个时候编译器会根据等号右边的值来推导变量的类型完成初始化。
go
var a := 1.2 // float64
b := 1 + a // float64 可兼容类型允许隐式转换,编译器可以将 1 隐式转换为 float64 类型
c := 1 // 编译器不允许对标识符引用的值进行强制转换
d := a + c // invalid operation: c + a (mismatched types int and float64)。
3.4 类型断言
类型断言是一个使用在接口值上的操作,用于检查接口类型变量所持有的值是否实现了期望的接口或具体的类型。
语法:value, ok := x.(T)
或 value := x.(T)
(此表达式若断言失败则会产生panic)
x:表示一个接口类型
T:表示一个具体的类型(或接口)
value:表示返回的 x 的值
ok:bool值,表示 x 的值类型是否为 T
go
var x interface{}
x = 10
fmt.Printf("%T \n", x.(interface{})) // int
v, ok := x.(int) // v = 10, ok = true
v2, _ := x.(string) // v2 = ""
v3 := x.(int) // v3 = 10
v4 := x.(string) // 产生 panic: interface conversion: interface {} is int, not string
// 如果 x 是 nil 接口值时,无论 T 是什么类型,断言都会失败,v 的值为 T 的缺省值。
x = nil
v, ok = x.(int)
fmt.Printf("v = %v, ok = %v \n", v, ok) // v = 0, ok = false
// 配合 switch
switch x.(type) {
case int:
fmt.Println("The type of x is int.")
case string:
fmt.Println("The type of x is string.")
default:
fmt.Println("unknown type.")
}
3.5 类型转换
类型转换包含:类型断言、强制转换、显示转换、隐式转换(类型推导)。
go
// 隐式转换
const a = 123
var i = 0
var i1 int64 = 1.0 // 可兼容类型允许隐式转换
var i2 int64 = 1.1 // 不兼容,产生错误
i3 = a * i1 // float64
// 显示转换/强制转换
var n int64 = 100
f := float64(n) // int to float64
ns := strconv.Itoa(n) // int to string
si, _ := strconv.Atoi("123") // string to int
// 指针类型强制转换 unsafe
var p int = 30
var prs *int = &p
var p2 *int64 = (*int64)(unsafe.Pointer(prs))
fmt.Printf("p addr = %d \n prs = %d \n p2 = %d, p2 addr = %d \n", &p, prs, *p2, p2)