写点什么

【一 Go 到底】第二十二天 --- 函数参数传递方式、变量作用域

作者:指剑
  • 2022-10-22
    重庆
  • 本文字数:1788 字

    阅读完需:约 6 分钟

一、函数参数传递方式

1.1 传递方式(2 种)

  1. 值传递(值类型参数)

  2. 引用传递(引用类型参数)


其实,不管是值传递还是引用传递,传递给函数的都是变量的副本,不同的是,值传递的是值的拷贝,引用传递的是地址的拷贝,一般来说,地址拷贝效率高,因为数据量小,而值拷贝决定拷贝的数据大小,数据越大,效率越低

1.2 值类型和引用类型

  1. 值类型:基本数据类型 int 系列,float 系列,bool,string,数组和结构体 struct

  2. 引用类型:指针,slice 切片,map,管道 chan,interface 等

1.3 值传递和引用传递使用特点

  1. 值类型默认是值传递,变量直接存储,内存通常在栈中分配

  2. 引用类型默认是引用传递,变量存储的是一个地址,这个地址对应的空间才真正存储数据(值),内存通常在堆上分配,当没有任何变量引用这个地址时,该地址对应的数据空间就成为一个垃圾,由 GC 进行回收

  3. 如果希望函数内的变量能够修改函数外的变量的值,可以传入变量的地址 &,函数内以指针的方式操作变量。效果上类似于引用

二、变量作用域

2.1 变量作用域说明

  1. 函数内部声明/定义的变量叫局部变量,作用域仅限于函数内部。详见函数内部变量案例

  2. 函数外部声明/定义的变量叫全局变量,作用域在整个包都有效,如果其首字母为大写,则作用域在整个程序有效。

  3. 如果变量是在一个代码块,如 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 = 18var 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)}
复制代码


发布于: 刚刚阅读数: 3
用户头像

指剑

关注

InfoQ签约作者 2022-07-13 加入

AWS社区建设者,AWS学生大使,微软学生大使,阿里云签约作者,Info Q签约作者,CSDN博客专家,华为云云享专家,OPS社区创始成员

评论

发布
暂无评论
【一Go到底】第二十二天---函数参数传递方式、变量作用域_Go_指剑_InfoQ写作社区