您现在的位置是:健康 >>正文

go 学习笔记之数组还是切片都没什么不一样

健康6615人已围观

简介前一篇文章详细介绍了围棋的基本语言,指出了围棋与其他主流编程语言的区别,并重点介绍了语法细节。我相信只要有一点记忆,就可以很容易地从现有的编程语言转换到围棋语言的编程习惯。虽然这种转换可能不是特别顺利...

前一篇文章详细介绍了围棋的基本语言,指出了围棋与其他主流编程语言的区别,并重点介绍了语法细节。我相信只要有一点记忆,就可以很容易地从现有的编程语言转换到围棋语言的编程习惯。虽然这种转换可能不是特别顺利,但是通过更多的练习,尤其是通过更多的尝试和错误 ,你总能慢慢感受到围棋的魅力!同样,在学习内置的围棋容器之前,让我们简单回顾一下围棋的基本语言 。了解新知识可以成为一名教师!复习前一节的知识详情,请查看微信公众号[雪梦科技帖子中值得特别注意的基本语法文章]。如果你认为它有用,请转发它。内置类型类别bool bool类型,可选真|假,默认初始化零值假。(u) int,(u) int 8,(u) int 16,(u) int 32,(u) int 64 ,uintpr 2 0 = 1,2 1 = 2 ,2 2 = 4字节长度整数。包括有符号整数、无符号整数和uintptr类型的指针类型,默认初始化值为0.byte (uint8)、rune (int32),stringbyte是uint8类型最基本的字节类型和别名,而rune是int32的Go和别名中的字符类型。不应该引入最常用的字符串类型字符串,对吗 ?浮点32、浮点64、复数64和复数128只是浮点类型的浮点类型,没有双精度类型,并且也通过字节长度来区分 。复数64是复数类型,实部和虚部由float32型复合而成。因此,这种形式的complex64被写入。内置类型特征类型转换仅具有显示转换。没有任何形式的隐式类型转换。不同变量类型之间不会自动执行隐式类型转换。围棋语言中的类型转换只是强制性的,只能显示转换。虽然提供了指针类型,但指针本身不能执行任何形式的计算。无法计算指针类型的变量。然而,存储器地址的方向可以再次改变。变量声明后有一个默认的初始化零值。可变零值取决于特定类型 。整型变量的初始化零值为0,字符串类型的初始化零值为空字符串。这并不是说无基本运算符算术运算符没有++i和--我只有i++和I--这种自增运算。没有必要再担心这两种方法之间的区别了!比较运算符= =可以比较数组是否相等。当两个阵列的尺寸等于阵列的长度时,可以比较这两个阵列。当顺序完全相同时,结果为真,否则为假。位运算符添加了位清零运算符&虽然其他主流编程语言没有这种运算符,但通过组合命令也可以实现类似的功能,但是由于提供了逐位清零运算符,因此不再需要自己组合和使用它们!过程控制语句的if条件表达式不需要小括号,并且支持变量赋值。首先 ,根据变量对临时变量进行定义和逻辑判断,然后根据不同的情况进行分类。当Go处理临时变量时,它直接增强了条件表达式,这在将来会非常常见!if条件表达式中定义的变量范围限于当前语句块条件表达式中定义的变量。这是为了方便不同分支的处理逻辑。因为它是一个临时变量,所以当前if语句块不能使用,并且变得可以理解。switch语句不能有中断。除非在使用fallthroughswitch语句的多个案例结束时没有中断,否则系统将自动执行中断处理。开关条件表达式不限于常数或整数。与其他主流编程语言相比 ,Go语言中的切换条件表达式更强大,类型也更松散。开关条件表达式可以省略。分支逻辑转向案例语言实现。switch条件表达式被省略,多种case语言执行分支流控制,其功能效果与multiple if相同。省略switch条件表达式后,每个case条件可以有多个用逗号分隔的条件。swicth语句本质上根据不同的条件执行相应的流量控制。每种情况的条件表达式支持多个,这增强了过程控制的能力。for循环的条件表达式也不需要小括号,也没有其他形式的循环。围棋语言只有for循环,没有while等其他形式的循环。for循环的初始条件。可以省略终止条件和自增表达式,也可以同时省略条件表达式,实现while循环效应,所有省略都是一个死循环。函数和参数传递函数声明是根据函数名、输入和输出的顺序定义的,并支持多个返回值 ,无论是变量定义还是函数定义 。Go总是与其他主流编程语言相反 。如果你按照输入和输出的顺序思考,你会发现。这个定义实际上很合理 。当一个函数有多个返回值时,返回值可以被命名。然而,对于呼叫者来说,没有区别。当一个函数返回多个值时,它可以有变量名。知道名字便于调用者快速熟悉函数声明,但是调用者不必根据返回值的名字接收调用结果。函数的输入没有复杂的概念,如所需参数 、可选参数等。它只支持可变参数列表 。变量参数列表与其他主流编程语言相同。它必须是最后一个输入参数的。函数参数传递只有值传递,没有引用传递,即所有变量都需要再次复制。参数传递只有值传递,这在逻辑上比较简单,但是在处理复杂的情况时,可以传递指针来实现引用传递的效果 。什么是内置容器?在复习了围棋语言的基本语法后 ,他们开始学习变量类型的载体,即容器的相关知识 。承载最基本类型变量的底部容器是数组,最高级的容器底部可以被数组封装,所以让我们先了解一下Go的数组之间的区别。数组和切片数组的声明和初始化的明显特征是一组具有特定长度的连续存储空。声明数组时必须指定数组的长度,并且初始化可以在声明的同时执行。当然,您也可以使用...语法要求编译器帮助我们确定数组的长度。func testray(t * testing . t){ vararr 1[3]intar 2:=[5]int { 1,2,3,4,5} arr3: = [...] int {2,4,6 ,8,10}/[00][1 23 45][2 46 8 10]t . log(AR1,AR2,AR3)vargrid[3][4]int//[[00 00][00 00][00 00 00]]t . log(网格)} [3] int指定数组长度为3 。元素类型是int,当然,您也可以在声明它时直接分配[5]int{1 ,2 ,3,4 ,5}。如果您懒得指定数组的长度,可以使用[...]int{2,4,6,8,10}表示。循环中数组和元素访问最常见的遍历是根据数组的索引进行访问。范围阻止方法提供了一种简化遍历便利方法。func testaratraverse(t * testing . t){ arr:=[...]I的int {2,4,6,8,10}:= 0;i <。镜头(arr);I:= ranger { t . log(arr[I])}对于I,v:= ranger { t . log(I ,v)}对于_,v:= ranger { t . log(v)} ranger可以返回索引值和索引条目。如果您只关心索引项而不关心索引值,您可以使用_ placeholder来指示您忽略了索引值。如果只关心索引值,就不能编写索引项。这种处理逻辑是连续接收函数的多个返回值,并且不会出现未使用的变量。数组是可以比较的值类型。数组是值类型,不同于其他主流编程语言,因此可以比较具有相同纬度和相同元素数量的数组。这方面的内容以前也强调过。这里 ,让我们简单回顾一下 。函数列(arr [5] int) {arr [0] = 666,v: = rangearr {fmt.println (I,v)} }函数测试列(t *测试) 。t){ var arr1[3]in tar2:=[5]int { 1,2,3,4,5}arr3 := [...]int{2 ,4,6,8,10}//[0 0 0][1 2 3 4 5][2 4 6 8 10]t . Log(arr1,arr2,arr3)//不能在printArray//printArray(arr1)fmt的参数中将arr1([3)int用作[5]int类型。Println("。打印阵列(arr 2)& quot;)printArray(arr2)fmt。Println("。打印阵列(arr 3)& quot;)printArray(arr3)//[12345][246810]t . log(arr2,arr3)}因为参数传递是值传递,所以printArray函数不能更改调用方传递的外部函数值。如果您想更改printarray函数中传递的数组内容,可以通过指针来完成,但是有没有更简单的方法呢?如果您想在printArrayByPointer函数中修改参数数组,可以通过数组指针来实现。如果你不熟悉它,你可以回头看看上一篇文章。函数printarraybypointer(arr *[5]int){ arr[0]= 666,v :=范围arr {fmt。Println(i,v)} }功能测试printArraybypointer(t *测试。t){ var arr1[3]in tar2:=[5]int { 1,2,3,4,5}arr3 := [...]int{2,4,6,8,10}//[0 0 0][1 2 3 4 5][2 4 6 8 10]t . Log(arr1,arr2,arr3)fmt。Println(" 。打印机阵列指针(阵列2)& quot;)printArraybypPoint(& amp;arr2)fmt。Println("。打印机阵列指针(阵列3)& quot;)printArraybypPoint(& amp;ARR 3)//[666 2 3 4 5][666 4 6 8 10]t . LOG(ARR 2,ARR 3)}修改数组元素可以通过传递数组指针来实现 。另外,围棋语言中的数组有一个紧密的相对切片,即切片,可以达到类似的效果。切片的声明和初始化非常类似于数组。如果在创建数组时没有指定数组的长度,那么实际上是创建切片而不是数组。func testsliceinit(t * testing . t){ var1[5]int//[0,000,000]t . log(S1)var2[]int//[]t . log(S2,莱恩(S2))} [] int未指定长度。此时创建切片,默认初始化零值为零,而不是空数组!类似地,数组可以被声明和初始化,切片也可以,语法非常相似,有一点被认为是数组!FUNC测试系统。T) {VARS1 = [5] INT {1,3,5,7,9}/[1357.9]T . LOG(S1)VARS 2 =[]INT { 1,3 ,5,7,9}/[1357.9] T.LOG (S2)}根本没有指定[的长度],最终结果变成了一片,真是令人眼花缭乱 !阵列和切片如此相似,以至于人们不得不怀疑它们之间到底发生了什么可疑的事情。事实上,切片可以从阵列中获得 。下面的例子说明了...] int {0,1,2,3,4,5,6,7,8,9}//arr =[01234456789]t . log(" arr = & quot;,arr)//arr[2:6]=[2 3 4 5]t . Log(& quot;[2:6]= & quot;,arr[2:6])//arr[:6]=[0 1 2 3 4 5]t . Log(& quot;[:6]= & quot;,arr[:6])//arr[2:]=[2 3 4 5 6 7 8 9]t . Log(& quot;arr[2:]= & quot;,arr[2:])//arr[:]=[0 1 2 3 4 5 6 7 8 9]t . Log(& quot;逮捕[:]= & quot;,arr[:])} arr[开始:结束]截取数组的一部分,结果是一个切片。切片的概念也很生动。像其他主流编程语言一样,[start:end]是一个左闭右开的区间,切片的含义也很清楚:当忽略起始索引start时,arr[:end]表示原始数组从开始到结束索引end的前一位;当忽略结束索引结束时,arr[ start:]表示原始数组从开始索引开始直到最后一位;忽略起始索引和结束索引并不常见 ,但其含义将是原始数组,但请记住,类型是切片而不是数组!到目前为止,我们知道切片与阵列非常相似。切片相对于阵列没有大小 ,那么切片和阵列的操作是否相同?函数更新切片(s[)int){ s[0]= 666 }函数测试更新切片(t *测试。[...]int{0,1,2,3,4 ,5,6,7,8,9}//arr =[0 1 2 3 4 5 6 7 8 9]t . Log(& quot;arr = & quot,arr)S1:= arr[2:6]//S1 =[2 3 4 5]t . Log(& quot;s1 = "。,S1)S2:= arr[:6]//S2 =[0 1 2 3 4 5]t . Log(& quot;s2 = "。,s2)更新切片(S1)//S1 =[666 3 4 5]测试日志(& quots1 = "。,s1)// arr = [0 1 666 3 4 5 6 7 8 9]t .对数(& quotarr = & quot ,arr)更新切片(S2)//S2 =[666 1 666 3 4 5]测试日志(& quots2 = " 。,s2)// arr = [666 1 666 3 4 5 6 7 8 9]t .对数(& quotarr = & quot,arr)}切片实际上可以改变传输参数 ,这是数组所做不到的!除非使用数组的指针类型,否则切片很容易完成?除非切片内部是指针,因为参数传递只涉及值传递,所以根本没有引用传递方法!切片和数组在参数传递中的表现不同,特别是在参数传递过程中不能修改数组。如果要更改数组,只能传递数组指针,而切片会更改数组!因为只有一种方法可以传递参数传递的值,所以假设切片内必须有指针,并且指针在参数传递过程中被传递,所以函数内的修改会影响函数外的变量。切片的内部实现有三个变量:指针ptr、数字透镜和容量上限,其中ptr指向真实的数据存储地址。正是由于slice的这种内部实现,它需要特性和表达式来使交换和数组不可分割地联系在一起。事实上,这个数据结果是静态数组的扩展,它本质上是一个动态数组,但是围棋语言被称为切片!切片是动态数组,这很容易解释。参数通过内部指针传递 ,因此尽管值通过并复制指针,但指针指向的实际元素毕竟是相同的,因此切片可以修改外部参数的值。数组在一定程度上是可以比较的,切片是动态数组,可以比较吗?让下面的测试方法验证你的猜测!我不知道你猜对了没有。切片不能比较 ,只能用零来判断。切片的添加和删除数组是静态结构,数组的大小不能扩展或缩小。这种数据结构不能满足元素数量不确定的场景。因此,会出现动态数组等切片。接下来 ,我们将关注如何添加或删除元素 。functprintslice(s[)int){ fmt . printf(“s = % v,透镜)= %d,cap = % d \ n & quot;功能测试切片自动延长(t *测试。t){ var s[]int//[]t . I的日志:= 0;i <。10;i++ {s =追加打印切片}// [0 1 2 3...,98,99]I的测试日志:= 0;i <。10;I++{s = s[1:]打印切片/[0123...,98,99]t . log .}添加元素s =追加当需要扩展时 ,每次扩展加倍,当元素s [1:]被删除时,音量减小。s = append(s,I)将元素添加到切片并返回新切片。由于切片是动态数组,当切片内的数组长度不够时,它会自动扩展以容纳新数组,扩展前后的内部数组会经历元素复制过程,所以append会返回新地址。扩展地址不是原始地址,因此有必要使用变量来接收添加的切片。当切片被连续重新截取时,s[1:],存储在切片中的元素开始收缩,数量减少 。产能也在下降。事实上,除了基于数组创建切片和直接创建切片之外 ,还有第三种创建切片的方法,即使用更多的方法 ,即制作函数。func testmaxicese (t *测试。t){ S1:= make([)int,10)//S1 = [0,000,000,000,000],len (S1) = 10,cap(S1)= 10t . logf(“S1 = % v,len(s1) = %d ,cap(s1) = %d,s1,透镜(s1) ,帽(S1))S2:= make([)int,10,32//S2 =[0 0 0 0 0 0 0 0 0 0 0],透镜(s2) = 10,帽(s2) = 32t 。日志f("。s2 = %v,镜头(s2) = %d,镜头盖(s2) = %d" 。,s2 ,len(s2),cap(s2))}初始化长度和容量可以通过make设置,这是文字切片不具备的功能 ,以这种方式创建的切片也支持批量复制功能!功能测试拷贝切片(t *测试。T) {var s1 = []int{1,3,5,7,9} var S2 = make([)int,10,32)copy(s2,s1)// s2 = [1 3 5 7 9 0 0 0 0 0],len(s2) = 10,cap(s2) = 32t。日志f("。s2 = %v,镜头(s2) = %d,镜头盖(s2) = %d" 。,s2,透镜(s2),cap(s2))变化s3 []intcopy(s3,s1)// s3 = [),透镜(s3) = 0,cap(s3) = 0t。日志f(" 。s3 = %v,len(s3) = %d ,cap(s3) = %d"。FUNC拷贝(夏令时,夏令时[)INT是切片之间拷贝的函数。令人惊讶的是,只有通过make方法创建的切片才能被复制。不明所以,如果你有任何理解,请指点!切片的底层结构是动态数组。如果切片是基于阵列切割的,那么此时的切片是从效果角度看原始阵列的视图。切片上的任何操作都将反映在原始数组上,这也是众所周知的。如果切片被再次切片,或者如果切片将跨越边界,实际上更简单。让我们演示一下。关键点是动态数组的底层结构。func testsliceoutbound(t * testing . t){ arr:=[...] int {0,1,2,3,4,5 ,6,7} S1: = arr [2: 6]//S1 = [2345],len (S1) = 4,cap(S1)= 6t . logf(“S1 = % v,len(s1) = %d,cap(s1) = %d,s1,透镜(s1),帽(S1))S2:= S1[3:5]//S2 =[5:6),透镜(s2) = 2,帽(s2) = 3t 。日志f("。s2 = %v,镜头(s2) = %d,镜头盖(s2) = %d"。,s2,len(s2),cap(s2))}[]只能访问len(arr)内的元素,而[:]只能访问cap(arr)内的元素,一般来说cap > = len所以有些情况似乎超出了界限 ,但它们并没有超出界限,只有两者的标准不同!我们知道切片的内部数据结构是基于动态数组的,并且有三个重要的变量,即指针指针指针 、数字镜头和容量上限。如果我们理解这三个变量是如何实现动态数组的,我们就不会陷入切片的深渊!数字透镜是通过下标访问时的有效范围。如果超出镜头,将报告超出范围的错误。容量上限是未来可以看到的最大范围。动态数组的本质是控制这两个变量来访问有效数组。因为s1 = [2 3 4 5],镜头(s1) = 4,镜头盖(s1) = 6,[]访问切片s1元素的范围是[0,4],所以s1[3]最多可以被访问 ,s1[4]已经越界!因为s1 = [2 3 4 5],镜头(s1) = 4,镜头盖(s1) = 6 ,[的范围:]从片段s1创建新片段是[0,6],所以最大可访问范围是s1[0:6],并且s1[3:7]已经越界!集合地图集合(Collection map collection)是由键值对组成的数据结构,其他主流编程语言也有类似的概念。相比之下,围棋中的地图可以加载更多样化的数据类型 。要使用文字值创建地图分隔线,请保留逗号、func testmap (t * testing)。t) {m1: =映射[字符串]字符串{ " author & quot:"。斯诺登1006," 。网站:"。斯诺登1006,"。语言:"。戈兰//映射[名称:snowdreams 1006站点:https://snow dreams 1006 . github . io]t . log(m1)}在一对键值对的末尾添加一个逗号,这是可以理解的,但最后一个也需要逗号,这让我无法理解为什么?默认情况下,由make创建的映射和由literal创建的映射具有不同的初始化零值。functtestampymake(t * testing . t){//空映射m1: = make(映射[字符串)int)//映射[] fallset.log (m1,M1 = = nil)//nil varm2映射[字符串)int//map [] truet.log (m2,m2 = = nil)} make函数创建的映射是空映射,而文字形式创建的映射是nil。同样的规则也适用于切片范围遍历地图是无序函数testmapraverse(t *测试)的事实。t) {m: =映射[字符串]字符串{ " name & quot:"。斯诺登1006,"。网站:"。https://snow dreams 1006 . git hub . io & quot。,}//映射[名称:snowdreams1006站点:https://snow dreams 1006 . github . io]t . Log(m)for k,v := range m {t.Log(k,V)} t . Log()for k:= range m { t . Log(k)} t . Log()for _,v: = rangem {t.log (v)}}这里再次遇到范围形式的遍历,忽略带有_ placeholder的键或值,这与数组和切片的遍历相同。唯一的区别是地图没有索引,遍历结果是无序的!获取元素时,您需要确定该元素是否具有Functestmapetitem(t * testing . t){ m:=映射[字符串]字符串{ " name & quot:"。斯诺登1006,"。网站:"。https://snow dreams 1006 . git hub . io & quot。 ,}// snowdreams1006t。日志(m[姓名])//零值为空字符串gt。日志(m[作者)//好的:=[网站];确定{日志(站点)}否则{日志(& quot密钥不存在)}}当在}}Go语言中映射得到一个不存在的键时,它将返回相应类型值的零值。地图[字符串]字符串返回的默认零值是空字符串。由于强提醒不会报告错误,这需要我们在呼叫时再做一次检查。当键值对存在时,第二个返回值返回true 。当不存在时返回false 。使用删除函数FunctestmapeleteItem(t * testing . t){ m:=映射[字符串]字符串{ " name & quot删除键值对 。:"。斯诺登1006,"。网站:" 。https://snow dreams 1006 . git hub . io & quot。 ,}//地图[名称:斯诺登1006网站:http://斯诺登1006.github.io]t.Log(m)删除(m。姓名)//地图[网站:删除日志id"。)//地图[站点:删除(地图 ,关键字)用于删除地图的键值对。如果您想验证删除是否成功,请不要忘记使用值,好的:= m[k]来确定指定的键值对是否存在,除了切片、映射、除func之外,其他类型都可以键入,因为映射是基于哈希表实现的,所以遍历是无序的。另一方面,切片、映射、函数是不可比较的,不能用作键。当然,如果自定义类型struc不包含上述类型,它也可以用作键。没必要。hashcode和equal等值可以携带func类型func testmapwidhfunvalue(t * testing . t){ m:= map[int]func(opint)int { } m[1]= func(opint)int { return op } m[2]= func(op int)int { return op * op } m[3]= func(op int)int { return op * op * op }//1 4 27t。Log(m[1](1)、M[2)(2)、M[3(3))}再一次 ,该功能是一等公民 。本章将在未来的函数编程中详细介绍它。没有setGo的默认类型甚至没有set,这在主流编程语言中是一种特殊的存在!正如Go循环只支持循环一样,由于增强了功能,循环可以在没有while循环的情况下播放 。因此,即使没有集合类型,集合效果也可以基于现有的数据结构来实现。当然,直接使用映射可以打包到set.func testpforset中,我自己)}其他{ t . Log(& quot;添加" 。我自己)}删除(我自己,1)},1)使用映射[类型]布尔封装来实现禁止重复元素的设置功能。等到解释到达面向对象的部分 ,然后很好地封装它 。这里只列出了核心结构。知识点的总结和围棋语言的梳理非常简洁。本节中的基本语法和内置容器都很好地反映了这一点。数组作为每种编程语言的基本数据结构,与其他主流编程语言没有什么不同。这是一个连续存储空。不同之处在于数组是值类型,所以也可以比较。这并不是新知识 ,毕竟上一节的内容已经详细阐述过了。本节的重点是数组的导数切片。因为数组本身是特定长度的连续空,并且因为它是不可变的,所以在其他主流编程语言中有相应的解决方案 ,其中许多底层数据结构是基于数组实现的,围棋语言也是如此。因此,我更愿意从心底里称它为动态数组!切片的设计思想非常简单。它包含三个重要变量 ,包括数组指针ptr、可访问元素长度len和分配容量cap 。当新元素连续添加到切片中时,总会达到最大分配容量。此时,切片会自动扩展,否则 ,容量会减少,从而实现动态控制的能力!指定数量的元素是一个数组,而未指定数量的元素是切片函数testarrayandslice(t * testing . t){//arrayvarrr1[3]int//slieva rar 2[]int//[0 0][]t . log(arr1,Arr2)}基于该数组创建的切片是视图函数testarrayandsliceByupdate(t * testing . t){ ARR:=[...] int {0,1,2,3,4,5 ,6,7,8 ,9}//ARR =[0123456789]t . log(" ARR = & quot;,arr)s := arr[2:6]//更新前s = [2 3 4 5],arr =[0 1 2 3 4 5 6 7 8 9]t . Logf(& quot;更新前s = %v,arr = %v"。,s,arr)s[0] = 666//更新后s = [666 3 4 5],arr =[0 1 666 3 4 5 6 7 8 9]t . Logf(& quot;更新后s = %v,arr = %v"。添加或删除切片元素都会返回新的切片功能)对于I:= 0;i <。10;i++ {s =追加(s,i)fmt。打印f(& quot;s = %v,镜头= %d,镜头盖= %dn"。,s ,len(s),cap(s))}fmt。Println(" 。从切片中移除项目)对于I:= 0;i <。10;i++ {s = s[1:]fmt。打印f(& quot;s = %v,镜头= %d,镜头盖= %d\n"。[索引]访问切片元素仅与切片的镜头相关,[开始:结束]创建新切片仅与原始切片函数testarayandslicebound的cap相关(t * testing.t) {arr: = [...] int {0,1 ,2,3,4,5 ,6,7,8 ,9}s1 := arr[5:8]// s1[0] = 5,s1[2] = 7t 。日志f(" 。s1[0] = %d,s1[%d] = %d,s1[0],透镜(s1)-1,s1[透镜(s1)-1])// s1 = [5 6 7),透镜(s1) = 3,帽(s1) = 5t。日志f("。s1 = %v,镜头(s1) = %d,镜头盖(s1) = %d"。,s1,镜头(s1 ,镜头盖(s1))s2 := s1[3:5]// s2[0] = 8,s2[1] = 9t。日志f("。s2[0] = %d ,s2[%d] = %d,s2[0],透镜(s2)-1,s2[透镜(s2)-1])// s2 = [8 9),透镜(s2) = 2 ,cap(s2) = 2t。日志f("。s2 = %v,镜头(s2) = %d,镜头盖(s2) = %d"。,s2,len(s2),cap(s2))}只有映射没有setfunc testmapandet(t * testing . t){ m:=映射[字符串]字符串{ " name & quot:" 。斯诺登1006,"。网站:"。https://snow dreams 1006 . git hub . io & quot。,"。lang"。:"。go" 。,}//好的:=[网站];确定{日志(站点)}否则{日志(& quot网站不存在)}s :=映射[字符串)bool { & quot姓名:真," 。网站:真,"。lang" 。:真,}//注意斯诺登1006if _,好:= m·[跟踪者];确定{ t . Log(& quot;关注雪花莲1006。)}其他{[}跟踪者]= true。日志(& quot注意雪堆1006。)}}delete函数删除设置的映射键值对functtestmapandsetby delete(t * testing . t){ m:=映射[字符串]字符串{ " name & quot:"。斯诺登1006,"。网站:"。https://snow dreams 1006 . git hub . io & quot 。,"。lang"。:" 。go"。,}删除(m。lang"。)//成功删除lang,ok := m[lang"。];!确定{ t . Log(& quot;成功删除lang)}}你有围棋语言的所有内置容器吗?如果声明有什么问题,请纠正我。欢迎来到公开号码[雪梦科技邮报]学习交流,每天都有所进步!

Tags:



友情链接