基本数据类型
序号 | 类型和描述 |
---|---|
1 | 布尔型(Boolean) 布尔型的值只可以是常量 true 或者 false |
2 | 数字类型 整型 int 和浮点型 float ,Go 语言支持整型和浮点型数字,并且原生支持复数**,其中位的运算采用补码。** |
3 | 字符串类型 字符串就是一串固定长度的字符连接起来的字符序列。Go的字符串是由单个字节连接起来的。Go语言的字符串的字节使用UTF-8编码标识Unicode文本。 |
4 | 派生类型 - 指针类型(Pointer) - 数组类型 - 结构体类型(struct) - 联合体类型 (union) - 函数类型 -切片类型 - 接口类型(interface) - Map 类型 - Channel 类型 |
数字类型
定长数字类型
序号 | 类型和描述 |
---|---|
1 | uint8 无符号 8 位整型 (0 ~ 2 8 − 1 2^{8}-1 28−1) |
2 | uint16 无符号 16 位整型 (0 ~ 2 16 − 1 2^{16}-1 216−1) |
3 | uint32 无符号 32 位整型 (0 ~ 2 32 − 1 2^{32}-1 232−1) |
4 | uint64 无符号 64 位整型 (0 ~ 2 64 − 1 2^{64}-1 264−1) |
5 | int8 有符号 8 位整型 ( − 2 8 -2^{8} −28 ~ 2 8 − 1 2^{8}-1 28−1) |
6 | int16 有符号 16 位整型 ( − 2 16 -2^{16} −216 ~ 2 16 − 1 2^{16}-1 216−1) |
7 | int32 有符号 32 位整型 ( − 2 32 -2^{32} −232 ~ 2 32 − 1 2^{32}-1 232−1) |
8 | int64 有符号 64 位整型 ( − 2 64 -2^{64} −264 ~ 2 64 − 1 2^{64}-1 264−1) |
9 | float32 IEEE-754 32位浮点型数 |
10 | float64 IEEE-754 64位浮点型数 |
11 | complex64 32 位实数和虚数 |
12 | complex128 64 位实数和虚数 |
不定长数字类型(基于架构变化)
序号 | 类型和描述 |
---|---|
1 | byte 类似 uint8 |
2 | rune 类似 int32 |
3 | uint 32 或 64 位 |
4 | int 与 uint 一样大小 |
5 | uintptr 无符号整型,用于存放一个指针 |
变量
变量声明
- 变量声明一般需要关键字
var
var hello string = "Hello World!" //单变量声明
var hello,world string = "Hello","World!" //多变量声明
- 在进行多变量声明时,必须保证声明的变量类型相同。Go语言无法在同一行同时声明不同类型的变量,下列写法是不被允许的
var hello int,world string = 666,"World!"
变量赋值
- 如果已经指定了变量类型,且未初始化,变量会默认为自己的零值
package main
import "fmt"
func main() {
var a int
fmt.Println(a)
var b bool
fmt.Println(b)
}
- 运行结果为
$ go run hello.go
0
false
- 一般数据类型的零值
数据类型 | 零值 |
---|---|
数字类型 | 0 |
布尔类型 | false |
字符串 | “”(空字符串) |
- 对于一些更加一般的数据类型,他们的零值被定义为
nil
(相当于其它语言的null
)
var ptr *int //int类型的指针
var i inter //inter是接口
var m map[string] int //映射
var f func(string) int //函数
- 在未指定数据类型时,变量也能正常赋值,此时依据的是Go语言提供的类型推导
package main
import "fmt"
func main() {
var a = "Hello World!"
fmt.Println(a)
}
- 为了简化变量的声明和使用,Go语言提供了一个简便的运算符
:=
,它可以让变量在未被声明的情况下直接使用
helloWorld := "Hello World!" //单变量声明
hello,world := "Hello","World!" //多变量声明
- 借助
Go
的类型推导机制,我们可以完成多变量不同类型的声明使用
six,sixString,sixFloat := 666,"6666",666.666
var six,sixString,sixFloat = 666,"6666",666.666
//这两行效果相同
- 注意:如果一个变量已经使用
var
声明过了,再使用:=
声明变量,就会发生编译错误
var temp string
temp := "Temp Var" //会报错
-
我们在实际开发中一般都会使用
:=
来声明和使用变量,用习惯了真的爽飞 -
在讲到多变量赋值的时候,我们可以清楚的看到这些变量是可以并行/同时赋值的,这就意味着我们可以使用更简便的方法进行变量的交换
package main
import "fmt"
func main() {
var hello,world = "Hello","World!"
fmt.Println(hello,world)
hello,world = world,hello
fmt.Println(hello,world)
}
- 运行一下,我们发现没有任何问题,两个变量的值成功交换
$ go run hello.go
Hello World!
World! Hello
-
Go允许函数拥有多个返回值,这就意味着我们有时候需要使用多个变量来接收这些值。但变量一旦声明就需要使用,当我们并不需要这些返回值的时候该怎么办?
-
Go提供了一个空白标识符
_
,表示这个变量被赋值但不需要使用
package main
import "fmt"
func main() {
var _,world = "Hello","World!"
fmt.Println(world)
}
-
但要注意的是,我们无法获取
_
的值 -
以下的写法是不被允许的
package main
import "fmt"
func main() {
var _,world = "Hello","World!"
fmt.Println(_,world)
}
关于全局变量
-
全局变量无法使用
:=
赋值,:=
只能被用在函数体内 -
局部变量如果被声明,一定要被使用,否则会报编译错误
package main
import "fmt"
func main() {
var a = "Hello World!"
var b = "Hello World!"
fmt.Println(b)
}
- 运行结果
$ go run hello.go
# command-line-arguments
.\hello.go:4.6: a declared and not used
- 全局变量可以只声明而不使用
package main
import "fmt"
var a = "Hello World!"
func main() {
var b = "Hello World!"
fmt.Println(b)
}
- 运行结果
$ go run hello.go
Hello World!
常量
常量声明
- 常量声明的关键字是
const
,定义的一般形式诸如const 常量名 常量类型 = 常量值
package main
import "fmt"
const helloWorld string = "Hello World!" //单常量声明
const a,b,c = 1,2,3 //多常量声明
const ( //多常量声明的另一种形式
PI = 3.14159
LENGTH int = 666
STR = "Go is the best language"
)
func main() {
fmt.Println(helloWorld,a,b,c,PI,LENGTH,STR)
}
- 运行结果
$ go run hello.go
Hello World! 1 2 3 3.14159 666 Go is the best language
内置函数
- 常量表达式中可以使用内置函数,但自定义函数则会报编译错误
package main
import "unsafe"
const (
STR = "This is temp string"
length = len(STR)
size = unsafe.Sizeof(STR)
)
func main(){
println(STR, length, size)
}
- 运行结果
$ go run hello.go
This is temp string 19 16
- 以下的代码则会报错
package main
const (
a = 5
b = 6
c = MySum(a,b)
)
func main(){
println(c)
}
func MySum(x int,y int) int {
return x+y
}
- 运行结果
$ go run hello.go
# command-line-arguments
.\hello.go:10:6 MySum(a,b) (value of type int) is not constant
iota
-
iota
是一个特殊常量,它可以被编译器修改 -
使用
iota
初始化常量,可以生成一组规则相似的常量。第一个const()
表达式中,iota
赋值的常量会被设置为0,此后每新增一个常量,都可以使得iota
进行一次计数,即此后的每一个常量都比前一个多一
package main
const (
zero = iota
one
two
)
func main(){
println(zero, one, two)
}
- 运行结果
$ go run hello.go
0 1 2
- 它和如下写法是一样的
package main
const (
zero = iota
one = iota
two = iota
)
func main(){
println(zero, one, two)
}
-
运行会得到相同的结果
-
接下来我们可以通过两个实验加深对
iota
的认识
package main
import "fmt"
func main() {
const (
a = iota //0
b //1
c //2
d = "Hello World" //独立值,iota += 1
e //和前面规律相同 iota += 1
f = 9999 //iota +=1
g //和前面规律相同 iota +=1
h = iota //7,恢复计数
i //8
)
fmt.Println(a,b,c,d,e,f,g,h,i)
}
- 运行结果
$ go run hello.go
0 1 2 Hello World Hello World 9999 9999 7 8
- 可以看到,即使我们对中间的几个变量进行了独立赋值,
iota
的计数也不会中断,而是继续进行,知道下一次iota
出现
package main
import "fmt"
const (
i=1<<iota
j=3<<iota
k
l
)
func main() {
fmt.Println("i=",i)
fmt.Println("j=",j)
fmt.Println("k=",k)
fmt.Println("l=",l)
}
- 运行结果
$ go run hello.go
i= 1
j= 6
k= 12
l= 24
- 在第二个
iota
出现后,其后的变量遵顼前一个变量的规律,实际上相当于
const (
i = 1 << 0
j = 3 << 1
k = 3 << 2
l = 3 << 3
)