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) }