对别人的意见要表示尊重。千万别说:"你错了。"——卡耐基
温馨提示:本文适合具有一定编程基础的童鞋阅读。
变量定义方式
变量名在运行时是不存在的,运行时直接操作内存地址。
未使用的局部变量,会被编译器认为是错误的,全局变量没事。
单个变量的定义
var x int # 自动初始化为0
var y = false # 自动推断类型
多个变量的定义
先计算右值,然后菜赋值:
var x,y int
var a, s = 100, "abc"
# 组的方式
var (
x, y int
a, s = 100, "abc"
)
简短模式
简短模式的限制:
- 只能用在函数内部
- 定义变量,同时显示初始化
- 不能提供数据类型
多返回值时,有部分会退化为赋值操作
func main() {
x := 100
a, s := 1, "abc"
}
错误使用情况:
var x = 100
func main() {
x := "abc" // 实际是重新定义和初始了同名局部变量
}
简短模式在函数多返回值,if/for/switch 中定义局部变量 很方便
多返回值时(必须至少一个是新定义的),有部分会退化为赋值操作:
func main(){
x := 100
x, y := 200, "abc" // 这里x 为赋值操作
z := 100
z := 200 // 会报错的
{
x, y :=200,300 // 不同作用域,全部是新定义
}
// 下面重复使用err很有意义
f,err := os.Open("/dev")
n,err := f.Read(buf)
}
变量命名
特别之处
符合首字母大小写决定了其作用域:
- 首字母大写的为导出成员,可被包外引用
- 首字母小写的仅能在包内使用
空标识符
“—” 标识忽略占位符使用,作为表达式左值,无法读取内容。
x, _ := f.read(buf) // _ 标识忽略err
通常用来避免 编译器对“未使用变量” 和 “导入包” 的错误检查
常量
常量在编译器编译后,作为指令数据使用,不会像变量一样分配存储空间,所以不能取地址
不可变,未使用也不会引发编译器错误
- 可以是计算出结果的表达式
- 后一行未指定初始值,则和上一行非空常量值相同
const x, y int = 123,332
const s = "ewew"
const (
i, f = 1, 0.123
b = false
s = "221"
z // 等于 221
)
func main() {
const x = 123
{
const x = "abs" // 不同作用域定义同名变量
}
}
枚举
go并没有提供枚举enum。可借助iota
const (
x = iota // 0
y // 1
z // 2
)
基本数据类型
通过math.MinInt8, math.MaxInt8 可以看到各种类型取值范围。
别名,可以直接替换的只有2个:
- byte 是 uint8
- rune s int32

引用类型
特指 slice, map, channel 这三种预定义类型
- 必须使用make函数创建,完成内存分配和相关属性初始化
s := make([]int, 0, 10) // slice
s = append(s, 100)
m := make(map[string]int) // map
m["a"] = 1
类型转换
- 必须是显示的类型转换
- 不能将非bool类型的当作true ,false
a := 10
b := byte(a)
c := a + int(b)
自定义类型
基于现有的基础类型,或者结构体等
user struct {
name string
age uint8
}
参考
- go by example中文网
- go 学习笔记
