Go入门:三、函数的声明和调用

这是我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

你可能还喜欢下面这些文章

Go入门:五、goroutine和channel

这是我Go学习的第五篇笔记,学习的是go的语言的其他特性,这些特性是其他语言所不具备的。这次主要学习的是goroutine和channel。我的语言学习过程一般分为下面几个:1. 变量和数据类型2. 流程控制方法3. 函数声明和调用4. 面向对象5. 语言特性6. 常用标准库goroutine介绍和使用Go语言中,每个并发执行的单元称为goroutine(可类比线程)。当一个程序启动时候,main函数在一个main goroutine中运行。如果想要创建新的goroutine,使用go关键字!语法创建一个新的 goroutinechannel是goroutine的通信机制,比如创建一个能够接收

linux shell 入门

从程序员的角度来看, Shell本身是一种用C语言编写的程序,从用户的角度来看,Shell是用户与Linux操作系统沟通的桥梁。用户既可以输入命令执行,又可以利用 Shell脚本编程,完成更加复杂的操作。在Linux GUI日益完善的今天,在系统管理等领域,Shell编程仍然起着不可忽视的作用。深入地了解和熟练地掌握Shell编程,是每一个Linux用户的必修 功课之一。Linux的Shell种类众多,常见的有:Bourne Shell(/usr/bin/sh或/bin/sh)、Bourne Again Shell(/bin/bash)、C Shell(/usr/bin/csh)、K Shel

Go入门:六、常用标准库

这是我的Go学习的第六篇笔记,也是Go入门的最后一篇笔记。在大多数语言中,了解了变量和数据类型,流程控制,函数,面向对象,再加上标准库,就可以用这门语言去写一些项目了。首先让我想想,在工作中通常会用语言频繁处理什么问题或者处理什么数据?最常见的应该是各种字符串操作,日期和时间,读写文件、socket等IO相关的操作!字符串处理 — StringsString提供了一组处理字符串的操作,常用的有:判断一个字符串是否在另一个字符串中分割字符串为[]string和组合[]string为一个字符串字符串替换...太多了,就不一一列举了,这里列出一些常用的字符串操作。字符串判断字符串分割与合并字符串转换

Execl宏教程:从hello world开始入门

Excel宏使用的是vba,基本上就是运行在Excel里面的vb。所以学习vba和学习一门编程语言没有什么区别。所以我们最开始需要学的的就是一些基础语句。为了不让学习显得太枯燥,我们从一个hello world开始。首先需要打开Microsoft Excel,找到开发工具->宏,输入一个宏名称,点击创建创建了新的宏之后,就会出现一个编辑器界面Sub test()End Sub使用一个弹窗弹出hello worldSub test()MsgBox("hello world")End Sub到这里,一个简单的宏就创建完成了,虽然它现在什么也不能做,但是别着急,后面宏会为你做很多很多的事情,能

Go入门:四、面向对象

这是我的Go学习笔记的第四篇,面向对象!现代语言几乎都会面向对象进行了支持!当然,Go也具备面向对象的特性!我的语言学习过程一般分为下面几个:1. 变量和数据类型2. 流程控制方法3. 函数声明和调用4. 面向对象5. 语言特性6. 标准库Go语言中的面向对象有点特殊。在Go语言里面,没有显式的class、extends等面向对象语言经常使用的关键词,但是却有面向对象的特性。看看Go怎么实现的把!创建一个类按照我的理解,类实际上就是某种模板,这个模板里面含有有限多个属性和方法。在Go里面,定义这个模板的语法使用type来实现!比如单个int类型可以构成一个类(没错,你甚至可以在int数据类型上

赞赏

微信赞赏支付宝赞赏

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注