一.包
1.1 包
在Go
语言里,一个文件就是一个包(如果我没理解错的话)。Go
语言会从package main
开始运行。
按照约定,包名与导入路径的最后一个元素一致。例如,“math/rand” 包中的源码均以 package rand 语句开始。
也就是说我们这样引入包,那使用就应该是这样的(和Python
很像):
package main
import (
"fmt"
"math/rand"
)
func main() {
fmt.Println("My favorite number is", rand.Intn(10))
}
1.2 导入
你可以单行导入:
import "fmt"
import "math"
当然也可以多行导入:
import (
"fmt"
"math"
)
对于一个项目来说,可以把用于开发同一个子模块的功能放在一起,这样可以便于管理。
1.3 导出
当标识符(包括常量、变量、类型、函数名、结构字段等等)以一个大写字母开头,如:Group1,那么使用这种形式的标识符的对象就可以被外部包的代码所使用(客户端程序需要先导入这个包),这被称为导出(像面向对象语言中的 public);标识符如果以小写字母开头,则对包外是不可见的,但是他们在整个包的内部是可见并且可用的(像面向对象语言中的 protected )。
比如合法的π: fmt.Println(math.Pi)
和非合法的π: fmt.Println(math.pi)
二.函数
2.1 参数
go
函数的返回值
是在参数
的后面
,{
的前面,例如:
func add(x int, y int) int {
return x + y
}
当然,还可以批量指定参数类型。当连续两个或多个函数的已命名形参类型相同时,除最后一个类型以外,其它都可以省略。
func add(x, y int) int {
return x + y
}
尝试:
package main
import "fmt"
func show(x,y int, name string) {
fmt.Println(x + y)
fmt.Println(name)
}
func main() {
show(1, 2, "kanna")
}
// 输出
// 3
// kanna
嗯,居然可以这样,看来和Python和C++还是有差别的。可能因为类型关键字放后面的缘故吧。
2.2 返回值
返回可以多值返回的:
package main
import "fmt"
func swap(x,y int) (int, int) {
return y, x
}
func main() {
var a, b int = 1, 2
fmt.Print(a, b, " ")
swap(a, b)
fmt.Print(a, b)
}
// Output: 1 2 1 2
果然是交换的形参
2.3 默认返回值
这个就像Matlab
一样:
package main
import "fmt"
func split(sum int) (x, y int) {
x = sum * 4 / 9
y = sum - x
return
}
func main() {
fmt.Println(split(17))
}
三.变量
3.1 变量
package main
import "fmt"
var c, python, java bool
func main() {
var i int
var b = 2
fmt.Println(i, c, python, java, b)
}
// OutPut:0 false false false 2
3.2 变量的初始化
变量声明可以包含初始值,每个变量对应一个。
如果初始化值已存在,则可以省略类型;变量会从初始值中获得类型。
就像2.1
的例子一样
3.3 短变量初始化
在函数
中,简洁赋值语句 := 可在类型明确
的地方代替 var 声明。
函数外的每个语句都必须以关键字开始(var, func 等等),因此 := 结构不能在函数外使用。
package main
import "fmt"
func main() {
var i, j int = 1, 2
k := 3
c, python, java := true, false, "no!"
}
3.4 变量的基本类型
Go
里面的变量类型非常严格
bool
string
int int8 int16 int32 int64
uint uint8 uint16 uint32 uint64 uintptr
byte // uint8 的别名
rune // int32 的别名 表示一个 Unicode 码点
float32 float64
complex64 complex128
3.5 零值(初始值)
零值
:没有明确初始值的变量声明会被赋予它们的 零值。
数值类型为 0,布尔类型为 false,字符串为 “”(空字符串)。
3.6 类型转换
Go 在不同类型的项之间赋值时需要显式转换!!!
下例math.Sqrt(float64(x*x + y*y))
中的float64()
不可删除
package main
import (
"fmt"
"math"
)
func main() {
var x, y int = 3, 5
var f float64 = math.Sqrt(float64(x*x + y*y))
var z uint = uint(f)
fmt.Println(x, y, f, z)
}
3.7 类型推导(auto)
可以用:=
进行类型推导,类似于C++
里的auto
:
package main
import "fmt"
func main() {
var a int = 2
var b float32 = 0.4
j := float32(a) + b
fmt.Printf("j is of type %T\n", j)
}
// OutPut: j is of type float32
// 如果改为 j := float32(a) + b
// OutPut: invalid operation: a + b (mismatched types int and float32)
Go的类型太严格了,不过某种程度上来说也算是好事。
3.8 常量
常量的声明与变量类似,只不过是使用 const 关键字。常量可以是字符、字符串、布尔值或数值。
固定写法:
const World = "世界"
常量可以不指定类型,但是一旦需要使用到它,它的类型会自动推导:
package main
import "fmt"
const (
Big = 1 << 100
Small = 2
)
func needInt(x int) int { return x*10 + 1 }
func needFloat(x float64) float64 {
return x * 0.1
}
func main() {
fmt.Println(needInt(Small))
fmt.Println(needFloat(Small))
fmt.Println(needFloat(Big))
}
/*
21
0.2
1.2676506002282295e+29
*/