Go学习笔记——基础知识

特点

  • 静态语言,支持运行时动态类型;支持隐式类型推导;
  • 接口基于Duck模型;仅通过接口支持多态;不支持泛型但支持反射;
  • 编译成可执行程序直接执行;支持自动垃圾回收;语言原生支持并发;跨平台;多应用于云计算基础设施软件、中间件、区块链等。

程序结构

1
2
3
4
5
6
7
8
9
# 文件名:hello.go
# 包名,main为可执行程序的包名
package main
# 引入外部包fmt(标准输入输出)
import "fmt"
# 函数声明,main代表程序入口函数
func main(){
fmt.Printf("Hello, world.\n")
}

补充:

  • Go的源程序默认使用UTF-8编码
  • 语句结尾的分号可以省略
  • “{”必须在函数头所在行尾部,不能单独起一行
  • main函数所在的包名必须是main。

编译运行

  • 编译 go build hello.go
  • 运行 ./hello

标识符

(仅记录与Java不同的)

关键字

常量声明 const、变量定义 var、函数定义 func、延迟执行 defer、 结构类型定义 struct、通道类型 chan

数据类型标识

类型 标识
整型 byte int int8-int64 uint uint8-uint64 uintptr (byte就是uint8)
浮点数 float32 float64 (自动类型推断为float64)
复数 complex64 complex128 (由两个float构成,对应实部和虚部)
字符 rune
接口 error
连续枚举类型 iota
匿名变量 _

iota用法: iota用于常量声明中,初始值为0,逐行增加

1
2
3
4
5
6
const (
a = iota //iota=0,a=0
b //iota=1,b=1
c = 3 //iota=2,未使用,c=3
d = 1 << iota //iota=3,d=8
)

注意:Go语言里自增和自减是语句而不是表达式[1]

变量和常量

变量声明

1
2
3
4
5
6
7
//显式声明,value可以是表达式,不指定则初始化为类型零值,声明后立即分配空间
var varName dataType [ = value]
//短类型声明,只能出现在函数内,自动进行数据类型推断
varName := value

//支持多个类型变量同时声明并赋值
a, b := 1, "hello"

字符串和切片

  • 字符串可以通过类似数组索引的方式访问,但是不能修改
  • 字符串转换为切片[]byte()在数据量大的时候要慎用,因为转换的时候需要复制内容
  • 字符串的底层实现是一个指向字节数组的指针和字节数组长度
  • 基于字符串创建的切片指向原字符串指向的字符数组,不可修改

指针

  • 结构体指针访问结构体字段仍然使用”.”操作符,没有“->”
  • 不支持指针运算(GO支持垃圾回收,语言层面禁止指针运算)
  • 允许返回局部变量地址

切片

切片(可变数组)维护三个元素——指向底层数组的指正、切片元素数量、底层数组容量

创建方式:数组索引、make

Map

Go内置的map不是并发安全的,需要时用sync包内的map保证并发安全

map键值对的修改不能通过map引用直接修改键值,需要KV整体赋值

控制结构

If-else

1
2
3
if initialization; condition {
// do something
}

Switch

  • 条件表达式支持任意支持相等比较运算的类型变量
  • switch后面可以带上初始化语句
  • case后可以使用多个值比较,使用逗号分隔
  • 配合使用可以进行类型查询

Goto

  • goto需要配合标签使用
  • goto只能在函数内跳转,但是不能跳过内部变量声明语句,只能跳过同级作用域或上层作用域

Q:

【1】这是否意味着自增或自减是原子操作?
答:不是。