func FuncName(参数列表) (返回类型){
函数体
return
}
package main
import (
"fmt"
)
//无参无返回值函数
func Display() {
fmt.Printf("hello go\n")
}
//无参有返回值函数
func Test1() int { //当只有一个返回值时可以不写括号
return 666 //return后面接的是要返回的值,多个值之间用逗号隔开
}
func Test2() (i int) { //可以在返回值列表中注明返回值名称
i = 10 //一个return即可返回所有要返回的值
return
}
func Test3() (i int, j int) { //可以返回多个值
i, j = 10, 20
return
}
func Test4() (int, float64) { //返回值的类型不限
return 10, 20.2
}
func main() {
Display()
var (
a, b, c, d, e int
f float64
)
a = Test1()
b = Test2()
c, d = Test3()
e, f = Test4()
fmt.Println("——————————————无参无返回值函数—————————————")
fmt.Println("a=", a)
fmt.Println("b=", b)
fmt.Println("c=", c, " d=", d)
fmt.Println("e=", e, " f=", f)
fmt.Println("———————————————————————————————————")
}
输出:
package main
import (
"fmt"
)
//有参无返回值函数
func Add(a int, b int) {
//func Add(a,b int){ 也可以这样写
var sum int
sum = a + b
fmt.Println("a+b=", sum)
}
func main() {
Add(10, 20)
}
输出:
当不确定传入参数个数时使用
package main
import (
"fmt"
)
//有参无返回值函数,求用户输入所有数字之和
//...Type为不定参数类型,传入的参数可以是0个或多个
//不定参数只能放在形参的最后一个参数
func Add(args ...int) {
var sum int
for _, data := range args { //注意这一块的data不需要定义
sum += data
}
fmt.Println("sum=", sum)
}
func main() {
Add(10, 20, 30, 40, 50)
}
不定参数的传递:
package main
import (
"fmt"
)
//有参无返回值函数,求用户输入所有数字之和
//...Type为不定参数类型,传入的参数可以是0个或多个
//不定参数只能放在形参的最后一个参数
func Add(args ...int) {
var sum int
for _, data := range args { //注意这一块的data不需要定义
sum += data
}
fmt.Println("sum=", sum)
}
func test(tmp ...int) {
Add(tmp...) //将所有参数传递给tmp
Add(tmp[2:]...) //将第三个数字及后面的数字传递给Add
}
func main() {
test(10, 20, 30, 40, 50)
}
输出:
package main
import (
"fmt"
)
//有参有返回值
func Add(a, b int) (sum int) {
sum = a + b
return
}
func main() {
sum := Add(10, 20) //使用sum接收返回值
fmt.Println("sum=", sum)
}
package main
import (
"fmt"
)
//函数也是一种类型,通过type给一个函数类型起名
type FuncName func(int, int) int //FuncName为一个函数类型,没有函数名称和{}
func Add(a, b int) int {
return a + b
}
func Minus(a, b int) int {
return a - b
}
func main() {
var ftest FuncName //定义函数类型变量ftest
ftest = Add //ftest的值为函数Add,也就只说调用ftest就等同于调用Add
sum := ftest(10, 20)
fmt.Println("sum=", sum)
ftest = Minus
sum = ftest(50, 20)
fmt.Println("Minus=", sum)
}
package main
import (
"fmt"
)
//函数也是一种类型,通过type给一个函数类型起名
//FuncName为一个函数类型,没有函数名称和{}
type FuncName func(int, int) int
func Add(a, b int) int {
return a + b
}
func Minus(a, b int) int {
return a - b
}
//回调函数,函数中有一个是函数类型,这个函数就是回调函数
//计算器可以进行四则运算
//多态,多种形态,调用同一个接口,实现不同功能,加减乘除
func Calc(a, b int, fTest FuncName) (result int) {
fmt.Println("Calc")
result = fTest(a, b)
return
}
func main() {
sum := Calc(10, 20, Add)
fmt.Println("sum=", sum)
sum = Calc(50, 20, Minus)
fmt.Println("Minus=", sum)
}
- 所谓闭包就是一个函数“捕获”了和它在同一个作用域的其他常量和变量。这就意味着当闭包被调用的时候,不管在程序什么地方调用,闭包能够使用这些变量和常量。他不关心这些捕获了的变量或常量是否已经超出了作用域,所以只要闭包还在使用它,这些变量就还会存在。在go语言中,所有的匿名函数都是闭包,匿名函数是指不需要定义函数名称的一种函数实现方式。
package main
import (
"fmt"
)
func main() {
i := 10
str := "mike"
//无参无返回值
func() {
fmt.Println("i=", i)
fmt.Println("str=", str)
}() //后面的()表示调用匿名函数
//有参无返回值
func(i, j int) {
fmt.Println("i=", i, " j=", j)
}(10, 20)
//无参有返回值
z := func() int {
return 666
}()
fmt.Println("z=", z)
//有参有返回值
max, min := func(i, j int) (max, min int) {
if i > j {
max = i
min = j
} else {
max = j
min = i
}
return
}(20, 30)
fmt.Println("max=", max, " min=", min)
}
闭包捕获参数的特点:
package main
import (
"fmt"
)
func main() {
i := 10
str := "mike"
//闭包是以引用方式捕获外部变量
func() {
i = 666
str = "go"
fmt.Println("外部:i=", i, " str=", str)
}()
fmt.Println("内部:i=", i, " str=", str)
}
输出:
package main
import (
"fmt"
)
//函数的返回值是一个匿名函数
func test() func() int {
var x int //没有初始化,值为0
return func() int {
x++
return x * x
}
}
func main() {
//返回值为一个匿名函数,返回一个函数类型,通过f调用匿名函数
//他不关心这些捕获了的变量或常量是否已经超出了作用域
//所以只要闭包还在使用它,这些变量就还会存在
f := test()
fmt.Println(f())
fmt.Println(f())
fmt.Println(f())
fmt.Println(f())
}
输出:
defer用于延迟一个函数或者方法的执行。
多个defer同时使用遵寻FILO原则
package main
import (
"fmt"
)
func main() {
i, j := 10, 20
defer func(i, j int) {
fmt.Printf("内部:i=%d,j=%d\n", i, j)
}(i, j) //把参数传递过去,先不调用,相当于(10,20)
i, j = 111, 222
fmt.Printf("外部:i=%d,j=%d\n", i, j)
}
输出:
package main
import (
"fmt"
"os" //调用os包
)
func main() {
args := os.Args //获取命令行参数,命令行参数都是以字符串的方式进行接受的。
n := len(args) //获取命令行参数的个数
for index, data := range args { //遍历命令行参数方法一
fmt.Printf("args[%d]=%s\n", index, data)
}
for i := 0; i < n; i++ { //遍历命令行参数方法二
fmt.Println(args[i])
}
}
- 为了能够构建这个工程,需要先把所需工程目录加入到环境变量GOPATH中。否则,即使处于同一工作目录(工作区)代码之间也无法通过绝对代码包路径完成调用。
- 在实际开发环境中,工作目录往往有多个,多个工作目录的目录路径都需要添加至GOPATH。当有多个目录时,请注意分隔符,多个目录的时候windows是分号,Linux是冒号,当有多个GOPATH时,默认会将go get的内容放在第一个目录下。
所有GO语言的程序都会组织成若干组文件,每组文件被称为一个包。这样每个包的代码都可以作为很小的复用单位,被其他项目引用。一个包的源代码保存在一个或者多个以.go文件后缀名的源文件中,通常一个包所在目录路径的后缀是包导入的路径。
对于一个较大的应用程序,我们应该将他的功能分割成逻辑单元,分别在不同的包里实现,我们创建的自定义包最好放在GOPATH的str目录下(或者GOPATH src的某个子目录)。
在GO语言中,代码包中的源码文件名可以是任意的。但是,这些任意名称的源码文件都必须以包声明语句作为文件中的第一行,每个包都对应一个独立的名字空间。
包中成员以名称大小写决定访问权限:
- public:首字母大写,可被包外访问
- private:首字母小写,仅包内成员可以访问。
注意:同一个目录下不能定义不同的package。
import . "fmt" 报名前加点表示使用包里面的函数可以直接使用函数名,必须要加报名,如Println("hello go")
import _ "fmt" 下滑线表示调用包而不使用包,即调用后不适用编译不会报错,该操作其实是不直接调用该包里面的函数,而是调用了该包里面的init函数。
import NewName "fmt" 给包起别名。
在go语言中,命名为main的包具有特殊的含义。go语言的编译程序会试图把这种名字的包编译为二进制可执行文件。所有用go语言编译的可执行程序都必须有一个名叫main的包。一个可执行程序有且仅有一个main包。当编译器发现某个包的名字为main是它也会发现名为main()的函数,某则不会创建可执行文件。main()函数是程序的入口,所以,如果没有这个函数,程序就没有办法喀什执行。程序编译时,会使用声明为main包的代码所在的目录名作为二进制可执行文件的文件名。
go语言中有两个保留的函数:init函数(能够应用于所有的package)和main函数(只能应用于package main)。这两个函数在定义时不能有任何的参数和返回值。虽然一个package里面可以写任意多个init函数,但这无论是对于可读性还是以后的可维护性来所,我们都强烈建议一个package中每个文件中只写一个init函数。
每个包可以包含任意多个init函数,这些函数都会在程序执行开始的时候被调用。所有被编译器发现的init函数都会安排在main函数之前执行。init函数用在设置包、初始化变量或者其他要在程序运行前优先完成的引导工作。
【1】同级目录
- 分文件编程(多个源文件),必须放在src目录。
- 设置GOPATH环境变量
- 同一个目录,包名必须一样
- go env查看GO相关的环境路径
- 同一个目录,调用别的文件的函数,直接调用即可,无需包名引用。
例子:
文件内容:
package main //文件test.go
import (
"fmt"
)
func test() {
fmt.Println("hello go")
}
package main //文件main.go
func main() {
test()
}
在liteide中通过Ctrl + R执行结果:
【2】不同级目录
- 不同目录包名不一样
- 调用不同包里面的函数,格式为:包名.函数名(args)
- 调用别的包的函数,函数名首字母大写才可以调用,小写不能调用。
例子:
目录结构:
C:\GOPATH\src\不同级目录\src\main.go
C:\GOPATH\src\不同级目录\src\calc\calc.go
文件内容:
package main //main.go
import (
"calc"
"fmt"
)
func main() {
sum := calc.Add(10, 20)
fmt.Printf("sum=%d\n", sum)
}
package calc //calc.go
func Add(a, b int) int {
return a + b
}
执行结果:
17.go install命令使用
- 配置GOPATH和GOBIN环境变量
- 进入src目录执行go install
- 系统自动生成bin和pkg目录