数组和切片
数组
定义:同一类型的元素集合
var a[3]int //定义一个数组,数组的下标是从0开始,长度为n的数组下标的有效范围是0到n-1
func arraySet() {
var a[6] int
a[0] = 1
a[1] = 2
fmt.Printf("array is %v\n",a)
var b[3]int = [3]int{1,2,3}
fmt.Println(b)
c := [...]int{1,3,4}
fmt.Println(c)
d := [3]int{10}
fmt.Println(d)
e := [3]int{2:10} // 下标为2的值设置为10
fmt.Println(e)
}
数组要保持类型一致,长度一致,这样才能做等值的赋值
数组遍历
func loopArray() {
a := [...]int{1,2,3,4,5,6,7,8,9,10}
for index,val := range a {
fmt.Printf("index:%d\tvalue:%d\n",index,val)
}
b := [6]string{"a","b","c","d","e","f"}
for i:=0;i<len(b);i++ {
fmt.Printf("index:%d\tvalue:%s\n",i,b[i])
}
}
二维数组与遍历
func doubleArray() {
var a[3][2]string = [3][2]string{
{"lion","tiger"},
{"cat","dog"},
{"pig","pigwan"},
}
fmt.Println(a)
}
func printArray(a[3][2]string) {
for _,v1 := range a {
for _,v2 := range v1 {
fmt.Printf("%s\n",v2)
}
fmt.Printf("\n")
}
}
func main() {
loopArray()
doubleArray()
var b[3][2] string
b[0][0] = "apple"
b[0][1] = "banana"
b[1][0] = "sumsung"
b[1][1] = "huawei"
b[2][0] = "茄子"
b[2][1] = "鸡儿"
printArray(b)
}
数组拷贝和传参
- 数组是值类型
func transArray() {
var a [3]int
a[0] = 10
a[1] = 20
a[2] = 30
b := a
b[0] = 1000
fmt.Println(a,b)
fmt.Printf("%p\t%p\n",&a,&b)
}
func modifyB(b [3]int) {
b[0] = 1000
return
}
切片
定义
- 基于数组类型的一层封装。非常灵活,可以扩容
- 切片初始化,a[start:end]创建一个包括从start到end-1的切片
- 数组是值类型,切片是引用类型
func modifySlice() {
//定义数组
darr := [...]int{157,89,90,82,100,78,67,69,59}
// 创建切片
dslice := darr[2:5]
fmt.Printf("slice before %v\n",dslice)
fmt.Printf("array before %v\n",darr)
for i := range dslice {
dslice[i] ++
}
fmt.Printf("array after %v\n",darr)
fmt.Printf("after slice %v\n",dslice)
}
切片的基本操作
- arr[start:end] : 包括start到end-1之间的所有元素
- arr[start:] : 包括start开始到最后一个元素之间所有的元素
- arr[:end]: 包括从0开始到end-1之间的所有元素
- arr[:] :包括整个数组所有的元素
使用make创建切片
func makeSlice() {
i := make([]int,5,10)
i[0] = 0
i[1] = 1
i[2] = 2
i[3] = 3
i = append(i, 5) //从长度+1开始append
i = append(i,6,7,8,9,10,11,12,13) // 追加多个值,自动扩容
fmt.Printf("%v\tlen %d\tcap %d\n",i,len(i),cap(i))
}
切片拷贝
func rewriteSlice() {
var a[]int = make([]int,5,5)
b := a
fmt.Printf("【修改前】a的地址%p,a的值%v;b的地址%p,b的值%v\n",&a,a,&b,b)
a = append(a,10) //a的地址和
fmt.Printf("【修改后】a的地址%p,a的值%v;b的地址%p,b的值%v\n",&a,a,&b,b)
}
切片的再切片
func sliceAgain() {
var a []int
var b [6]int = [6]int{1,2,3,4,5,6}
a = b[0:4]
fmt.Printf("a的长度%d,容量%d,类型%T\n",len(a),cap(a),a)
c := b[1:4]
fmt.Printf("c的长度%d,容量%d,类型%T\n",len(c),cap(c),c) //c的长度是3,容量是5,因为开头从1开始,引用底层的b也就少了一位
d := a[0:2]
fmt.Printf("d的长度%d,容量%d,类型%T\n",len(d),cap(d),d) //d是a的切片的再切片,所以容量和a一致,长度以截取的长度为准
}
空切片
var a []int //未被初始化,没有分配长度和容量(没有内存空间),所以称之为空切片,append可以自动扩容,免去初始化的过程,nil是个空地址的意思
func noneSlice() {
var name []string
if name == nil {
fmt.Printf("this is none slice %v\n",name)
name = append(name, "wanghui","devops")
fmt.Printf("none slice append value %v\n",name)
}
}
// 切片的append
func appendSlice() {
var b []int = []int{1,2,3,4}
var a []int
a = append(a,b...) //在a里面追加b(...就是展开b的元素的意思)
}
切片传参
证明切片是引用传递
func transArgs(a []int) {
fmt.Printf("%p\n",a)
for i := range a{
a[i] = 111
fmt.Println(a[i])
}
}
func main() {
nums := []int{1,2,3,4}
fmt.Printf("%p\n",nums)
transArgs(nums)
fmt.Printf("%p\n",nums) // 参数会被改变
}
切片的拷贝
copy(dest,src)
拷贝之后,各自的地址不会发生改变,只是拷贝目的地的值发生了改变
func copySlice() {
a := []int{1,2,3}
b := []int{7,8}
copy(b,a)
fmt.Printf("a=%v,len(a)=%d,addr(a)=%p\tb=%v,len(b)=%d,addr(b)=%p\n",
a,len(a),&a,
b,len(b),&b)
}
课后作业与参考
- 求数组的所有元素之和
func arraySum() {
var arr [10]int
for i:=0;i<len(arr);i++ {
arr[i] = rand.Intn(10000)
}
var sum int
for j:=0;j<len(arr);j++ {
sum += arr[j]
}
fmt.Printf("arr is %v\nsum=%d\n",arr,sum)
}
- 找出数组中指定元素相加等于8的下标
比如 arr := []int{1,3,5,8,7} ,下标分别是(0,4),(1,2)
func indexReturn() {
//gen array
var arr [10]int
for i:=0;i<len(arr);i++ {
arr[i] = i
}
//calc
fmt.Println(arr)
for i:=0;i<len(arr);i++ {
for j:=i+1;j<len(arr);j++ {
if (arr[j]+arr[i]==12) {
fmt.Printf("arr下标和等于12的下标是i=%d,j=%d\n",i,j)
}
}
}
}
- 使用sort函数进行数组排序
func useSort() {
var arr [10]int
for i:=0;i<len(arr);i++ {
arr[i] = rand.Intn(10000)
}
fmt.Printf("before sort %v\n",arr)
sort.Ints(arr[:])
fmt.Printf("after sort %v\n",arr)
}
- 实现一个密码生成工具,支持以下功能
- 指定密码长度,默认16位
- 使用类型选择,生成不同类型的密码
package main
import (
"flag"
"fmt"
"math/rand"
"time"
)
var (
numCharset = "0123456789"
strCharset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
mixCharset = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
advanceCharset = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()"
)
func geneLetter() {
//获取26个字母
start := 'A'
for i:=0;i<26;i++{
fmt.Printf("%c",start)
start += 1
}
}
func main() {
var length int
var charset string
flag.IntVar(&length,"l",16,"-l the length of passwd")
flag.StringVar(&charset,"t","mix","-t the charset of passwd")
flag.Parse()
rand.Seed(time.Now().UnixNano())
var userCharset string
switch charset {
case "num":
userCharset = numCharset
case "char":
userCharset = strCharset
case "mix":
userCharset = mixCharset
case "advance":
userCharset = advanceCharset
default:
userCharset = mixCharset
}
var password []byte
for i:=0;i < length;i++ {
index := rand.Intn(len(userCharset))
char := userCharset[index]
password = append(password,char)
}
strPassword := string(password)
fmt.Printf("生成的密码是%s\n",strPassword)
}
有疑问加站长微信联系(非本文作者)