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

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

C++入门:三、函数

这是我学习C++的第三篇笔记,函数。我的学习路径是现在学习的是函数的声明、定义、调用等相关知识。函数声明和定义函数的声明包含返回类型,函数名字,0个或者多个形参,无函数体,通常在头文件中对函数进行声明。函数的定义包含返回类型,函数名字,0个或多个形参,以及函数体。比如写一个求阶乘的函数,可以写成下面这样写一些简单的函数大多数语言都差不多,不过可惜每种语言或多或少都有自己的特色,这是比较令人头秃的地方。函数的参数函数可以带有0或多个参数,每个参数都需要声明类型。参数传递可以传值和传引用。如果形参是引用类型,那么它将绑定到对应的实参中,我们成为传引用。否则,将会把实参的值拷贝后赋值给形参,我们成为

C++实现python字符串的endswith方法

可以使用的或方法配合比较运算符来模拟方法的功能。下面是一个示例函数,它检查一个字符串是否以另一个字符串结束:在这个示例中,函数接受两个参数:和。函数首先检查的长度是否大于或等于的长度。如果不是,那么显然不能以结束,函数返回。否则,函数使用方法从的末尾提取与长度相同的子字符串,并将其与进行比较。如果它们相等,那么以结束,函数返回。否则,函数返回。请注意,这个函数是区分大小写的。如果你想要一个不区分大小写的版本,你可以在比较之前使用和函数将和转换为小写。在这个版本中,函数首先使用和函数将和转换为小写。然后,它调用函数来检查转换后的字符串是否以结束。

python学习笔记:三、函数

这是第三篇python学习笔记,我们即将要学习python的函数。内容主要包括两个部分,函数的声明和函数的调用。函数声明和调用比如我们要声明一个“吃”的函数,语法如下:def eat(): return "eat something"print(eat())上面是一个没有参数的函数,做的事情很简单,声明一个函数,然后返回一个字符串。接下来要增加一个参数了。def ead(food): return "eat %s" % foodprint(eat('fruit'))可以看到,上面声明了一个带有一个参数的函数,当然可以声明带两个,三个等。这些都是固定的,那么如果要声明一个不固定参数的

Go语言的 make 和 new

new 和 make 是两个内置函数,主要用来创建并分配类型的内存。在我们定义变量的时候,可能会觉得有点迷惑,不知道应该使用哪个函数来声明变量,其实他们的规则很简单,new 只分配内存,make 只能用于 slice、map 和 channel 的初始化。下面我们就来具体介绍一下new在Go语言中,new 函数描述如下:从上面的代码可以看出,new 函数只接受一个参数,这个参数是一个类型,并且返回一个指向该类型内存地址的指针。同时 new 函数会把分配的内存置为零,也就是类型的零值。【示例】使用 new 函数为变量分配内存空间。当然,new 函数不仅仅能够为系统默认的数据类型,分配空间,自定义

shell中 $? $# $* $$ $* $@ $0 特殊变量含义

shell中有一些常用的难记的特殊变量,如下:$0当前脚本的文件名$n传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是$1,第二个参数是$2。$#传递给脚本或函数的参数个数。$*传递给脚本或函数的所有参数。$@传递给脚本或函数的所有参数。被双引号(" ")包含时,与 $* 稍有不同$?上个命令的退出状态,或函数的返回值。$$当前Shell进程ID。对于 Shell 脚本,就是这些脚本所在的进程ID。$0 - 当前脚本文件名$n - 第n个参数$# - 参数个数$* - 所有参数$@ - 所有参数$? - 上一个命令的返回值$$ - 当前进程id

c++ vector取最后一个元素

在C++中,你可以使用的成员函数来获取最后一个元素。这个函数返回对向量中最后一个元素的引用。以下是一个简单的示例:在这个例子中,我们创建了一个包含五个整数的。然后,我们使用函数获取最后一个元素,并将其存储在变量中。最后,我们打印出这个元素。请注意,如果向量是空的(即,不包含任何元素),调用函数将导致未定义行为。因此,在调用之前,最好先检查向量是否为空,这可以通过调用成员函数来完成。

计算机语言学习指南

这篇文章讨论基于语言的基本要素,如何快速入门一种计算机语言。是一篇语言从学习到使用的指导手册,并且这种学习方式是一个系统的学习,相比于碎片化的学习,这种学习更加不容易遗忘。语言的基本成分语言的基本成分为数据、运算、控制、传输。想想你学过的语言,是不是都是这样。归结语言的组成成分,学习一门语言可以从这四个方面下手,这四个方面掌握之后,对这个语言就有个最基本的了解了。语言基本成分:数据数据是程序操作的对象。实际上我们可以思考,一个数据拥有的属性有哪些,根据我们已经掌握的语言来说(比如PHP)。$a = 1$a是数据,那么这个数据有哪些属性呢?名称(a),类型(int)。从这一行代码只能发现这两个属

signal函数详解

signal作用是为信号注册一个处理器。这里的“信号”是软中断信号,这种信号来源主要有三种:程序错误:比如除0,非法内存访问。外部信号:终端Ctrl-C产生的SIGINT信号,定时器产生的SIGALERM。显示请求:kill函数发送的任意信号。当kill一个进程的时候,默认会发送SIGTERM信号,此时这个信号只有默认处理操作(SIG_DFL),直接中断进程执行。如果此时该进程正在执行一个任务,直接终止该进程会导致任务没有完成。这个时候为SIGTERM信号注册一个信号处理函数就十分有必要。介绍参数sig要设置信号处理函数的信号。它可以是实现定义值或下例值之一:SIGABRTSIGFPESIGI

C++ 判断 char* 是否相等

在C++中, 是一个指向字符的指针,通常用于表示C风格的字符串。判断两个  指针是否相等,需考虑两个方面:判断指针本身的地址是否相等:可以通过直接使用  或  操作符来实现。 和  指向不同的地址(尽管它们的内容相同),而  和  指向相同的地址。2. 判断指针指向的字符串内容是否相等:需要使用  函数,它是C标准库中的一部分,在C++中可用。 函数用于比较 、 和  的内容。如果内容相同, 返回

php print 这个坑,遇到连接符从右往左执行

在使用php的时候,我很少用到print这个函数,哦,不对,这是一个语言结构,而并非日函数!看一段代码

赞赏

微信赞赏支付宝赞赏

发表回复

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