GO基本类型枚举
类型 | 长度 | 默认值 | 说明 |
---|---|---|---|
bool | 1 | false | 布尔类型 |
byte | 1 | 0 | uint8 |
rune | 1 | 0 | int32的别名,Unicode Code Point。返回utf-8字符串的字符长度而不是内存长度 |
int, uint | 4或者8 | 0 | 32位机器上就是32位,64位机器上就是64位 |
int8, uint8 | 1 | 0 | -128 ~ 127, 0 ~ 255 |
int16, uint16 | 2 | 0 | -32768 ~ 32767, 0 ~ 65535 |
int32, uint32 | 4 | 0 | -2147483648~ 2147483647, 0 ~ 4294967295 |
int64, uint64 | 8 | 0 | -9223372036854775808~9223372036854775807,0~18446744073709551615 |
float32 | 4 | 0.0 | 1.4e-45~3.4e38,小数点后6位精度 |
float64 | 8 | 0.0 | 4.9e-324~1.8e308,小数点后15位精度 |
complex64 | 8 | 0+0i | 32 位实数和虚数 |
complex128 | 16 | 0+0i | 64 位实数和虚数 |
uintptr | 4或8 | 0 | 足以存储指针的 uint32 或 uint64 整数 |
array | 数组,值类型 | ||
struct | 结构体,值类型 | ||
string | "" | 字符串类型 | |
slice | nil | 切片,底层是数组。引用类型 | |
map | nil | 引用类型 | |
channel | nil | 通道,引用类型 | |
interface | nil | 接口 | |
function | nil | 函数 |
go 中类型之间必须显示转换。
可以将类型分为命名
和未命名
两类。命名类型包括 bool、int、string 等,⽽而 array、slice、map 等和具体元素类型、⻓长度等有关,属于未命名类型。
具有相同声明的未命名类型被视为同一类型。如:
- 具有相同基类型的指针。
- 具有相同元素类型和⻓长度的数组。
- 具有相同元素类型的
slice
。 - 具有相同键值的
map
。 - 具有相同元素类型和传送⽅方向的
channel
。 - 具有相同字段序列 (字段名、类型、标签、顺序) 的匿名
struct
。 - 签名相同 (参数和返回值,不包括参数名称) 的
func
。 - ⽅方法集相同 (⽅方法名、⽅方法签名相同,和次序⽆无关) 的 interface。
new和make
内置函数 new
计算类型⼤大⼩小,为其分配零值内存,返回指针。⽽而 make
会被编译器翻译 成具体的创建函数,由其分配内存和初始化成员结构,返回对象⽽而⾮非指针。引用类型需要由 make
创建。
字符串
字符串是不可变值类型,内部⽤用指针指向 UTF-8 字节数组。 默认值是空字符串 ""。
- ⽤用索引号访问某字节,如 s[i]。
- 不能⽤用序号获取字节元素指针,&s[i] ⾮非法。
- 不可变类型,⽆无法修改字节数组。
- 字节数组尾部不包含 NULL。
- 使⽤用索引号访问字符 (byte)。
|
|
- 使⽤用 "`" 定义不做转义处理的原始字符串,⽀持跨⾏。
- []byte 和 []rune 在字符处理上的差异:
|
|
输出:
|
|
指针
⽀支持指针类型 *T,指针的指针 **T。不能对指针做算术运算。
- 默认值nil,用“.”访问目标成员。
- 操作符 "&" 取变量地址,"*" 透过指针访问目标对象。
- 可以在
unsafe.Pointer
和任意类型指针间进⾏行转换。指针类型之间不可以强制转换为此引入unsafe
特殊场景下使用它可以打破go
的类型和内存安全机制,但是用着不安全。所以有了unsafe.Pointer
,它表示任意类型且可寻址的指针值,可以在不同的指针类型之间进行转换。- 任何类型的指针值都可以转换为
Pointer
Pointer
可以转换为任何类型的指针值uintptr
可以转换为Pointer
。uintptr
是 Go 的内置类型。返回无符号整数,可存储一个完整的地址,用于指针运算。也就是说将指针转换为uintptr
可以变相实现指针运算。Pointer
可以转换为uintptr
。uintptr
被GC当作普通整数,不能阻止所"引用"的对象被收回。- 指正构成的循环引用加上
runtime.SetFinalizer
会导致内存泄露。 引用 https://segmentfault.com/a/1190000017389782 中的内容说明:
- 任何类型的指针值都可以转换为
|
|
在剖析这段代码做了什么事之前,我们需要了解结构体的一些基本概念:
- 结构体的成员变量在内存存储上是一段连续的内存
- 结构体的初始地址就是第一个成员变量的内存地址
- 基于结构体的成员地址去计算偏移量。就能够得出其他成员变量的内存地址 再回来看看上述代码,得出执行流程:
- 修改
n.i
值:i
为第一个成员变量。因此不需要进行偏移量计算,直接取出指针后转换为Pointer
,再强制转换为字符串类型的指针值即可。- 修改
n.j
值:j
为第二个成员变量。需要进行偏移量计算,才可以对其内存地址进行修改。在进行了偏移运算后,当前地址已经指向第二个成员变量。接着重复转换赋值即可。unsafe.Offsetof
:返回成员变量x
在结构体当中的偏移量。更具体的讲,就是返回结构体初始位置到x
之间的字节数。需要注意的是入参ArbitraryType
表示任意类型,并非定义的 int。它实际作用是一个占位符。
表达式
保留字:
break | case | chan | const |
continue | default | func | defer |
go | else | goto | fallthrough |
if | for | import | interface |
map | package | range | return |
select | struct | switch | type |
var |
所有符号:
+ | & | += | &= | && | == | != |
- | | | -= | |= | || | < | <= |
* | ^ | *= | ^= | <- | > | >= |
/ | << | /= | <<= | ++ | = | := |
% | >> | %= | >>= | -- | ! | ... |
&^ | &^= |
运算符优先级
从高到低:
* / & << >> & &^
+ - | ^
== != < <= < >=
<- && ||
语法相关
range
返回的第一个值是key
,第二个是value
。当只写一个接收变量时获得key
。range
取到的值是一个复制,对其修改不会影响原有对象。map
、channel
是指针包装,slice
底层是数组,被定义为一个struct
。switch
自动break
,使用fallthrough
关键字可以继续下一分支,但是不再判断条件。- 为加强代码可读性不太建议使用
goto
语法。 - 函数不支持嵌套,重载,默认参数。
- 对于数组而言,内置函数 len 和 cap 都返回数组⻓长度 (元素数量)。