type
status
date
slug
summary
tags
category
icon
password
关键词:
range,多值返回,类型嵌入,接收器,slice与map的nil
range
range语法可以用于遍历slice,map等数据结构,当用于slice时,其使用方法有如下几种:
你可以把range返回的元素个数当成1,那么这个变量就代表了slice中的下标,也就是说,按照这种方式,循环打印idx,你得到的结果是0,1,2,…,len(slice)-1
你也可以把range返回的元素个数当成2,那么第一个变量为slice中的下标,第二个变量为具体的值;
假如你认为元素个数为2,那么你可以用_来忽略你用不到的值,毕竟在Go语言中,一个没被使用的变量是会让编译器报错的,下划线可以解决这个问题;
多值返回
Go语言是一门支持多值返回的语言,比如下面这个函数:
返回了一个类型为Result的变量,和一个error变量;
那如何接受这类函数的值呢?
最标准的就是
假如我需要直接将返回的多个值直接打印,我可以:
但是写成下面这样不被允许:
在此,我们拓展开来,看看 = 和 := 这两个符号带给开发者的陷阱:
这段代码的目的是为了将ts中每一个transformation的结果加入到steps数组并返回,编译也是能通过的,但实际是达不到我们的效果的,原因就出在这个 :=上,它使得左边两个变量都是新的变量,其中的n会覆盖掉这个函数传入的参数n,同时每次迭代之后这个n就会失效
那我们该如何解决这个问题呢?
我们只要将err这个变量单独声明即可
类型嵌入
当一个结构体内嵌了一个类型时,它继承了这个类型的所有方法,这种继承与oop中的继承不同,是在外部结构体上定义这些成员,并将这些成员的调用或访问委托给内部对象的语法糖,以此达到避免显示调用内部成员的目的。
以下是一段简单的式样代码:
在类型嵌入中,也要特别关注类型断言,比如下面这段代码:
tim可以被断言为一个Wrapper,但是tim.Node不可以。
接收器
以下是值/指针接收器
方法是定义在接收器的类型上的,具体而言,分为两种情况:
1.接收器为值类型
以上述代码为例,此时Name这个方法是被Node类型和*Node类型同时实现,这两种类型都可以调用这个Name方法;
2.接收器为指针类型
以上述代码为例,此时Name这个方法仅仅被*Node这个类型实现,Node类型没有这个方法;
但是,即使如此,Node类型也可以调用这个方法,因为在具体调用时Node会被自动转换为*Node;
最后注意一下,当接收器为指针类型时,可以改变接收器内部元素的值,反之不可以,毕竟,Go是按值传递的。
Nil
nil在go语言中,不光可以代表空指针,slice,map,interface等都可以
我们具体来看一下slice和map中nil有什么陷阱
先看下一段关于slice的代码:
如你所见,这段代码申明了一个slice变量,此时为nil,随后用append方法给其增加一个元素,从结果来看符合我们的预期。
再来看下面一段关于map的代码:
这段代码申明了一个值为nil的map变量,随后给其增加了一个元素,但结果居然是nil panic;
为什么给slice的nil增加一个元素可以,给mao就不行呢?
实际上,直接对nil进行操作都是不可以的,nil在go中是immutable(不可变的),slice那段代码,本质上是是因为append创建了一个新的数组,不再是在nil上进行操作,然后将这个新数组的值返回给slice,使得其变为我们看到的结果。而map那段代码,并没有这样的过程,于是便会出现panic。
我们可以使用make来初始化。防止nil值
全文终。
注:
- 作者:Alex
- 链接:https://nextme.one/wureny.eth/article/gomistake1
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。