-
- GO语言学习笔记-函数篇 Study for Go ! Chapter three - Function
- GO语言学习笔记-数据篇 Study for Go ! Chapter four - Data
- GO语言学习笔记-方法篇 Study for Go ! Chapter five - Method
- GO语言学习笔记-接口篇 Study for Go ! Chapter six - Interface
- GO语言学习笔记-并发篇 Study for Go ! Chapter seven - Concurrency
- GO语言学习笔记-包结构篇 Study for Go ! Chapter eight - Package Structure
- GO语言学习笔记-反射篇 Study for Go ! Chapter nine - Reflect
- GO语言学习笔记-测试篇 Study for Go ! Chapter ten- Test
- GO语言学习笔记-工具链篇 Study for Go ! Chapter eleven - Tool Chain
1. Variable
-
关键字为 " var "
-
自动初始化为二进制零值
-
-
变量类型放在变量名之后
-
可以一次性定义多个变量且可以是不同类型的初始值
-
可以用组的方式定义一组变量用“ { } ” 括起来
简短模式(short variable declaration):
-
关键字为 “ := ”
-
只能用在函数内部
-
不提供数据类型
-
定义的同时显式初始化
-
在函数内部使用简短模式时,如果在函数外有全局变量,函数内部的使用会被认为是同名变量
-
在函数内部使用简短模式时,如果在函数内部已有同名变量且本次简短模式定义包含至少一个新变量,则再一次使用的简短模式定义会被认为是部分“ 退化 ”的赋值操作
赋值退化:
-
赋值退化的前提时,之前至少有一个新变量被定义,并且必须是同一作用域
-
在处理函数错误返回值时,退化变量有利于重复使用err变量
多变量赋值:
-
先计算出所有右值再进行赋值操作
-
赋值操作必须保证左右值类型相同
Attention:
-
未使用的局部变量在golang中将被视作错误
2. Name
命名规范与建议:
-
以字母或者下划线开始,并可由字母、下划线、数字组合
-
区分大小写
-
用驼峰 (camel case) 规则拼写
-
局部变量优先使用短名
-
不要使用保留关键字
-
不建议使用与预定义常量、类型、内置函数相同的名字
-
专有名词通常全部大写
-
符号名字的首字母大小写决定了其作用域。首字母大写的为导出成员,可被包外引用,而首字母小写只能在包内引用
-
空标识符( blank identifier ) “ _ ” 作为忽略占位符,可做表达式左值,用来规避编译器对未使用变量和导入包的错误检查。( 空标识符为预置成员不能重新定义 )
3. Constant
-
关键字“ const ”
-
可以指定常量的类型,也可以由编译器通过初始值判断
-
可以在函数代码块里定义常量,未被使用的常量不会引发编译错误
-
当显式指定常量类型时,需要保证左右值类型一致,必要时可以做显式转换。右值不能超过常量类型的取值范围,否则会引发溢出错误
-
常量值也可以是能通过计算得出的表达式,如unsafe.Sizeof、len、cap等
-
在常量组的定义中,如果即没有说明类型也没有给初始化值,那么该常量的类型和初始值与上一行的非空常量右值的表达式文本相同
-
golang中没有明确意义上的 enum 定义,但是可以借助 iota 标识符 实现一组自增常量值来实现枚举类型
-
当自增的作用范围为常量组时,可以在多常量定义中使用多个 iota ,他们之间各自单独技术,只需保证每一行常量的列数相同即可
-
中断常量自增只需要显式初始化下一行值
-
恢复常量自增则需要显式恢复,并且恢复时的自增值时按照行序递增,而非按上一行取值
-
自增的默认数据类型为 int (也可以显式指定自增类型)
-
在实际编码中,建议使用自定义类型实现用途明确的枚举类型,但这并不能将取值范围限定在预定义的枚举值之内
Qusetion:
What is the differences between constant and variable other than " read-only " ?
Answer:
-
变量在运行期分配并存储内存,而常量通常被编译器在预处理阶段就直接展开,作为指令数据使用
-
数字变量不会分配存储空间,无须像变量那样通过内存寻址来取值,因此无法获取地址
Attention:
-
无类型声明的变量,编译器会直接展开
-
显式指定类型的变量,编译器会做强类型检查
4. Basic Type:
-
支持二进制、八进制、十六进制、科学计数法表示
-
可用类似 math.MaxInt8/MinInt8定义个数字类型的取值范围
-
可用strconv 在不同进制的字符串之间转换
-
使用浮点数时需要注意小数点后的有效精度,相关细节可以参考IEEE-754的标准
alias 别名:
-
byte alias for uint8
-
rune alias for int32
-
别名类型无需转换,可以直接赋值
-
但不是说,具有相同的底层结构的类型就属于alias 别名,例如64位平台上的 int 和 int 64 结构完全一致但也属于不同的类型,需要显式转换
5. Reference Type:
-
在golang 中特指 slice、 map、 channel 这三种预定义类型
-
reference type 具有更加复杂的储存结构
-
reference type 除了分配内存以外,还需要初始化一系列属性,例如:指针、 长度、 哈希分布、数据队列等
-
内置 new 函数按照指定类型长度分配零值内存,返回指针,并不关心类型内部构造和初始化方式,所以 reference type 必须使用 make 函数创建,编译器会将 make 转换成为目标类型专用的创建函数(指令),以确保完成全部内存分配和相关内容初始化
Attention:
-
使用new 函数其实也可以为引用类型分配内存,但是这是不完整的创建,例如:使用 new 函数为字典(map)创建内存时,仅仅为字典类型本身(实际就是一个指针包装)分配了所需内存,并没有分配键值储存内存,也没有初始化散列桶等基础属性,因此使用 new 函数 为引用类型分配内存会导致无法正常工作
6. Type Conversion
-
隐式类型转换带来的问题远大于他的好处
-
除了常量、引用类型和未命名类型以外,在 golang 中,强制要求使用显式类型转换
-
由于这个规则,加上 golang 不支持操作符重载,所以我们总是能确定语句以及表达式的明确含义
-
不能将非 bool 类型的结果 当作 true/false 使用
-
如果 type conversion 的对象是指针、单向通道或者没有返回值的函数类型,那么必须使用括号,避免歧义造成语法分解错误
7. Custom Type
-
关键字 “ type ”
-
可以进行基于现有类型的创建、结构体、函数类型的创建等
-
和 var 、 const 类似,多个type定义可合并成组,可在函数或代码块内定义局部类型
Attention:
-
即使 custom type 指定了基础类型, 也只表明他们有相同的底层数据结构,该两者之间不存在任何关系,属于两种完全不同的类型,除了操作符外, custom type 不会继承基础类型的其他信息(包括方法),不能被视作别名、不能隐式转换、 不能直接用于比较表达式
Unnamed type or named type:
-
array 、 slice、 map、 channel 等类型与具体的元素类型以及长度有关,被称为 未命名类型 (unnamed type),使用 “ type ” 关键字 就可以将其转换为 命名类型 (named type)
-
具有相同声明的未命名类型会被视为同一类型
未命名类型转换规则: