本文目录一览:
- 1、go语言中数组使用的注意事项和细节
- 2、golang - channel
- 3、利用go语言实现求数组交集的算法
- 4、go语言的多维数组怎么写
- 5、golang中数组和slice作为参数的区别
- 6、Golang 中数组(Array)和切片(Slice)的区别
go语言中数组使用的注意事项和细节
1、数组是多个 相同类型 的数据的组合,一个数组一旦声明/定义了,其 长度是固定的,不能动态变化 。
2、var arr []int 这时arr就是一个slice 切片 。
3、数组中的元素可以是任何数据类型,包括值类型和引用类型,但是 不能混用 。
4、数组创建后,如果没有赋值,有默认值如下:
数值类型数组: 默认值为 0
字符串数组: 默认值为 ""
bool数组: 默认值为 false
5、使用数组的步骤:
(1)声明数组并开辟空间
(3)给数组各个元素赋值
(3)使用数组
6、数组的下标是从0开始的。
7、数组下标必须在指定范围内使用,否则报panic:数组越界,比如var arr [5]int的有效下标为0~4.
8、Go的数组属于 值类型 ,在默认情况下是 值传递 ,因此会进行值拷贝。 数组间不会相互影响。
9、如想在其他函数中去修改原来的数组,可以使用 引用传递 (指针方式)。
10、长度是数组类型的一部分,在传递函数参数时,需要考虑数组的长度,看以下案例:
题1:编译错误,因为不能把[3]int类型传递给[]int类型,前者是数组,后者是切片;
题2:编译错误,因为不能把[3]int类型传递给[4]int类型;
题3:编译正确,因为[3]int类型传给[3]int类型合法。
golang - channel
通过var声明或者make函数创建的channel变量是一个存储在函数栈帧上的指针,占用8个字节,指向堆上的hchan结构体
源码包中src/runtime/chan.go定义了hchan的数据结构如下:
hchan结构体的主要组成部分有四个:
用来保存goroutine之间传递数据的循环数组:buf
用来记录此循环数组当前发送或接收数据的下标值:sendx和recvx
用于保存向该chan发送和从该chan接收数据被阻塞的goroutine队列: sendq 和 recvq
保证channel写入和读取数据时线程安全的锁:lock
环形数组作为channel 的缓冲区 数组的长度就是定义channnel 时channel 的缓冲大小
在hchan 中包括了读/写 等待队列, waitq是一个双向队列,包括了一个头结点和尾节点。 每个节点是一个sudog结构体变量
channel有2种类型:无缓冲、有缓冲, 在创建时 make(chan type cap) 通过cap 设定缓冲大小
channel有3种模式:写操作模式(单向通道)、读操作模式(单向通道)、读写操作模式(双向通道)
channel有3种状态:未初始化、正常、关闭
如下几种状态会引发panic
channel 是线程安全的,channel的底层实现中,hchan结构体中采用Mutex锁来保证数据读写安全。在对循环数组buf中的数据进行入队和出队操作时,必须先获取互斥锁,才能操作channel数据
利用go语言实现求数组交集的算法
题目: 给定两个数组,编写一个函数来计算它们的交集.(来自 leecode(349) )
示例 1:
输入:nums1 = [1,2,2,1], nums2 = [2,2] 输出:[2] 示例 2:
输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4] 输出:[9,4]
说明:
我的解法:
题目同上,只不过在输出的时候
输出结果中每个元素出现的次数,应与元素在两个数组中出现的次数一致。
示例 1:
输入:nums1 = [1,2,2,1], nums2 = [2,2] 输出:[2,2] 示例 2:
输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4] 输出:[9,4]
解法
如果给定的数组是排好序的,
arr1 = [1,2,3,4,4,13],arr2 = [1,2,3,9,10]
那这个返回值该如何获取得两个数组的交集呢?
解法
go语言的多维数组怎么写
package main
import "fmt"
var arr [2]int //申明一个数组
func main() {
arr[0] = 1 //数组赋值
fmt.Println(arr)
arrtest := [3]int{1, 2, 3} //数组的另一种申明方式
fmt.Println(arrtest)
a := [...]int{1, 2} //[...]自动识别数组的长度
fmt.Println(a)
fmt.Println(len(a))//输出数组的长度
}
下边是slice的申明和使用其实这就是一种动态的数组
复制代码 代码如下:
package main
import "fmt"
func main() {
d := []int{1, 2, 3} //申明一个slice这个是动态的数组,没有长度
fmt.Println(d)
var q, w []int
q = d[0:1] //可以定取得上边的长度
w = d[1:3]
d = append(d, 2) //向其中添加元素
fmt.Println(d)
fmt.Println(q, w)
}
golang中数组和slice作为参数的区别
最主要的区别是:slice支持负数的下标(代表从字符串结尾开始算位置),substring不支持
substring() 方法用于提取字符串中介于两个指定下标之间的字符。主要用于字符串截取
stringObject.substring(start,stop)
start:必需。一个非负的整数,规定要提取的子串的第一个字符在 stringObject 中的位置。
end:可选。一个非负的整数,比要提取的子串的最后一个字符在 stringObject 中的位置多 1。
如果省略该参数,那么返回的子串会一直到字符串的结尾。
例如:"abcdefg".substring(3,5)返回de,字符串的第3个字符是d(从0开始,即a是第0个字符),截取到第5个字符前(不包括第5个)
与 slice()方法不同的是,substring() 不接受负的参数。
slice() 方法可提取字符串的某个部分,并以新的字符串返回被提取的部分。
stringObject.slice(start,end)
start:要抽取的片断的起始下标。如果是负数,则该参数规定的是从字符串的尾部开始算起的位置。也就是说,-1 指字符串的最后一个字符,-2 指倒数第二个字符,以此类推。
end:紧接着要抽取的片段的结尾的下标。若未指定此参数,则要提取的子串包括 start 到原字符串结尾的字符串。如果该参数是负数,那么它规定的是从字符串的尾部开始算起的位置。
slice() 比 substring() 要灵活一些,因为它允许使用负数作为参数。
Golang 中数组(Array)和切片(Slice)的区别
Go 中数组的长度是不可改变的,而 Slice 解决的就是对不定长数组的需求。他们的区别主要有两点。
数组:
切片:
注意 1
虽然数组在初始化时也可以不指定长度,但 Go 语言会根据数组中元素个数自动设置数组长度,并且不可改变。切片通过 append 方法增加元素:
如果将 append 用在数组上,你将会收到报错:first argument to append must be slice。
注意 2
切片不只有长度(len)的概念,同时还有容量(cap)的概念。因此切片其实还有一个指定长度和容量的初始化方式:
这就初始化了一个长度为3,容量为5的切片。
此外,切片还可以从一个数组中初始化(可应用于如何将数组转换成切片):
上述例子通过数组 a 初始化了一个切片 s。
当切片和数组作为参数在函数(func)中传递时,数组传递的是值,而切片传递的是指针。因此当传入的切片在函数中被改变时,函数外的切片也会同时改变。相同的情况,函数外的数组则不会发生任何变化。