给大家推荐一款曾经风靡一时的休闲娱乐小游戏——2048
只要我们下载安装了Go,就可在开发环境下的终端内直接输入下列命令,就可启动游戏:
go run github.com/hajimehoshi/ebiten/v2/examples/2048@latest
回归正题 让我们继续来回顾GO语言基础语法
1. Go 变量
1.1 变量是什么?
变量来源于数学,是计算机语言中能储存计算结果或能表示值的抽象概念,变量可以通过变量名访问,但不同的变量保存的 数据类型 可能会不一样。
1.2 变量的定义
声明变量的一般形式是使用var
关键字:var identifier type
var
: 关键字,表示声明变量identifier
: 变量名字Type
:数据类型,这是一种抽象表示,仅作文档说明,代表任意类型
当然也可以,一次声明多个变量,如:var identifier1, identifier2 type
package main
import "fmt"
func main() {
var a string = "Runoob"
fmt.Println(a)
var b, c int = 1, 2
fmt.Println(b, c)
}
/*以上实例输出结果为:1 2 */
提示:
Go语言中的变量需要 声明后才能使用,同一作用域内不支持重复声明。 并且Go语言的变量 声明后必须使用。
1.3 变量名的命名规则
Go 语言变量名由字母、数字、下划线组成,其中首个字符不能为数字。
所谓 变量名 就是程序中预先分配好的 固定大小的内存区域,在 Go 中可以想象它是一个 抽屉,将数据内容存放在其中。而变量名的内存区域的大小则是由它的 数据类型 所确定。
补充:
- 名称只能包含字母 数字 字符和 下划线(
a-z
、A-Z
、0-9
和_
) - 名称是 区分大小写(
age
、Age
和AGE
是三个不同的变量) - 名称是 没有长度限制
- 名称中 不能包含空格
- 名称 不能是任何 Go关键字
因为有些 变量名被编程语言赋予了特殊的含义,它们作为其语言的重要组成部分被称为 关键字 或 保留字。这些名字是不能用于变量的命名。
Go语言中有 25 个关键字 :
1. | break | default | func | interface | select |
---|---|---|---|---|---|
2. | case | defer | go | map | struct |
3. | chan | else | goto | package | switch |
4. | const | fallthrough | if | range | type |
5. | continue | for | import | return | var |
此外,Go 语言中还有 37 个保留字 :
常量: true false iota nil
数据类型: int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64 uintptr float32 float64
complex128 complex64 bool byte rune string error
内置函数: make len cap new append copy close delete complex real imag panic recover
package main
import "fmt"
func main() {
var name string
var age int
var _sys int
}
除此之外,包含多个单词的变量名可能难以阅读,使用一些技巧来提高可读性。
- 驼峰命名法——除了第一个单词,每个单词都以大写字母开头 :
myVariavleName := "John"
- 帕斯卡命名法——每个单词都以大写字母开头 :
MyVariableName := "John"
- 蛇形命名法——每个单词由一个下划线字符分隔 :
my_variable_name := "John"
多变量声明 :使用一个 var
关键字,把一些变量写在一个括号()
里
//类型相同多个变量, 非全局变量
var vname1, vname2, vname3 type
vname1, vname2, vname3 = v1, v2, v3
var vname1, vname2, vname3 = v1, v2, v3 // 和 python 很像,不需要显示声明类型,自动推断 vname1, vname2, vname3 := v1, v2, v3 // 出现在 := 左侧的变量不应该是已经被声明过的,否则会导致编译错误
// 这种因式分解关键字的写法一般用于声明全局变量
var (
vname1 v_type1
vname2 v_type2
)
package main
import "fmt"
var x, y int
var ( // 这种因式分解关键字的写法一般用于声明全局变量
a int
b bool
)
var c, d int = 1, 2
var e, f = 123, "hello"
//这种不带声明格式的只能在函数体中出现
//g, h := 123, "hello"
func main(){
g, h := 123, "hello"
fmt.Println(x, y, a, b, c, d, e, f, g, h)
}
/*以上实例执行结果为:0 0 0 false 1 2 123 hello 123 hello */
1.4 变量的初始化
第一种,指定变量类型,如果没有初始化,则变量默认为零值。
零值就是变量没有做初始化时系统默认设置的值。
Go语言在声明变量的时候,会自动对变量对应的内存区域进行初始化操作。每个变量会被初始化成其类型的默认值,例如:
- 整型和浮点型变量的默认值为
0
- 字符串变量的默认值为空字符串
""
- 布尔型变量默认为
false
- 切片、函数、指针变量的默认为
nil
初始化 标准语法 如下: var identifier Type - value
package main
func main() {
// 变量的初始化
var name string = "杜宇鹏"
var age int = 28
}
第二种,根据值自行判定变量类型。
如果提供初始值,编译器可以自动从初始值中获取类型信息
package main
func main() {
var name = "杜宇鹏"
var age = 28
var ok = true
}
也可以初始化多个变量,让编译器进行类型推导,一次初始化多个变量
package main
func main() {
/*多变量初始化*/
var name, age, ok = "杜宇鹏", 28, true
}
第三种,如果变量已经使用 var 声明过了,再使用:=声明变量,就产生编译错误。
格式: v_name := value
在 函数内部,可以使用 :=
运算符对变量进行声明和初始化
package main
func main() {
/*短变量声明*/
name := "杜宇鹏"
age := 28
ok := true
}
该声明,必须在函数内部。并且必须提供初始值。不提供初始值是不可能进行变量声明的
但当
var intVal int intVal :=1
这时候会产生编译错误,因为 intVal 已经声明,不需要重新声明
直接使用下列语句即可:
intVal := 1
此时不会产生编译错误,因为有声明新的变量,因为 :=
是一个声明语句。
intVal := 1
相等于:
var intVal int
intVal =1
第四种,匿名变量。
如果我们需要接收到多个值,有一些值使用不到,可以使用 下划线 _ 表示变量名称,这种变量叫做 匿名变量
package main
import "fmt"
func getNameAndAge() (string, int) {
return "杜宇鹏", 30
}
func main() {
/* 使用匿名变量忽略值 */
name, _ := getNameAndAge()
fmt.Printf("name: %s\n", name)
}
但后续我们也无法使用 _
获取值,它就像粉碎机一样,将数据毁灭了。
2. Go 常量
2.1 常量是什么?
常量是一个简单值的标识符,在程序运行时,不会被修改的量。
常量中的数据类型只可以是布尔型、数字型(整数型、浮点型和复数)和字符串型。
可以使用 const
关键字。
2.2 常量的定义
const
关键字 将变量声明为 只读意味着它是 不可更改且只读的。语法格式如下:
const CONSTNAME Type = value
注意,常量的值必须在声明时赋初始值,声明完成之后不允许修改。
Go 常量的声明与变量非常相似。区别在于声明常量使用 const
关键字,并且在声明时就必须初始化
-
显式类型定义:
const b string = "abc"
-
隐式类型定义:
const b = "abc"
(编译器可以根据变量的值来推断其类型)
多个相同类型的声明可以简写为: const c_name1, c_name2 = value1, value2
package main
import "fmt"
func main() {
const LENGTH int = 10
const WIDTH int = 5
var area int
const a, b, c = 1, false, "str" //多重赋值
area = LENGTH * WIDTH
fmt.Printf("面积为 : %d", area)
println()
println(a, b, c)
}
/* 以上实例运行结果为:
面积为 : 50
1 false str
*/
常量还可以用作枚举:
const (
Unknown = 0
Female = 1
Male = 2
)
数字 0、1 和 2 分别代表未知性别、女性和男性。
const
同时声明多个常量时,如果省略了值则表示和上面一行的值相同
package main
import "fmt"
const (
k = 1 // 开始值
m // 默认为上一项 k 的值 1
g
t = 2 // 新的值
p // 默认为上一项 t 的值 2
q
)
func main() {
fmt.Println(k, m, g, t, p, q) // 1 1 1 2 2 2
}
常量可以用len(), cap(), unsafe.Sizeof()函数计算表达式的值。常量表达式中,函数必须是内置函数,否则编译不过:
package main
import "unsafe"
const (
a = "abc"
b = len(a)
c = unsafe.Sizeof(a)
)
func main(){
println(a, b, c)
}
/* 以上实例运行结果为:abc 3 16 */
2.3 iota
iota,特殊常量,可以认为是一个可以被编译器修改的常量。
iota 在 const关键字出现时将被重置为 0(const 内部的第一行之前),const 中每新增一行常量声明将使 iota 计数一次(iota 可理解为 const 语句块中的行索引)。
iota 可以被用作枚举值:
const (
a = iota
b = iota
c= iota
)
第一个 iota 等于 0,每当 iota 在新的一行被使用时,它的值都会自动加 1;所以 a=0, b=1, c=2 可以简写为如下形式:
const (
a = iota
b
c
)
iota 用法
package main
import "fmt"
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
)
fmt.Println(a,b,c,d,e,f,g,h,i)
}
/*以上实例运行结果为:0 1 2 ha ha 100 100 7 8 */
看个有趣的的 iota 实例:
package main
import "fmt"
const (
i=1<<iota
j=3<<iota
k
l
)
func main() {
fmt.Println("i=",i)
fmt.Println("j=",j)
fmt.Println("k=",k)
fmt.Println("l=",l)
}
/* 以上实例运行结果为:i= 1 j= 6 k= 12 l= 24 */
iota 表示从 0 开始自动加 1,所以 i=1<<0, j=3<<1( << 表示左移的意思),即:i=1, j=6,这没问题,关键在 k 和 l,从输出结果看 k=3<<2,l=3<<3。
简单表述:
- i=1:左移 0 位,不变仍为 1。
- j=3:左移 1 位,变为二进制 110,即 6。
- k=3:左移 2 位,变为二进制 1100,即 12。
- l=3:左移 3 位,变为二进制 11000,即 24。
注意: <<n == *(2^n)