Golang 学习笔记(三)——变量常量 基础类型

目录:

  • 类型列表
  • 标识符 & 关键字
  • 变量
  • 常量
  • 布尔类型 bool
  • 数值类型
  • 字符串类型
  • 错误类型型
  • 一些技巧(分组声明、枚举、运算符)

类型列表

类型 长度 零值 说明
bool 1 false true/false, 默认false
byte 1 0x0 uint8 别名
rune 4 0 int32 别名 代表一个 unicode code point
int/unit 0 与计算架构相关 32bit/64bit
int8/uint8 1 0; 0x0 -128 ~ 127; 0 ~ 255
int16/uint16 2 0 -32768 ~ 32767; 0 ~ 65535
int32/uint32 4 0 -21亿 ~ 21亿, 0 ~ 42亿
int64/uint64 8 0 -922亿亿 ~ 922亿亿, 0 ~ 1844亿亿
float32 4 0 精确到7位小数
float64 8 0 精确到15位小数
complex64 8 0
complex128 16 0
uintptr nil 指针(可以存指针的整数型)
array 元素为零值 值类型, 数组
struct type{} 值类型, 结构体
string “” 值类型, 字符串类型, 常用
slice nil 引用类型, 切片
map nil 引用类型, 字典
channel nil 引用类型, 通道
interface nil 接口类型, 接口
function nil 函数类型, 函数

基础类型

其中,Go 语言中的内置基础类型为:

  • 布尔型:bool
  • 数值型:
    • 整数型:int int64 int32(rune) int16 int8 uint8(byte) uint16 uint32 uint64 uint
    • 浮点型:float32 float64
    • 复数型:complex64 complex128
  • 字符串:string
  • 错误型:error

关于类型转换

不支持隐式类型转换,必须进行显式类型转换。
转换只发生在两种互相兼容的类型之间: 各类数值类型之间不允许相互赋值或操作,不然会在编译时报错。

1
<type>(expression)

标识符 & 关键字

标识符

在Go语言中,变量、常量、函数、结构体和接口被统称为“程序实体”,而它们的名字被统称为“标识符”。
标识符可以是任何 Unicode 编码可以表示的字母字符、数字以及下划线“_”,不能以数字或下划线开头。
注意:Go语言中,访问权限由名字首字母大小写来控制,首字母大写为 public,小写为包级私有。

关键字

用途 关键字
程序声明 import package
实体声明与定义 chan const func struct interface map type var
流程控制 break case continue default defer else fallthrough for go goto if import range return select switch

变量

变量声明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//第一种,指定变量类型,声明后若不赋值,使用默认值
var v_name v_type
v_name = value

//第二种,Go 会根据值自行推断变量类型
var v_name = value

//第三种,省略var, 注意 :=左侧的变量不应该是已经声明过的,否则会导致编译错误.
v_name := value

// e.g.
var a int = 10
var b = 10
c : = 10

多变量声明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//类型相同多个变量, 非全局变量
var vname1, vname2, vname3 type
vname1, vname2, vname3 = v1, v2, v3 // 平行赋值

var vname1, vname2, vname3 = v1, v2, v3 // 自动类型推断

vname1, vname2, vname3 := v1, v2, v3 //出现在:=左侧的变量不应该是已经被声明过的,否则会导致编译错误


//类型不同多个变量, 全局变量, 局部变量不能使用这种方式
var (
vname1 v_type1
vname2 v_type2
)

注意:

  • 多变量赋值时,将先行计算所有左侧变量的值,再进行赋值
  • 已声明但是没有使用的变量会在编译阶段报错
  • 对于不需要的变量,用_忽略, e.g.v, _ := func1()

常量

常量可以是字符,字符串,布尔或数字,常量赋值是编译期的行为。

1
2
3
4
5
6
7
8
9
10
11
12
13
const constantName = value
const Pi float32 = 3.1415926

const c_name [type] = value
const c_name1, c_name2 = value1, value2
const (
c_name1 = vluae1
c_name2 = value2
)

// =右侧,必须为常量或常量表达式,如果使用到了函数,必须为内置函数(编译期行为)

const i = 10000

注意
A.常量必须是编译期能确定的Number(char/integer/float/complex)、String和bool
B.在定义常量数组时,如果不提供初始化值,则表示与上行常量类型、值,完全相同,例如

1
2
3
4
5
const (
a = "abc"
b
)
//则 b = "abc"

C.常量可以用len,cap,unsafe.Sizeof()常量计算表达式的值. 常量表达式中,函数必须是内置函数,否则编译不过

bool

Go 语言中,不尔类型为 bool,值是 true 或 false,默认为 false。不能把非0值当做 true。

