5week-1函数定义和返回值列表
- 一个函数执行1次也要封装用函数
函数的分类
- 内建函数,如make、new、panic等
- 库函数,如math.Ceil()等
- 自定义函数,使用func关键字定义
一.函数定义
func 函数名 (参数列表) [返回值列表]{
函数体 代码块
[return 返回值]
}
- add就是函数名:本质上给程序员用的,标识符,和常量,变量一样
- 参数列表里:叫做形式参数,是标识符,和常量,变量一样
- 参数列表可以写成
x y, int
表示xy都是int类型 - 函数名 (函数列表)(返回值列表) 叫做函数签名
- 函数列表叫:做入参, 返回值列表:叫做出参
//add(x int, y int)这个叫函数签名
//x int, y int 叫形参/入参 还可以写出 x,y int;作用是占位
func add(x int, y int) {
fmt.Println("这是函数体,代码块,多行组成")
fmt.Println(x + y) //print不是返回,这个是打印到控制台
}
二.函数调用
package main
import "fmt"
func add1(x int, y int) int {
//x int, y int 叫形参/入参 还可以写出 x,y int;作用是占位
// int 是返回值类型;个数是1个,可以是多个
fmt.Println(x)//这个叫输出到控制台.给人看的,没有返回值
return x + y //return 1是返回值,返回的数据类型要和 返回值类型一样
}
func main() {
fmt.Println(add1(10, 20)) //如果想用1次add1返回的值,可以直接打印函数,并传参
v1 := add1(4, 5)
//如果有返回值,调用的时候要用变量接收,然后打印
fmt.Println(v1 + 200) //如果想多次使用add1返回的值,就要把返回值赋值给变量.
// const v2 = add1(1, 2) //函数返回值,赋值给常量,不行,因为v2是常量,add1的返回值是变量
const v3 = 101
fmt.Println(v3 + 100)
}
三.函数类型
package main
import "fmt"
func add1(x int, y int) int {
return x + y
}
func test(x int) int {
return x
}
func test1() {
}
func main() {
fmt.Println(add1) //直接打印函数,是函数的指针地址 0xe45c40
fmt.Printf("add1函数的类型是:%T\n", add1) //查看函数的类型.是函数的签名
fmt.Printf("test函数的类型是:%T\n", test)
fmt.Printf("test1函数的类型是:%T\n", test1) //无返回值的函数,不能用变量接收
}
- 结果
,函数的签名决定函数的类型,函数的签名和函数类型有关
四.函数返回值
1.无返回值
package main
import "fmt"
func fn1() {} //无返回值的函数,不能用变量接收,如果接收了是语法错误;其他语言可以,但,是一个特殊值
func main() {
// v := fn1() //错误
fmt.Println(fn1()) //错误
}
2. 有返回值1 ---直接返回字面量
package main
import "fmt"
func fn2() int { //有返回值,
return 100 直接return 返回值规定的类型,数字
}
func main() {
v := fn2() // v:= 是类型推断,自动判断返回值类型
fmt.Printf("%T %v", v, v)
}
- 结果
3. 有返回值2 ---返回值和数字相加
func fn3() int { //返回值类型是int,
r := 100 //自己定义返回值,返回值r=100,返回r 和上面直接return类似
return r
}
func fn3() int {
var r = 100
return r
}
func fn3() int {
var r = 100
return r + 23 //由于r是继承了返回值int类型. 那么 r+23的值也是int类型
}
4.返回值---里面声明了变量
和类型
,函数中给返回值赋值
package main
import "fmt"
func fn4() (r int) {
r = 200
return r
}
func main() {
v4 := fn4()
fmt.Printf("%T %v\n", v4, v4)
}
- 结果
5.返回值---推断1
package main
import "fmt"
func fn5() (r int) {
r = 200
return //函数里就有1个变量r. 返回值列表里写了 r, return才能自动推断返回r,否则不能推断
}
func main() {
v5 := fn5()
fmt.Printf("%T %v\n", v5, v5)
6.返回值---赋值
package main
import "fmt"
func fn55() (r int) {
t := 200
return t
}
func main() {
v5 := fn55()
fmt.Printf("%T %v\n", v5, v5)
}
- 结果
7.返回值---直接返回,返回值列表中的值
package main
import "fmt"
func fn6() (i int, j bool) {
return 199, true
}
func fn7() (i int, j bool) { //返回值列表,声明变量
i, j = 200, true //赋值
return
}
func main() {
i, v4 := fn6()
fmt.Println(i, v4)
a, b := fn7()
fmt.Println(a, b)
}
- 结果
8.多个返回值
- 1个变量不能接收2个值
package main
import "fmt"
func fn6() (int, int) {
a, b := 100, 200
return a, b
}
func main() {
x, y := fn6() //py可以,把返回值封装成1个元组,但是go不行
fmt.Println(x, y)
f, _ := fn6() //如果不想用某个值 用_忽略
fmt.Println(f)
}
- 结果
9.函数返回值列表声明返回值变量
package main
import "fmt"
func fn7() (m int, n bool) { //m和n 是为后期返回值提前占位;和形参类似;只不过是出参,都是此函数内的局部变量;m和n已经是本函数声明过的,但是没有赋值,是零值
m = 100
return
}
func main() {
// n7 := fn7()
fmt.Println(fn7())
}
- 结果
// 10.error接口类型返回
func fn8() (i int, err error) { // 2个返回值,i 是int类型; error是接口类型
if f, err := os.Open("d:/test1"); err != nil { //如果打开文件,不是空,
//一是f操作文件的东西,c语言叫句柄 二是ok或者err错误,判断错误文件打开电脑上的文件
return -1, err
} else {
fmt.Println(f)
return 100, errors.New("test string")
}
}
func main() {
fn8()
}