这是我纯手写的《Go语言入门》,手把手教你入门Go。源码+文章,看了你就会🥴,此处应有掌声👏👏👏。
文章中所有的代码我都放到了github.com/GanZhiXiong/go_learning这个仓库中。
基本数据类型
Go语言的基本数据类型分别是:布尔型、数字类型、字符串类型
我比较喜欢以表格的形式展示,所以我会尽可能用到表格
类型 | 描述 |
---|---|
布尔型 | 布尔型的值只可以是常量 true 或者 false。一个简单的例子:var b bool = true。 |
数字类型 | 整型 int 和浮点型 float32、float64,并且支持复数,其中位的运算采用补码。 |
字符串 | 是一串固定长度的字符连接起来的字符序列。Go 的字符串是由单个字节连接起来的,字节使用 UTF-8 编码标识 Unicode 文本。 |
这里我重点讲下数字类型,字符串我会在后面写一篇文章专门讲解。
数字类型
数字类型分为:整形和浮点型
整形
整形又分为:无符号整形和有符号整形
其中int和uint的位数由操作系统位数决定,如64位操作系统,则int为有符号64位
无符号整形
类型 | 描述 | 范围 |
---|---|---|
uint | 无符号32位或64位整形 | |
uint8 | 无符号8位整形 | 0 - 255 |
byte | 类似uint8 | |
uint16 | 无符号16位整形 | 0 - 65535 |
uint32 | 无符号32位整形 | 0 - 4294967295 |
uint64 | 无符号64位整形 | 0 - 18446744073709551615 |
uintptr | 无符号整型,用于存放一个指针 |
有符号整形
类型 | 描述 | 范围 |
---|---|---|
int | 有符号32位或64位整形 | |
int8 | 有符号8位整形 | -128 - 127 |
int16 | 有符号16位整形 | -32768 - 32767 |
int32 | 有符号32位整形 | -2147483648 到 2147483647 |
rune | 类似int32 | |
int64 | 有符号64位整形 | -9223372036854775808 到 9223372036854775807 |
浮点型
类型 | 描述 |
---|---|
float32 | IEEE-754 32位浮点型数 |
float64 | IEEE-754 64位浮点型数 |
complex32 | 32 位实数和虚数 |
complex64 | 64位实数和虚数 |
类型转换
类型转换分为两张方式:隐式类型转换和显示类型转换(强制类型转换)
有很多程序员可能连显示类型转换和隐式类型转换的概念都还不清楚
- 隐式类型转换 - 以安全方式进行的转换, 不会导致数据丢失。例如,从小的整数类型转换为大的整数类型,从派生类转换为基类。
- 显式类型转换 - 显式类型转换,即强制类型转换。显式转换需要强制转换运算符,而且强制转换可能会造成数据丢失。
例如:
C语言中隐式转换的规则为:小字节类型向大字节类型转换
如:
int a = 1; double b = 1.234;
b = a; // 隐式转换
a = (int)b; // 显示转换
而Go语言类型转换比较特殊,它和一些主流语言有如下两点不同:
- 不允许隐式类型转换
这意味着不同类型的变量之间不能进行运算操作,如int不能加int32 - 别名和原有类型也不能进行隐式类型转换
可以看过Go是很严格的语言,严格的好处就是能减少代码出错。
下面我用代码来演示下Go的类型转:
func TestImplicit(t *testing.T) {
var a = 1
var b = 2
a = b
t.Log(a, b)
t.Log("a type:", reflect.TypeOf(a))
t.Logf("b type: %T", b)
// 即使int32在int64范围内,还是会报错,因为Go不支持隐式类型转换
var c int32 = 3
var d int64 = 4
// 报错:Cannot use 'c' (type int32) as type int64
//d = c
// Invalid operation: c + d (mismatched types int32 and int64)
//var and = c + d
d = int64(c)
t.Log(c, d)
t.Log("c type:", reflect.TypeOf(c))
t.Logf("d type: %T", d)
// 别名和原有类型也不能进行隐式类型转换
var e MyInt
var f int64
f = d
// Cannot use 'd' (type int64) as type MyInt
//e = d
e = MyInt(d)
t.Log(e, f)
t.Log("c type:", reflect.TypeOf(e))
t.Logf("d type: %T", e)
}
这里演示Go获取变量类型的两种方式
- reflect.TypeOf()
- 格式化输出%T
上面代码的结果我就不贴出来了,先自己计算输出结果,然后自行手写后看执行结果。
数据范围
通过math这个package可以获取数据类型的最大值和最小值。
func TestDataRange(t *testing.T) {
t.Log("int8 范围:", math.MinInt8, math.MaxInt8)
t.Log("int16 范围:", math.MinInt16, math.MaxInt16)
t.Log("int32 范围:", math.MinInt32, math.MaxInt32)
t.Log("int64 范围:", math.MinInt64, math.MaxInt64)
}
指针类型
C和C++可以对指针直接进行操作;
C#可以使用unsafe操作指针;
Java严格来说是没有指针的概念,引用类似指针;
那么Go呢?
- Go有指针,但是不支持指针运算
这意味着不能通过指针自增来访问连续的存储空间,如数组
func TestPoint(t *testing.T) {
a := 1
aPtr := &a
// 进行指针运算会报错:
// Invalid operation: aPtr + 1 (mismatched types *int and untyped int)
// 无效操作:aPtr + 1(不匹配的类型*int和无类型int)
//aPtr = aPtr + 1
t.Log(a, aPtr)
t.Logf("%T, %T", a, aPtr)
}
- string是值类型,其默认的初始化值为空字符串,而不是null