持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第22天,点击查看活动详情
一、函数参数传递方式
1.1 传递方式(2种)
-
值传递(值类型参数)
-
引用传递(引用类型参数)
其实,不管是值传递还是引用传递,传递给函数的都是变量的副本,不同的是,值传递的是值的拷贝,引用传递的是地址的拷贝,一般来说,地址拷贝效率高,因为数据量小,而值拷贝决定拷贝的数据大小,数据越大,效率越低
1.2 值类型和引用类型
值类型:基本数据类型int系列,float系列,bool,string,数组和结构体struct引用类型:指针,slice切片,map,管道chan,interface等
1.3 值传递和引用传递使用特点
-
值类型默认是值传递,变量直接存储,内存通常在栈中分配
-
引用类型默认是引用传递,变量存储的是一个地址,这个地址对应的空间才真正存储数据(值),内存通常在堆上分配,当没有任何变量引用这个地址时,该地址对应的数据空间就成为一个垃圾,由GC进行回收
-
如果希望函数内的变量能够修改函数外的变量的值,可以传入变量的地址&,函数内以指针的方式操作变量。
效果上类似于引用
二、变量作用域
2.1 变量作用域说明
- 函数内部声明/定义的变量叫局部变量,作用域仅限于函数内部。
详见函数内部变量案例 - 函数外部声明/定义的变量叫全局变量,作用域在整个包都有效,如果其首字母为大写,则作用域在整个程序有效。
- 如果变量是在一个代码块,如 for/if中,那么这个变量的作用域仅在该代码块
2.2 案例演示
2.2.1 函数内部变量案例
package main
import "fmt"
// 函数
func test() {
// 下面声明的变量 仅在该函数内,与首字母是否大小写无关
// 注意 := 的声明方式,仅在函数内可以这样声明
// 在函数内声明的变量 仅在该函数内操作,在函数体外无法使用
age := 10
Name := "Test"
fmt.Printf("Func inside use , age=%v, Name=%v", age, Name)
}
func main() {
test()
// // 下面调用会报错
// fmt.Println(age,Name)
}
2.2.2 函数外部声明案例
在其他文件也可以引用(大写字母开头)
package main
import "fmt"
var Age int = 18
var Name string = "Mike"
func main() {
// Age = 18, Name = Mike
fmt.Printf("Age = %v, Name = %v", Age, Name)
}
2.3 作用域案例练习
// package main
// import "fmt"
// // 函数
// func test() {
// // 下面声明的变量 仅在该函数内,与首字母是否大小写无关
// // 注意 := 的声明方式,仅在函数内可以这样声明
// // 在函数内声明的变量 仅在该函数内操作,在函数体外无法使用
// age := 10
// Name := "Test"
// fmt.Printf("Func inside use , age=%v, Name=%v", age, Name)
// }
// func main() {
// test()
// // // 下面调用会报错
// // fmt.Println(age,Name)
// }
// // 函数外部定义变量使用
// package main
// import "fmt"
// var Age int = 18
// var Name string = "Mike"
// func main() {
// // Age = 18, Name = Mike
// fmt.Printf("Age = %v, Name = %v", Age, Name)
// }
// 作用域案例练习
package main
import "fmt"
var name = "June"
func test01() {
fmt.Println(name)
}
func test02() { // 编译器采用就近原则
name := "MK"
fmt.Println(name)
}
func main() {
fmt.Println(name) // 输出 June
test01() // 输出June
test02() // 输出 MK
test01() // 输出 June
}
三、函数练习
3.1 打印金字塔
根据用户输入,打印对应层数的金字塔
package main
import "fmt"
func tower(layers int) {
for i := 1; i <= layers; i++ {
// 打印空格
for k := 1; k <= layers-i; k++ {
fmt.Print(" ")
}
for j := 1; j <= 2*i-1; j++ {
// // 空心金字塔
// if j == 1 || j == 2*i-1 || i == layers {
// fmt.Print("*")
// } else {
// fmt.Print(" ")
// }
fmt.Print("*")
}
fmt.Println()
}
}
func main() {
var layers int
fmt.Printf("请输入您要打印的层数:")
fmt.Scanln(&layers)
tower(layers)
}
3.2 打印九九乘法表
package main
import "fmt"
func nMn(num int) {
for i := 1; i <= num; i++ {
for j := 1; j <= i; j++ {
fmt.Printf("%v * %v = %v \t", j, i, j*i)
}
fmt.Println()
}
}
func main() {
var num int
fmt.Printf("请输入一个整数(1-9): ")
fmt.Scanln(&num)
nMn(num)
}