这是我Go学习笔记的第三篇!接下来学习的是Go的函数声明和调用。
我的语言学习过程一般分为下面几个:
1. 变量和数据类型 2. 流程控制方法 3. 函数声明和调用 4. 面向对象 5. 语言特性 6. 标准库
函数声明
func 函数名称(参数表) 返回值类型 { // 函数体 }
写一个函数是非常简单的,掌握语法格式就可以了。函数是一个功能的封装,能让函数体内的代码得到很好的复用。
比如我要输出个人信息,我可以把个人信息封装到函数里面,后续直接调用这个函数而不是每次都print一堆信息了
package main
import "fmt"
// 定义一个能够打印个人信息的函数
func info() {
fmt.Println("姓名: hc")
fmt.Println("性别: 男")
fmt.Println("职位: 程序员")
}
func main() {
// 调用上面定义的函数
info()
}
上面定义的函数没有参数,也没有返回值,非常简单的一个函数。如果我想让姓名可变,那么可以定义一个带有参数的函数
package main
import "fmt"
// 定义一个能够打印个人信息的函数
// 这里加入了name参数,类型为string
func info(name string) {
fmt.Printf("姓名: %s\n", name)
fmt.Println("性别: 男")
fmt.Println("职位: 程序员")
}
func main() {
// 调用的时候传入参数
info("hc")
}
接下来定义一个有意义的带有参数和返回值的函数,比如计算一个数字的绝对值
package main
import "fmt"
// 返回一个数字的绝对值
func abs(n int) int {
if n < 0 {
n = -n
}
return n
}
func main() {
fmt.Println(abs(-1))
}
参数传递
关于go的参数传递,作为一个新手会有些疑惑的地方。go语言只有传值,没有传引用。传入指针也是传入指针的一个拷贝。
传值
函数内部改变参数的值,不改变原值。比如:
i := -1
fmt.Println(abs(i)) // 输出的是1
fmt.Println(i) // 输出的是-1,原值并没有被改变
传指针
传入变量的地址,可以改变原来的变量
package main
import "fmt"
func abs(n *int) int {
if *n < 0 {
*n = -*n
}
return *n
}
func main() {
var i int
i = -1
fmt.Println(abs(&i)) // 输出的是1
fmt.Println(i) // 输出的还是1,i原值被改变了
}
一个比较经典的传引用的例子是交换两个变量的值
func swap(x *int, y *int) { var temp int temp = *x *x = *y *y = temp } // 调用 x := 1 y := 2 swap(&x, &y) //x变成2,y变成1了
可以看到,函数的参数是一个地址。(&在变量的前面是取地址运算符),使用*来从地址取值。
map参数
当我们把map作为参数传递到函数里面时,在函数内改变map值的时候,发现外部的map值也被改变了。map传入的是指针?
通过查资料我们可以发现,创建map的方法如下:
// makemap implements Go map creation for make(map[k]v, hint).
// If the compiler has determined that the map or the first bucket
// can be created on the stack, h and/or bucket may be non-nil.
// If h != nil, the map can be created directly in h.
// If h.buckets != nil, bucket pointed to can be used as the first bucket.
func makemap(t *maptype, hint int, h *hmap) *hmap
返回的是一个map的指针!当我们把map传入函数的时候,实际上传递的是一个指针。
chan
func makechan(t *chantype, size int64) *hchan
和map一样的含有chan类型,chan也是一个指针,作为参数传递的也是一个指针类型。
slice
slice和map,chan不太一样。slice是结构体和元素指针的混合结构。
参考:https://www.flysnow.org/2018/02/24/golang-function-parameters-passed-by-value.html
赞赏微信赞赏
支付宝赞赏