变量
:::info
我们去声明变量,要尽量简洁
(变量的声明尽量简化,使用简单的语句,go 2.0版本作者希望会删除掉一些过于花式的语言声明,我们自己要有所准备)
:::
声明/初始化
单个变量 | 多个变量 | ||
---|---|---|---|
var |
只声明 | <font style="color:rgb(0, 0, 136);">var</font><font style="color:rgb(0, 0, 0);"> v_name v_type</font> |
1. 不同变量同一类型: <font style="color:rgb(0, 0, 136);">var</font><font style="color:rgb(0, 0, 0);"> v_name1</font><font style="color:rgb(102, 102, 0);">,</font><font style="color:rgb(0, 0, 0);"> v_name2 v_type</font> 2. 不同变量不同类型(一般用于函数外): |
初始化 | <font style="color:rgb(0, 0, 136);">var</font><font style="color:rgb(0, 0, 0);"> v_name </font><font style="color:rgb(102, 102, 0);">=</font><font style="color:rgb(0, 0, 0);"> value</font> 解释: 系统借助初始化的值,可自动判断类型,无需声明,不过你要写上也行 |
||
:= |
初始化 | <font style="color:rgb(51, 51, 51);">a := 50 </font> |
<font style="color:rgb(0, 0, 0);">a</font><font style="color:rgb(102, 102, 0);">,</font><font style="color:rgb(0, 0, 0);"> b</font><font style="color:rgb(102, 102, 0);">,</font><font style="color:rgb(0, 0, 0);"> c </font><font style="color:rgb(102, 102, 0);">:=</font><font style="color:rgb(0, 0, 0);"> </font><font style="color:rgb(0, 102, 102);">5</font><font style="color:rgb(102, 102, 0);">,</font><font style="color:rgb(0, 0, 0);"> </font><font style="color:rgb(0, 102, 102);">7</font><font style="color:rgb(102, 102, 0);">,</font><font style="color:rgb(0, 0, 0);"> </font><font style="color:rgb(0, 136, 0);">"abc"</font> (c语言是不可这样的) |
要求
- 不可重复声明,可重复赋值
- 类型上
- 省略
若初始化,有值了,类型不必声明,若仅仅只是初始化,则要求声明变量类型 - 同行声明/初始化
<font style="color:rgb(0, 0, 136);">var</font><font style="color:rgb(0, 0, 0);"> v_name1</font><font style="color:rgb(102, 102, 0);">,</font><font style="color:rgb(0, 0, 0);"> v_name2 v_type</font>
必须同类型
- 省略
- 声明与使用
- 若声明(甚至初始化)了某一局部变量,没被使用,在编译阶段的时候就会跟你报错
- 若声明(甚至初始化)了某一全局变量,没被使用,是允许的
- 函数外声明
函数外的每个语句都必须以关键字开始(**var、const**、func等),故**:=**
不能使用在函数外。
**常用:因式结果写法
**
特殊说明
匿名变量
在使用多重赋值时,如果想要忽略某个值,可以使用匿名变量(anonymous variable)。 匿名变量用一个下划线_表示,例如:作用:_多用于占位,表示忽略值。 匿名变量不占用命名空间,不会分配内存,所以匿名变量之间不存在重复声明。 (在Lua等编程语言里,匿名变量也被叫做哑元变量。)
func foo() (int, string) {
return 10, "Q1mi"
}
func main() {
x, _ := foo()
_, y := foo()
fmt.Println("x=", x)
fmt.Println("y=", y)
}
零值问题
零值是什么? | ||
---|---|---|
基本类型 | 布尔 | false |
数值类型 | 包括: 整数(包含:int与uint、显式整型、字符byte和rune)、浮点数(float32或者float64)、虚数(complex64或complex128)、uintptr 零值都为0 Note: 1. 对于字符来说,确实是0,而非 '' 2. 对于浮点数,则是 0.0 (可能也只是显是0)3. 对于虚数,则是 0+0i 4. uintptr的零值也为 0 ,只是从未用过 |
|
字符串 | "" |
|
聚合类型 | 值类型(没有引用) | 包括:数组、结构体 零值,会对应着定义的类型,比如数组 [2]int 的零值就为[0,0] Note:严格上来说,值类型包括基本类型+数组和结构体,可以认为为零值都是0,只是会在表现形式上有点偏差 |
引用类型 | 包括:slice、map、channel、interface、function函数 零值都为nil(而非C/C++ NULL。作用是等价的) Note:只有初始化后(new和make函数),才可使用 |
:::success 具体
:::
- 整型
- int, int8, int16, int32, int64:默认值为 0
- uint, uint8, uint16, uint32, uint64, uintptr:默认值为 0
- 浮点型
- float32, float64:默认值为 0.0
- 复数类型
- complex64, complex128:默认值为 (0+0i)
- 布尔型
- bool:默认值为 false
- 字符串
- string:默认值为 “”(空字符串)
聚合类型
- 数组
- 各元素的零值。例如,一个 int 类型的数组,其元素默认值为 0。
- 结构体
- 各字段的零值。例如,一个包含 int 和 string 字段的结构体,其字段默认值分别为 0 和 “”。
引用类型
- 指针
- 各类型指针:默认值为 nil
- 切片
- slice:默认值为 nil
- 映射
- map:默认值为 nil
- 通道
- chan:默认值为 nil
- 接口
- interface:默认值为 nil
- 函数
- 各类型函数:默认值为 nil
与其他语言差异
- 声明
- go语言:只有四种声明:
**<font style="color:#AD1A2B;">var</font>**<font style="color:#AD1A2B;">(声明变量), </font>**<font style="color:#AD1A2B;">const</font>**<font style="color:#AD1A2B;">(声明常量), type(声明类型) ,func(声明函数)</font>
(短变量**<font style="color:#AD1A2B;">:=</font>**
包括在var中),且可以通过赋值进行自动类型推断(如果只是声明,则需要标明类型) - c语言:通过类型来声明变量,类型写在前面,
int/float/double/char a;
- go语言:只有四种声明:
- 可一个赋值语句对多个变量进行赋值,比如
- 交换两个变量,a, b = b, a,但两个变量的类型必须是相同
- 初始化——
<font style="color:rgb(0, 0, 0);">a</font><font style="color:rgb(102, 102, 0);">,</font><font style="color:rgb(0, 0, 0);"> b</font><font style="color:rgb(102, 102, 0);">,</font><font style="color:rgb(0, 0, 0);"> c </font><font style="color:rgb(102, 102, 0);">:=</font><font style="color:rgb(0, 0, 0);"> </font><font style="color:rgb(0, 102, 102);">5</font><font style="color:rgb(102, 102, 0);">,</font><font style="color:rgb(0, 0, 0);"> </font><font style="color:rgb(0, 102, 102);">7</font><font style="color:rgb(102, 102, 0);">,</font><font style="color:rgb(0, 0, 0);"> </font><font style="color:rgb(0, 136, 0);">"abc"</font>
常量
常量是一个简单值的标识符,在程序运行时,不会被修改的量。 常量中的数据类型只可以是基本类型:布尔型、数字型(整数型、浮点型和复数)和字符串型。语法
- 基本语法:
<font style="color:rgb(0, 0, 136);">const</font><font style="color:rgb(0, 0, 0);"> identifier </font><font style="color:rgb(102, 102, 0);">[</font><font style="color:rgb(0, 0, 0);">type</font><font style="color:rgb(102, 102, 0);">]</font><font style="color:rgb(0, 0, 0);"> </font><font style="color:rgb(102, 102, 0);">=</font><font style="color:rgb(0, 0, 0);"> value</font>
与var相同,只是把var换成const - 多个变量(也与var相同)
1.
<font style="color:rgb(0, 0, 136);">const</font><font style="color:rgb(0, 0, 0);"> c_name1</font><font style="color:rgb(102, 102, 0);">,</font><font style="color:rgb(0, 0, 0);"> c_name2 </font><font style="color:rgb(102, 102, 0);">=</font><font style="color:rgb(0, 0, 0);"> value1</font><font style="color:rgb(102, 102, 0);">,</font><font style="color:rgb(0, 0, 0);"> value2</font>
2. 或者
const (
Unknown = 0
Female = 1
Male = 2
)
:::info NOTE:与c语言的差异
:::
c语言的枚举看下方,用的enum和花括号,且还要求定义枚举变量
c语言定义常量(用于对比)
:::info 天然常量
:::
实例 | ||
---|---|---|
整数常量 | 520, 1314, 123 | |
浮点常量 | 3.14, 5.12, 8.97(实数 ) | |
字符常量 | 1. 要求:括在单引号中 2. 分类: 普通字符:’L’, ‘o’, ‘v’, ‘e’ 转义字符:’\n’, ‘\t’, ‘\b’ 通用的字符(例如 ‘\u02C0’) |
|
字符串常量 | 1. “FishC”(字符用单引号,字符串用双引号,多个字符穿起来,以 ‘\0’ 结束=字符串,python中单双引号共同相同,内嵌的时候会要求不一样而已) 2. 分隔 比如下面这三种形式所显示的字符串是相同的 |
:::info 定义常量
:::
宏定义 | const关键字 | 枚举常量 | |
---|---|---|---|
作用 | 使得程序变得直观,但编译时不会报错,只有运行时会错,建议少使用 | 保护变量,使其变成变常量,如果变量值不怎么变建议使用 | 使得程序变得直观,是一种特殊的整型(这也是局限性) |
语法区别 | #define 宏 替换体 写在开头,很像 #include <stdio.h> |
像个副词,可修饰类型,可修饰指针,但要求声明和赋值一起完成,也就是只能初始化 1. const int LENGTH = 10; 2. 指针 |
类似结构 具体省略啥的自己看枚举那章 |
?iota
- 是什么?——特殊常量,可以认为是一个可以被编译器修改的常量。
- 使用条件
1. 只在常量表达式中使用(
<font style="color:rgb(51, 51, 51);">const(...)</font>
) - 什么时候用的上? 1. ???教程上说定义枚举常量会比较有用,但是go语言哪来的枚举常量,还没实地用过
- 怎么用?
- 初始值:iota 在 const关键字出现时将被重置为 0(const 内部的第一行之前),
- 怎么计数
- 次数:
**iota的计数=**const 中每新增一行常量声明将使 iota 计数一次
(iota 可理解为 const 语句块中的行索引)。 - 实例分析:开头iota=0,i**ota计数模式默认+1,但也可以不是简单的+1,见实例2
**
- 次数:
NOTE:
左移运算符”<<”是双目运算符。左移n位就是乘以2的n次方。
右移运算符”>>”是双目运算符。右移n位就是除以2的n次方。 3. 多个iota定义在一行3. 可插队(=可独立设置值)
itoa开始计数→插队,设置独立值→用iota恢复计数(注意,实例恢复到7,而不是3,暗指其实即使被插队,itoa依然根据每行的声明,暗中计数)