这是我参与「第五届青训营 」伴学笔记创作活动的第 1 天
本文会整理Go语言中的语法点/注意事项/冷知识等等内容,并尽量给出证明以及示例代码。
变量声明与导包
1、如果代码中存在未使用的变量或者导入的包,则无法通过编译。不过全局变量可以只声明而不使用
package main
// "sort" imported but not used
import "sort"
// 无报错
var all int
func main() {
// local declared but not used
var local int
}
2、导入同一个 module 下的其他包时,会以模块名(即 go.mod 里的module [name] 这个 name)作为根目录
go.mod内容
module note
go 1.18
导入的pkg包的代码
package pkg
import "fmt"
func init() {
fmt.Println("init")
}
func Fun() {
fmt.Println("pkg Fun!")
}
导入该项目目录下的pkg包(文件夹)
import "note/pkg" // 只会执行包里的 init() 函数
func main() {
pkg.Fun()
}
3、特殊导包的模式有三种
- 起别名
- 只进行初始化
- 不写包名即可调用,类似静态导包
package main
import (
f "fmt" // 起另一个名字,但是这样原来的包名会不可用
_ "note/pkg" // 只会执行包里的 init() 函数
. "math" // 调用包里的函数等时可以不写包名
)
func main() {
f.Println("Another fmt")
//fmt.Println("fmt") // undeclared name: fmt
f.Printf("Max(1.2, 1.3): %v\n", Max(1.2, 1.3)) // 调用Max()无需写包名
}
执行结果
init
Another fmt
Max(1.2, 1.3): 1.3
4、可以使用简短声明来给已声明的变量赋值,但这需要 := 的左边必须有一个新声明的变量
package main
import "fmt"
func main() {
a := 0
fmt.Println(&a, ":", a)
a, b := 1, 2
// a, _ := 1, 2 // no new variables on left side of :=
fmt.Println(&a, ":", a)
fmt.Println(b)
}
结果:
0xc000012098 : 0
0xc000012098 : 1
2
这说明两个 a 的地址相同,是同一个变量
这个特性用的最多的地方当然是 Go 比较著名的异常处理 if err != nil 的前一句(即接收函数返回值时)
func main() {
i1, err := divide(6, 3)
if err != nil {
fmt.Println(err.Error())
}
fmt.Println("result1:", i1)
fmt.Println(&err) // 0xc000054250
i2, err := divide(1, 0)
if err != nil {
fmt.Println(err.Error())
}
fmt.Println("result1:", i2)
fmt.Println(&err) // 0xc000054250
}
func divide(divisor, dividend int) (int, error) {
if dividend == 0 {
return 0, errors.New("被除数不能为零")
}
return divisor / dividend, nil
}
结果两个 err 的地址也是相同的
5、Go中的字符类型 rune 基本等价于 int32
类型定义
type rune = int32
rune is an alias for int32 and is equivalent to int32 in all ways. It is used, by convention, to distinguish character values from integer values.
输出字符变量的变量类型
func main() {
c := 'a'
fmt.Printf("%T", c) //int32
}
字符串相关
1、Go 的内置函数 len() 返回的是字符串的 byte 数量,如果要获取中文字符串的中文字数,可以转换成 []rune 再用 len() 获取
func main() {
s := "对的。"
fmt.Println(len(s)) //9
fmt.Println(len([]byte(s))) //9
fmt.Println(len([]rune(s))) //3
}
结果解释:在UTF-8编码中,一个中文字符等于三个字节,一个中文标点符号占三个字节。
2、string 类型的变量值不能为 nil
和Java以及C++不同,Go中的string是基本数据类型,string 的空值是 ""。
var s string = nil //cannot use nil as string value in variable declaration
冷知识
1、go 语言里的关键字可以做为变量名,但是并不推荐
func main() {
true := false
fmt.Println(true) //false
}