1. 包、变量和函数
(一)每个 Go 程序都由包构成
程序从 main 包开始运行。
本程序通过导入路径 "fmt" 和 "math/rand" 来使用这两个包。
按照约定,包名与导入路径的最后一个元素一致。例如,"math/rand" 包中的源码均以 package rand 语句开始。
Go1 2package main3 4import (5 "fmt"6 "math/rand"7)8 9func main() {10 fmt.Println("我最喜欢的数字是 ", rand.Intn(10))11}
(二)导入
导入方式相当于JS ,用圆括号将导入的包分成一组,这是“分组”形式的导入语句。
示例:
Go1 2import "fmt"3import "math" //多个导入语句导入方式4 5import (6 7"ejs"8"expole"9 10 )
不过使用分组导入语句要更好。
(三)导出名
导出名这个点和JS有很大差距,导入的包都有一个或多个导出名,导出名必须为大写 。 同时,在导入一个包时,你只能引用其中已导出的名字。 任何「未导出」的名字在该包外均无法访问。
(四)函数
函数和TS的函数比较相似,都是由定义func+函数名+返回值+函数体构成
这是官方网站的定义:函数可接受零个或多个参数。
ps:注意类型是在变量的后面。
同时,当连续两个或多个函数的已命名形参类型相同时,除最后一个类型以外,其它都可以省略。
与JS/TS不同的是,Go的函数能返回多个值,定义方式是圆括号包裹返回值的类型,同时返回值使用return。获取返回值并赋值的方式也有些许不同
示例:
Go1 2package main3 4import "fmt"5 6func add(x int, y int) int {7 return x + y8}9func divide(x,y int) int {10return x-y11}12func getString (x,y string) (string,string) {13return y,x 14}15 16 17func main() {18 a,b :=getString("nihao",“你好”)19 20 fmt.Println(add(42, 13))21}
特殊的Go的返回值可以被命名,他们会被视为直接在函数顶层进行定义。我们约定俗成的将返回值的命名定义成能反映返回值含义的命名。同时返回值能被当成文档使用。
同时,没有参数的 return 语句会直接返回已命名的返回值,也就是「裸」返回值。
注意:裸返回语句应当仅用在下面这样的短函数中。在长的函数中它们会影响代码的可读性
Go1 2package main3 4import "fmt"5 6func split(sum int) (x, y int) {7 x = sum * 4 / 98 y = sum - x9 return10}11 12//等价于13 14func split(sum int) (int,int){15 x :=sum *4 /916 y := sun-x17 return x,y18}19 20func main() {21 fmt.Println(split(17))22}
(五)变量
变量的定义方式和commonJS很相似,都是使用var进行定义和声明,和函数的参数列表一样,类型在最后。同时var的使用区域可以是在包层级也可以是在函数层级。
Go1package main2 3import "fmt"4 5var c, python, java bool6 7func main() {8 var i int9 fmt.Println(i, c, python, java)10}
同样的,初始化变量的方式也和JS相似。和TS相似,如果给予了变量初始值,将会自动推断变量的类型,可以省略变量的类型定义。
Go1 2package main3 4import "fmt"5 6var i, j int = 1, 2 //声明并赋值7 8func main() {9 var c, python, java = true, false, "no!"10 fmt.Println(i, j, c, python, java)11}
短变量声明方式:在函数那一块中,示例使用了:=的方式进行声明并赋值,这就是短变量声明方式。但简单归简单短变量声明还是有许多限制的,如:在函数中,短赋值语句 := 可在隐式确定类型的 var 声明中使用。函数外的每个语句都 必须 以关键字开始(var、func 等),因此 := 结构不能在函数外使用。也就是包层级无法使用短变量声明方式
Go1package main2 3import "fmt"4 5func main() {6 var i, j int = 1, 27 k := 38 c, python, java := true, false, "no!"9 10 fmt.Println(i, j, k, c, python, java)11}
踩坑点注意:在 Go 中,是允许在函数内部使用函数字面量(function literals)的方式来定义一个函数。但是,使用这种方式定义函数时,不允许使用函数名。也就是说
Go1func main() {2// func any (face int) int { 这种情况是不允许的3//return face4//}5//正确的声明方式6any :=func (face int ) int {7return face8}9}
(六)变量的基本类型
1.bool 布尔类型 2.string 字符串类型 3.int 整型 家族有:int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64 uintptr 4.byte 字节,也就是uint8的别名 5.rune 表示一个unicode码位,也就是int32的别名 6.float 浮点数 家族有:float32 float64 7.complex64 32位实数或者虚数 complex128 64位实数或虚数
在我们直接声明一个变量但没有对它进行赋值的时候,Go会自动给这个变量添加零值(万恶的JS,万恶的undefined),零值的值是根据声明对象时的类型决定的,数值类型为0、布尔类型为false,字符串为“”(空串)。
(七)类型转换
在Go中类型转换需要显式的使用表达式T(v)将值v转换为类型T。 转换示例:
Go1var i int = 422var f float64 = float64(i)3var u uint = uint(f)
或者使用短变量声明方式进行转化
Go1i := 422f := float64(i)3u := uint(f)
(八)类型推断
类型推断的方式和TS相似,但是有一部分区别。
当右边包含未指明类型的数值常量时,新变量的类型就可能是 int、float64 或 complex128 了,这取决于常量的精度:
Go1package main2 3import "fmt"4 5func main() {6 v := 42.123+0.5i 7 fmt.Printf("v is of type %T\n", v)//v is of type complex1288}
(九)常量
常量的声明方式和JS相似,都是使用const关键字进行定义,但是唯一需要注意的是,常量不能使用:=短变量声明方式进行声明。
数值常量是高精度的值,一个未指定类型的常量由上下文来决定其类型。