成体系的、快速学通Go,就在此时,持续连载!
上一篇:
https://lan6193.blog.csdn.net/article/details/123454411https://lan6193.blog.csdn.net/article/details/123454411上文熟悉了Go的基础符号、基础规则,本文我们来重点说说常量、变量、数据类型这些基础元素,为快速写出自己的程序打好各项玩法基础!
目录
数据类型
常量
变量
数据类型
在常见的各种声明中,少不了定义“它”是什么类型的,比如一个变量/常量的类型、一个函数的反正类型等。数据类型的出现正是为了把数据分成所需内存大小不同的数据,编程的时候需要用大数据的时候才需要申请大内存,就可以充分利用内存。现在一起看看所有的数据类型:
类型名称 | 关键字 | 默认值 | 可选值/备注 |
布尔 | bool | false | true、false |
字符串 | string | 空字符串(长度为0),go中字符串使用 UTF-8 编码 | |
float32浮点类型 | float32 | 0 | |
float64浮点类型 | float64 | 0 | |
32 位实数和虚数 | complex64 | ||
32 位实数和虚数 | complex64 | ||
无符号整型 | uint | 0 | 在64位机器上等价于uint64,可选uint32、uint64 |
无符号8位整型 | uint8 | 0 | 范围:0至2^8-1 |
无符号16位整型 | uint16 | 0 | 范围:0至2^16-1 |
无符号32位整型 | uint32 | 0 | 范围:0至2^32-1 |
无符号64位整型 | uint64 | 0 | 范围:0至2^64-1 |
有符号整型 | int | 0 | 在64位机器上等价于uint64 |
有符号8位整型 | int8 | 0 | 范围:2^-7至2^7-1 |
有符号16位整型 | int16 | 0 | 范围:2^-15至2^15-1 |
有符号32位整型 | int32 | 0 | 范围:2^-31至2^31-1 |
有符号64位整型 | int64 | 0 | 范围:2^-63至2^63-1 |
字节类型 | byte | 类似uint8 | |
rune类型 | rune | 类似 int32 | |
无符号整型 | uintptr | 用于存放指针 |
其它类型:
函数类型、数组类型、切片类型、指针类型、结构体struct类型、channel、map(k-v映射,其它语言中的字典)、接口类型(interface)
这里仅作介绍,有个初始印象,一些较复杂类型我们后面需要抽出大量篇幅来专门说明和分析。
常量
所谓常量,就是在程序运行中不会被修改的量。常量的类型可以是字符串型、布尔型、数字型(整数型、浮点型和复数)。
来看看常量的声明及应用
import (
"fmt"
"reflect"
)
// 显式的定义,带类型
const d0 string = "name0"
// 隐式的定义,不带类型(编译器会根据值来推断类型)
const d1 = "name1"
const d2 = 19.9
const d3 = false
// 定义多个同类型常量,可用如下方式简写
const d4, d5 = 1, 2
// 注意,上述const定义还可以合在一起通过const ()的方式一起定义
func main() {
fmt.Println(d0 + d1) // +相当于两个字符串的拼接
fmt.Println(reflect.TypeOf(d2)) // 没有带类型,那我们看看它默认被声明为了什么类型?
fmt.Println(d3)
fmt.Println(d4 + d2) // 运算+
fmt.Println(d4 - d5) // 运算-
/*
name0name1
float64
false
20.9
-1
*/
// d5 = 1 // 可以看到Cannot assign to d5,常量是不能被修改的,否则就不是常量了
}
特殊的常量符号-iota
1,iota是和const一起出现的常量符号,经过它定义的常量是可以被编译器修改的;
2,iota在const关键字出现时会被重置为0(const下第一行之前),const中每新增一行常量声明将使iota计数一次;
3,iota可以用来做常见的枚举。
来通过实例看看它是怎么回事:
const (
a1 = iota // 初始为0
a2 = iota // 自动+1
a3 = iota // 自动+1
a4 // 在新的一行iota再次被使用,它的值都会自动+1,a3=2,因此a4=3
a5 = 9.9 // 被设置为9.9,与iota无关,但此行iota计数实际为4
a6 // 依旧是9.9,此行iota计数为5
a7 = true // 被设置为true,即布尔类型,虽与iota无关,但此行iota计数实际为6
a8 // true, 此行iota计数实际为7
a9 = iota // 重新设置为iota,则此时为8
a10 // 继续iota,会+1,因此值为9
a11 = 1 + iota // 继续iota,值本应该为10,但赋值时给iota做了+1操作,因此值=11
)
const (
b1 = iota + 1 // 初始为0,但做了+1操作,值为1
b2 = iota + 1 // 本应为1,但做了+1操作,值为2
b3 // 本应为2,但做了+1操作(格式与上一行一致),因此值为3
b4 = iota // 本应为3,直接设置为iota,相当于按原有iota计数,因此值为3
b5 = iota + 1 // 本应为4,但做了+1操作,因此值为5
b6 = "b6" // 设置为字符串,则值为字符串b6(注意此行iota本应是5)
b7 = iota + 1 // 本应为6,但做了+1操作,因此值为7
)
// <<是移位运算,代表左移
const (
c1 = iota // c1=0
c2 = 1 << iota // iota值为1,c2值等于将0001左移1位,等价于c2 = 1 << 1,即0010=2
c3 = iota << iota // iota值为2,等价于c3 = 2 << 2,即0010 --> 1000=8
c4 = 3 << iota // iota值为3,等价于c4 = 3 << 3,即00000011 --> 00011000=24
c5 = c3 + c4 + iota // 相当于c5 = 8 + 24 + 4 = 36
)
func main() {
/*
因为iota会自动+1,因此上述前三行定义又等价于:
const (
a1 = iota
a2
a3
)
其中b3就相当于 b3 = iota + 1
*/
fmt.Println(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11)
fmt.Println(b1, b2, b3, b4, b5, b6, b7)
fmt.Println(c1, c2, c3, c4, c5)
}
speed running:
0 1 2 3 9.9 9.9 true true 8 9 11
1 2 3 3 5 b6 7
0 2 8 24 36
代码中做了详细解释,相信你现在对iota已有了新的认识哦!
变量
变量也很简单,使用var来声明,格式与常量几乎没什么区别:
import (
"fmt"
"reflect"
)
var (
e1 = "d1"
e2 = 2
e3 = false
e4 = 9.9
e5 = 2 * e4
)
func main() {
fmt.Println(e1, e2, e3, e4, e5) // d1 2 false 9.9 19.8
// 修改变量
e2 = 2 * e2
fmt.Println(e2) // 4
// 仅声明,不赋值,则变量为默认类型的零值(零值意为该类型的初始值,如整型是0,字符串就是空字符串,布尔就是false等等)
var e6 int
var e7 bool
fmt.Println(e6, e7) // 0 false
// 还可以同时声明+赋值,符号为:=
e8 := 9.9 // 直接定义变量e8并赋值9.9,并未指定类型,编译器自动设定为float64
fmt.Println(e8, reflect.TypeOf(e8)) // 9.9 float64
// 可同时定义多个变量
var e9, e10, e11 = 1, 2, 3
fmt.Println(e9, e10, e11) // 1 2 3
}
经过上文总结和示例,关于常量、变量、数据类型相信你已经有了一个全面的认识,一些运算符也悄然蕴含到了其中,下一篇我们专门来汇总一下各种运算符及其用法。