1
2
var isActive bool // 全局变量声明
var enabled, disabled = true, false // 忽略类型的声明

数值类型

整数类型有无符号和带符号两种。Go 中的整数类型有 int, int8, int16, int32, int64, rune 和 byte, uint8, uint16, uint32, uint64。其中 rune 是 int32 的别称,byte 是 uint8 的别称。
这些类型变量之间不允许相互赋值或操作,不然会在编译时报错。尽管 int 的长度也是 int32,但他俩也不可互用。
浮点数有 float32 和 float64 两种,默认为 float64。
Go 语言还支持复数,默认为 complex128。

byte 与 rune

byterune都属于别名类型,byteuint8的别名类型,而rune则是int32的别名类型。
byte类型的值需用8个比特位表示,其表示法与uint8类型无异。
一个rune类型的值即可表示一个 Unicode 字符。用于代表 Unicode 字符的编码值也被称为 Unicode 代码点。一个 Unicode 代码点通常由“U+”和一个以十六进制表示法表示的整数表示。例如,英文字母“A”的 Unicode 代码点为“U+0041”。
rune类型的值需要由单引号'包裹。例如'A'。这种表示方法一目了然。还有其他几种形式表示rune类型值,但都不常用,不再赘述。

字符串类型

Go 语言中的字符串都是采用 UTF-8 字符集编码。字符串是用一对双引号(””)或反引号(``)括起来定义,分别是解释型表示法和原生表示法。二者的区别是,前者表示的值是所见即所得的(除了回车符)。在那对反引号之间的内容就是该字符串值本身。而后者所表示的值中的转义符会起作用并在程序编译期间被转义。
字符串值是不可变的,这点和 Java 中字符串类似。我们一旦创建了一个此类型的值,就不可能再对它本身做任何修改。(可以通过将 string 转为 []btye 再转回 string 的方式实现)
注意,我们在一个字符串值或者一个字符串类型的变量之上应用 Go 语言的内置函数len将会得到代表它的那个字节数组的长度。这可能与我们看到的表象是不同的。

错误类型

error 类型实际上是抽象了 Error() 方法的 error 接口,Golang 使用该接口进行标准的错误处理。

1
2
3
type error interface {
Error() string
}

可以自己实现这个接口,也可以使用 errors 包

1
var e error = errors.New("error message")

一般情况下,如果函数需要返回错误,就将 error 作为多个返回值中的最后一个(但这并非是强制要求)。参考模型:

1
2
3
4
5
6
func Foo(param int) (n int, err error) {
// ...
}
if n, err := Foo(0); err != nil {
// 错误处理
}

一些技巧

分组声明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import (
"fmt"
"os"
)

const (
i = 100 //首行必须有常量表达式
pi = 3.1415
)

var ( //全局变量可用,函数体内不支持
i int
pi float32
)

枚举

iota,特殊常量,可以认为是一个可以被编译器修改的常量
在每一个const关键字出现时,被重置为0,然后再下一个const出现之前,每出现一次iota,其所代表的数字会自动增加1。如不提供初始值,则表示使用上一行的表达式。
iota生成从0开始的自动增长枚举值,意味着,多一个枚举值,iota+=1,无论是否使用

基本语法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const (
a = 1
b = 2
)

const (
a = iota //0
b //1
c //2
)

const (
_ = iota
a //1
b //2
)

iota用法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
func main() {
const (
a = iota //0
b //1
c //2
d = "ha" //独立值,iota += 1
e //"ha" iota += 1
f = 100 //iota +=1
g //100 iota +=1
h = iota //7,恢复计数
i //8
)

}

const (
x = iota // 0
y = iota // 1
z = iota // 2
w //省略,默认和前面一样字面值 w = iota, 即3
)
const v = iota //遇到const关键字,iota重置

注意: 每行的变量数必须一致 const ( A, B = iota, iota C, D E, F )

1
2
3
4
5
func main() {
println(A,B,C,D,E,F)
}

//结果: 0 0 1 1 2 2 【各自增长】

运算符

Go运算符全部是从左到右结合的,不支持运算符重载。

1
2
3
4
5
6
7
优先级    运算符                        说明
高 * / % << >> & &^(AND NOT)
+ - ! ^
== != < <= > >=
<- channel运算符
&&
低 ||

在go中,++--为语句,而非表达式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package main

func main(){
i := 1
i ++
println(i)

b := i
println(b)

//syntax error: unexpected ++, expecting semicolon or newline or }
//c := i++
//意味着, ++/--不能出现在等号右侧
}

参考资料:
谢大的《Go Web 编程》
wklken 的 Golang 笔记