一、类型
1.变量
Go 是静态类型语⾔言,不能在运⾏行期改变变量类型。
2.常量
a.常量值必须是编译期可确定的数字、字符串、布尔值。
b.在常量组中,如不提供类型和初始化值,那么视作与上一常量相同。
const( s = "abc" x // x = "abc" )
c.关键字 iota 定义常量组中从 0 开始按⾏行计数的⾃自增枚举值。如果 iota 自增被打断,须显式恢复。
const ( A = iota // 0 B // 1 C = "c" // c D // c,与上⼀一⾏行相同。 E = iota // 4,显式恢复。注意计数包含了 C、D 两⾏行。 F // 5 )
3.基本类型
类型 |
长度 |
默认值 |
说明 |
bool |
1 |
false |
|
byte |
1 |
0 |
uint8 |
rune |
4 |
0 |
Unicode Code Point, int32 |
int, uint |
4 或 8 |
0 |
32 或 64 位 |
int8, uint8 |
1 |
0 |
-128 ~ 127, 0 ~ 255 |
int16, uint16 |
2 |
0 |
-32768 ~ 32767, 0 ~ 65535 |
int32, uint32 |
4 |
0 |
-21亿 ~ 21 亿, 0 ~ 42 亿 |
int64, uint64 |
8 |
0 |
|
float32 |
4 |
0.0 |
|
float64 |
8 |
0.0 |
|
complex64 |
8 |
||
complex128 |
16 |
||
uintptr |
4 或 8 |
⾜足以存储指针的 uint32 或 uint64 整数 |
|
array |
值类型 |
||
struct |
值类型 |
||
string |
“” |
UTF-8 字符串 |
|
slice |
nil |
引⽤用类型 |
|
map |
nil |
引⽤用类型 |
|
channel |
nil |
引⽤用类型 |
|
interface |
nil |
接⼝口 |
|
function |
nil |
函数 |
注:
- byte 等同于int8,常用来处理ascii字符
- rune 等同于int32,常用来处理unicode或utf-8字符
4.引⽤类型
引⽤类型包括: slice、map 和 channel。它们有复杂的内部结构,除了申请内存外,还需要初始化相关属性。
内置函数 new 计算类型⼤小,为其分配零值内存,返回指针。而 make 会被编译器翻译成具体的创建函数,由其分配内存和初始化成员结构,返回对象⽽非指针。
a := []int{0, 0, 0} // 提供初始化表达式。 a[1] = 10 b := make([]int, 3) // makeslice b[1] = 10 c := new([]int) c[1] = 10 // Error: invalid operation: c[1] (index of type *[]int)
5.类型转换
go不⽀持隐式类型转换。
var b byte = 100 // var n int = b // Error: cannot use b (type byte) as type int in assignment var n int = int(b) // 显式转换
6.字符串
a.字符串是不可变值类型,内部用指针指向 UTF-8 字节数组。 不能⽤序号获取字节元素指针,即:&s[i] 非法。
b.使⽤ “`” 定义不做转义处理的原始字符串,支持跨行。
s := `a b\r\n\x00 c` println(s)
7.指针
将 Pointer 转换成 uintptr,可变相实现指针运算。
8.⾃自定义类型
a.可将类型分为命名和未命名两⼤类。命名类型包括 bool、int、string 等,而array、slice、map 等和具体元素类型、⻓度等有关,属于未命名类型。
b.可用 type 在全局或函数内定义新类型。新类型不是原类型的别名,除拥有相同数据存储结构外,它们之间没有任何关系。
func main() { type myint int64 var a myint = 100 println(a) var b int64 b = a // 不能直接赋值 必须要显示转换 b = int64(a) }
二、表达式
1.保留字
break |
default |
func |
interface |
select |
case |
defer |
go |
map |
struct |
chan |
else |
goto |
package |
switch |
const |
fallthrough |
if |
range |
type |
continue |
for |
import |
return |
var |
2.运算符
a.全部运算符、分隔符,以及其他符号:
+ |
& |
+= |
&= |
&& |
== |
!= |
( |
) |
– |
| |
-= |
|= |
|| |
< |
<= |
[ |
] |
* |
^ |
*= |
^= |
<- |
> |
>= |
{ |
} |
/ |
<< |
/= |
<<= |
++ |
= |
:= |
, |
; |
% |
>> |
%= |
>>= |
— |
! |
… |
. |
: |
&^ |
&^= |
0110 ^ 1011 = 1101 XOR 只能⼀一个为 1。(异或)
0110 &^ 1011 = 0100 AND NOT 清除标志位。(根据右边的操作数,如果是1则清除左边的数据为0,否则维持不变。1011代表:清除、不变、清除、清除,所以是0100)
b.运算符优先级(从上到下优先级降低):
high |
* |
/ |
& |
<< |
>> |
& |
&^ |
+ |
– |
|” |
^ |
||||
== |
!= |
< |
<= |
< |
>= |
||
<- |
|
||||||
&& |
|||||||
low |
|| |
注:
“++”、”–” 是语句⽽非表达式。
没有 “~”,取反运算也⽤用 “^”。
3.初始化
4.控制流
a.不⽀支持三元操作符 “a > b ? a : b”。
b.不支持while
4.1.1 range
a.range类似迭代器操作,返回 (索引, 值) 或 (键, 值)。
类型 | 第一个值 | 第二个值 | 备注 |
string | index | s[index] | unicode, rune |
array/slice | index | s[index] | |
map | key | m[key] | |
channel | element |
b.示例
s := "abc" for i := range s { // 忽略 2nd value,⽀支持 string/array/slice/map。 println(s[i]) } for _, c := range s { // 忽略 index。 println(c) } for range s { // 忽略全部返回值,仅迭代。 ... } m := map[string]int{"a": 1, "b": 2} for k, v := range m { // 返回 (key, value)。 println(k, v) }
c.range关于数组和slice的区别:
func TestRange(t *testing.T) { arr := [3]int{1, 2, 3} for i, v := range arr { // index、value 都是从复制品中取出 if i == 0 { arr[1] = 200 // 修改原数组 对index、value没影响 } fmt.Println(i, v) } fmt.Println(arr) fmt.Println("-----------------") slc := []int{1, 2, 3} for i, v := range slc { // 复制 struct slice { pointer, len, cap }。 if i == 0 { slc[1] = 200 // 对原slice的修改 会影响value } fmt.Println(i, v) } fmt.Println(slc) }
输出结果:
注:range 会复制对象。另外两种引⽤用类型 map、channel 是指针包装,而不像 slice 是 struct。
4.1.2 switch
分⽀表达式可以是任意类型,不限于常量。可省略 break,默认自动终⽌。如需要继续下一分支,可使用 fallthrough,但不再判断条件。
func TestSwitch(t *testing.T) { var num int switch num { case 2: fmt.Println("a") case 0: fmt.Println("b") fallthrough // 不加fallthrough只输出"b" default: fmt.Println("c") } }
输出:
4.1.3 Goto、Break、Continue
break 可⽤用于 for、switch、select,而 continue 仅能⽤于 for 循环。
x := 100 switch { case x >= 0: if x == 100 { break } println(x) // 不会输出x }
三、函数
1.函数定义
2.变参
四、数据
1.Array
2.Slice