listen_8_切片
1.切?定义
2. 切?基本操作 ?录
3. 切?传参
4. make和new的区别
5. 课后练习
1. 切?是基于数组类型做的?层封装。它?常灵活,可以?动扩容
var a []int //定义?个int类型的空切?
2. 切?初始化, a[start:end]创建?个包括从start到end-1的切?
func main() { a := [5]int{76, 77, 78, 79, 80} var b []int = a[1:4] //基于数组a创建?个切?,包括元素a[1] a[2] a[3] fmt.Println(b) }
3. 切?初始化?法2
c := []int{6, 7, 8} //创建?个数组并返回?个切?
5. 数组切?的基本操作 切?基本操作 a) arr[start:end]:包括start到end-1(包括end-1)之间的所有元素 b) arr[start:]:包括start到arr最后?个元素(包括最后?个元素)之间的所有元素 c) arr[:end]:包括0到end-1(包括end-1)之间的所有元素 d) arr[:]:包括整个数组的所有元素
//创建?个数组,其中[…]是编译器确定数组的?度,darr的?度是9 darr := [...]int{57, 89, 90, 82, 100, 78, 67, 69, 59} //基于darr创建?个切?dslice,包括darr[2],darr[3],darr[4]三个元素 dslice := darr[2:5] fmt.Println("array before",darr)
7. 使?make创建切?
//[]中没有?度 i := make([]int, 5, 5) //第一个5 为切片长度,第二个为切片的容量,,切片可以append
9. 切?的再切?
fruitarray := […]string{ "apple", "orange", "grape", "mango", "water melon", "pine apple", "chikoo"} fruitslice := fruitarray[1:3] //?度是2, 容量是6 fmt.Printf("length of slice %d capacity %d\n", len(fruitslice), cap(fruitslice)) //再重新进?切?,不能?于数组fruitarray的?度,否则越界 fruitslice = fruitslice[:cap(fruitslice)]
10.append操作
cars := []string{"Ferrari", "Honda", “Ford"} //?度和容量都等于3 fmt.Println("cars:", cars, "has old length", len(cars), "and capacity", cap(cars)) cars = append(cars, “Toyota") //容量等于6 ,超过原有的长度之后,容量每次是按倍数增加的 fmt.Println("cars:", cars, "has new length", len(cars), "and capacity", cap(cars))
空切片
//定义names是?个空切?,?度和容量都等于0 //不能对空切?进?访问,否则panic var names []string if names == nil { fmt.Println("slice is nil going to append") names = append(names, "John", "Sebastian", "Vinay") fmt.Println("names contents:",names)
append?个切?
veggies := []string{"potatoes","tomatoes","brinjal"} fruits := []string{“oranges","apples"} //fruits后?的3个点表示展开fruits切?成?个个元素 food := append(veggies, fruits...)
//在函数内部修改numbers切?的值;;切片作为传参 func subtactOne(numbers []int) { for i := range numbers { numbers[i] -= 2 } }
切片拷贝
veggies := []string{"potatoes","tomatoes","brinjal"} fruits := []string{“oranges","apples"} copy(veggies, fruits)
切片遍历
for index, val := range b { }
//和数组遍历是?样的
make和new区别
6. make为内建类型slice、map和channel分配内存。 //初始化?个切? s := make([]int, 10, 30) 17. new?于各种类型的内存分配,new返回是?个指针
题
1. 下列程序输出什么? 练习 func main() { var sa = make ([]string,5,10); for i:=0;i<10;i++{ sa=append(sa, fmt.Sprintf("%v",i)) } fmt.Println(sa); } 2. 使?golang标准包 “sort”对数组进?排序 3. 实现?个密码?成?具,?持以下功能: a) ?户可以通过-l指定?成密码的?度 b) ?户可以通过-t指定?成密码的字符集,?如-t num?成全数字的密码 -t char ?成包含全英?字符的密码,-t mix包含?成数字和英?的密码, -t advance ?成包含数字、英?以及特殊字符的密码
package main import ( "flag" "fmt" "math/rand" "time" ) var ( length int charset string ) const ( NumStr = "0123456789" CharStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" SpecStr = "+=-@#~,.[]()!%^*$" ) func parseArgs() { flag.IntVar(&length, "l", 16, "-l 生成密码的长度") flag.StringVar(&charset, "t", "num", `-t 制定密码生成的字符集, num:只使用数字[0-9], char:只使用英文字母[a-zA-Z], mix: 使用数字和字母, advance:使用数字、字母以及特殊字符`) flag.Parse() } func test1() { for i := 0; i < len(CharStr); i++ { if CharStr[i] != ' ' { fmt.Printf("%c", CharStr[i]) } } } func generatePasswd() string { var passwd []byte = make([]byte, length, length) var sourceStr string if charset == "num" { sourceStr = NumStr } else if charset == "char" { sourceStr = CharStr } else if charset == "mix" { sourceStr = fmt.Sprintf("%s%s", NumStr, CharStr) } else if charset == "advance" { sourceStr = fmt.Sprintf("%s%s%s", NumStr, CharStr, SpecStr) } else { sourceStr = NumStr } //fmt.Println("source:", sourceStr) for i := 0; i < length; i++ { index := rand.Intn(len(sourceStr)) passwd[i] = sourceStr[index] } return string(passwd) } func main() { rand.Seed(time.Now().UnixNano()) parseArgs() //fmt.Printf("length:%d charset:%s\n", length, charset) //test1() passwd := generatePasswd() fmt.Println(passwd) }