【go】函数的简单介绍

1.包的引出
需要在文件中调用其它文件定义的函数
在不同的包中可以定义同名 的函数

2.包的本质就是创建不同的文件夹,来存放程序文件

3.包的作用
区分同名的标识符
控制函数、变量的访问范围,即作用域

4.语法
package 包名
import “package path”

5.包的使用入门
文件组织结构

// hello.go
package main
import (
	"fmt"
	"unsafe"
	"go_code/project00/utils"
)

func main() {
	n1 := 1.2
	n2 := 2.3
	var operator byte
	fmt.Println("plz input the operator")
	fmt.Scanf("%c", &operator)
	// test
	fmt.Printf("Your input is %v, type is %T, it needs %d bytes\n", operator, operator, unsafe.Sizeof(operator))
	ans := utils.Cal(n1, n2, operator)
	fmt.Printf("answer is %.2f", ans)	
}
// utils.go
package utils
import "fmt"

//首字母大写,该函数可以导出
func Cal(n1 float64, n2 float64, operator byte) float64 {
	var res float64
	switch operator {
	case '+':
		res = n1 + n2
	case '-':
		res = n1 - n2
	default:
		fmt.Println("ERROR")
	}
	return res
}

6.文件的包名通常与文件所在的folder一致
7.package指令在第一行,然后import
8.import包的时候,路径从$GOPATH的src下开始,不带src,编译器自动从src下引入

9.import时可以给包取别名,写在路径前面
原来的名字就不好使了

10.同一个包下,不能有相同的函数名
11.如果要编译成一个可执行文件,需要把包声明为main,package main
如果写的是一个库,包名可以自定义

12.编译时需要编译main包所在的文件夹
编译的指令在项目目录下,不用带src

go build go_code\project00\main

在$GOPATH目录下可以指定名字和目录

go build -o bin\my.exe go_code\project00\main

13.内存分配
基本数据类型通常分配在栈区(编译器存在逃逸分析)
引用数据类型通常分配在堆区
代码区
在这里插入图片描述
14.函数可以返回多个值
返回和差

// hello.go
package main
import (
	"fmt"
	"go_code/project00/utils"
)

func main() {
	n1 := 1
	n2 := 2
	// fmt.Println("plz input the operator")
	res1, res2 := utils.Cal(n1, n2)
	fmt.Printf("answer is %v, %v", res1, res2)	
}
// utils.go
package utils

//首字母大写,该函数可以导出
func Cal(n1 int, n2 int) (int, int) {
	sub := n1 - n2
	sum := n1 + n2
	return sum, sub
}

15.go不支持重载

16.go中,函数也是一种数据类型,可以赋值给一个变量,该变量是一个函数类型的变量。通过该变量可以对函数调用

package main
import (
	"fmt"
)

func fibo(n int) int {
	if n < 3 {
		return 1
	}
	return fibo(n - 1) + fibo(n - 2)
}

func main() {
	a := fibo
	fmt.Printf("type of a is %T, type of fibo is %T\n", a, fibo)
	fmt.Println("input n")
	var n int
	fmt.Scanln(&n)
	fmt.Println(a(n))// 1 1 2 3 5
}

17.go中,函数可以作为形参

package main
import (
	"fmt"
)

func fibo(n int) int {
	if n < 3 {
		return 1
	}
	return fibo(n - 1) + fibo(n - 2)
}

func myFun(funVar func(int) int, num int) int {
	return funVar(num);
}

func main() {
	a := fibo
	fmt.Printf("type of a is %T, type of fibo is %T\n", a, fibo)
	fmt.Println("input n")
	var n int
	fmt.Scanln(&n)
	fmt.Println(myFun(fibo, n))// 1 1 2 3 5
}

18。go支持自定义数据类型
type 自定义类型名 类型
相当于起别名

	// 给int取了别名,但go认为int与myInt是不同的类型
	type myInt int
	var num1 myInt
	var num2 int
	num1 = 40
	num2 = int(num1) // 需要显式转换
	fmt.Println(num1, num2)
package main
import (
	"fmt"
)

type myFunType func(int, int) int
func getSum(n1 int, n2 int) int {
	return n1 + n2
}

func myFun(funVar myFunType, n1 int, n2 int) int {
	return funVar(n1, n2)
}

func main() {
	fmt.Println(myFun(getSum, 2, 4))
}

19.支持对函数返回值命名

func getSumAndSub(n1 int, n2 int) (sum int, sub int) {
	sum = n1 + n2
	sub = n1 - n2
	return
}

函数在定义时就定义了返回值

20.go支持可变参数
slice切片是一个动态数组

这种报错是忘了返回

# command-line-arguments
.\hello.go:12:1: missing return at end of function
package main
import (
	"fmt"
)

// 可变参数的使用
func sum(n1 int, args... int) int {
	sum := n1
	// args traversal
	for i := 0; i < len(args); i++ {
		sum += args[i] // 取出args的ith值
	}
	return sum
}

func main() {
	fmt.Println(sum(10))
	fmt.Println(sum(1, 2, 3, 4, 6))
}

可变参数只能放在形参列表的最后一个

21.每个源文件都可以包含一个init函数,该函数在main函数之前,被go运行框架调用,也就是initial会在main之前被调用。

22.如果一个文件同时有全局变量定义,init,main
执行的流程是变量定义=>init=>main

package main
import "fmt"

var age = test()

func test() int {
	fmt.Println("test()")
	return 90
}

func init() {
	fmt.Println("init()")
}

func main() {
	fmt.Println("main age=", age)
}

23.执行顺序
seq
24.匿名函数
如果某个函数希望只用一次,可以用匿名
匿名函数 也可以多次调用

匿名函数可以在定义时调用

// 接收结果
	res1 := func (n1 int, n2 int) int {
		return n1 + n2
	}(10, 2) // 在定义时完成调用
	fmt.Println(res1)

将匿名函数赋给变量,通过变量调用

// a是一个函数变量
	a := func (n1 int, n2 int) int {
		return n1 - n2
	}
	// a可以反复调用
	fmt.Println(a(20, 44))

将匿名函数赋给全局变量,成为全局匿名函数,

var (
	age = test()
	//前面写了var 不用写:
	// fun1不用大写,全局变量
	fun1 = func (n1 int, n2 int) int {
		return n1 * n2
	}
)
func test() int {
	fmt.Println("test()")
	return 90
}

func main() {
	fmt.Println("main age=", age)
	fmt.Println(utils.Age, utils.Name)

	fmt.Println(fun1(3, 42))
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值