Go语言学习记录2——基础语法【包、变量、函数】

一.包

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
*/
上一篇:PostgreSQL 13 新建数据库、用户及配置


下一篇:解析struct的内存布局