package mainimport (
"fmt"
)
func printArray(myArray [4]int) {
// 值拷贝
for index, value := range myArray {
fmt.Println("index = ", index, " , value = ", value)
}
myArray[0] = 233
}
func main() {
// 固定长度数组
var myArray1 [10]int
var myArray2 [10]float32
myArray3 := [10]int{1, 2, 3, 4}
myArray4 := [4]int{11, 22, 33, 44}
// for i := 0; i < 10; i ++ {
for i := 0; i < len(myArray1); i++ {
fmt.Println(myArray1[i])
}
fmt.Println("===== ===== ===== =====")
for j := 0; j < len(myArray2); j++ {
fmt.Println(myArray2[j])
}
fmt.Println("===== ===== ===== =====")
for index, value := range myArray3 {
fmt.Println("index= ", index, ", value = ", value)
}
// 查看数组的数据类型
fmt.Printf("myArray1 types = %T\n", myArray1)
fmt.Printf("myArray2 types = %T\n", myArray2)
fmt.Printf("myArray3 types = %T\n", myArray3)
fmt.Printf("myArray4 types = %T\n", myArray4)
fmt.Println("===== ===== ===== =====")
printArray(myArray4)
fmt.Println("=====")
for index, value := range myArray4 {
fmt.Println("index = ", index, ", value = ", value)
}
}
package mainimport (
"fmt"
)
// func printArray(myArray [4]int) {
// // 值拷贝
// for index, value := range myArray {
// fmt.Println("index = ", index, " , value = ", value)
// }
// myArray[0] = 233
// }
func printSlice(myArray []int) {
// 引用传递
// Slice 和 数组相比的一个好处是可变长度,这为形参的参数值长度提供了更多的可能性,更加灵活了
// 动态数组是指向数组内存的指针(引用)
for _, value := range myArray {
fmt.Println("value = ", value)
}
myArray[0] = 233
}
func main() {
// // 固定长度数组
// var myArray1 [10]int
// var myArray2 [10]float32
// myArray3 := [10]int{1, 2, 3, 4}
// myArray4 := [4]int{11, 22, 33, 44}
// // for i := 0; i < 10; i ++ {
// for i := 0; i < len(myArray1); i++ {
// fmt.Println(myArray1[i])
// }
// fmt.Println("===== ===== ===== =====")
// for j := 0; j < len(myArray2); j++ {
// fmt.Println(myArray2[j])
// }
// fmt.Println("===== ===== ===== =====")
// for index, value := range myArray3 {
// fmt.Println("index= ", index, ", value = ", value)
// }
// // 查看数组的数据类型
// fmt.Printf("myArray1 types = %T\n", myArray1)
// fmt.Printf("myArray2 types = %T\n", myArray2)
// fmt.Printf("myArray3 types = %T\n", myArray3)
// fmt.Printf("myArray4 types = %T\n", myArray4)
// fmt.Println("===== ===== ===== =====")
// printArray(myArray4)
// fmt.Println("=====")
// for index, value := range myArray4 {
// fmt.Println("index = ", index, ", value = ", value)
// }
// var myArray5 [10]int
myArray := []int{1, 2, 3, 4} // 动态数组 切片 slice
fmt.Printf("myArray type is %T\n", myArray)
printSlice(myArray)
fmt.Println("===== ===== ===== =====")
// printSlice(myArray5)
for _, value := range myArray {
fmt.Println("value = ", value)
}
}
package mainimport (
"fmt"
)
// func printArray(myArray [4]int) {
// // 值拷贝
// for index, value := range myArray {
// fmt.Println("index = ", index, " , value = ", value)
// }
// myArray[0] = 233
// }
// func printSlice(myArray []int) {
// // 引用传递
// // Slice 和 数组相比的一个好处是可变长度,这为形参的参数值长度提供了更多的可能性,更加灵活了
// // 动态数组是指向数组内存的指针(引用)
// for _, value := range myArray {
// fmt.Println("value = ", value)
// }
// myArray[0] = 233
// }
func main() {
// // 固定长度数组
// var myArray1 [10]int
// var myArray2 [10]float32
// myArray3 := [10]int{1, 2, 3, 4}
// myArray4 := [4]int{11, 22, 33, 44}
// // for i := 0; i < 10; i ++ {
// for i := 0; i < len(myArray1); i++ {
// fmt.Println(myArray1[i])
// }
// fmt.Println("===== ===== ===== =====")
// for j := 0; j < len(myArray2); j++ {
// fmt.Println(myArray2[j])
// }
// fmt.Println("===== ===== ===== =====")
// for index, value := range myArray3 {
// fmt.Println("index= ", index, ", value = ", value)
// }
// // 查看数组的数据类型
// fmt.Printf("myArray1 types = %T\n", myArray1)
// fmt.Printf("myArray2 types = %T\n", myArray2)
// fmt.Printf("myArray3 types = %T\n", myArray3)
// fmt.Printf("myArray4 types = %T\n", myArray4)
// fmt.Println("===== ===== ===== =====")
// printArray(myArray4)
// fmt.Println("=====")
// for index, value := range myArray4 {
// fmt.Println("index = ", index, ", value = ", value)
// }
// var myArray5 [10]int
// myArray := []int{1, 2, 3, 4} // 动态数组 切片 slice
// fmt.Printf("myArray type is %T\n", myArray)
// printSlice(myArray)
// fmt.Println("===== ===== ===== =====")
// // printSlice(myArray5)
// for _, value := range myArray {
// fmt.Println("value = ", value)
// }
// 声明 slice 的 4 种方法
// 1. 声明 slice1 是一个切片,并且初始化,默认值是 1, 2, 3,长度 len 是 3
slice1 := []int{1, 2, 3}
fmt.Printf("len = %d, slice1 = %v\n", len(slice1), slice1)
// 2. 声明 slice2 是一个切片,但是此时并未给 slice2 分配内存空间
// 此时无法为 slice2[0] = 1 赋值,会提示越界错误
var slice2 []int
// 可以通过 make 开辟内存空间
slice2 = make([]int, 3)
slice2[0] = 233
fmt.Printf("len = %d, slice2 = %v\n", len(slice2), slice2)
// 3. 声明 slice3 是一个切片,同时为 slice3 分配内存空间,3 个空间,初始化值为 0
var slice3 []int = make([]int, 3)
fmt.Printf("len = %d, slice3 = %v\n", len(slice3), slice3)
// 4. 声明 slice4 是一个切片,同时为 slice4 分配内存空间,4 个空间,初始化值为 0,通过 := 推导出 slice4 是一个切片
slice4 := make([]int, 4)
fmt.Printf("len = %d, slice4 = %v\n", len(slice4), slice4)
// 判断 slice 是否为空
var slice5 []int
if slice5 == nil {
fmt.Println("slice5 is nil,是一个空切片")
} else {
fmt.Println("slice5 是有空间的")
}
}
切片的长度(len)和容量(cap)不同,长度表示左指针及右指针之间的距离,容量表示左指针至底层数组末尾的距离。
切片的扩容机制,append() 的时候,如果长度增加后超过容量,则将容量增加 2 倍。
package mainimport (
"fmt"
)
// func printArray(myArray [4]int) {
// // 值拷贝
// for index, value := range myArray {
// fmt.Println("index = ", index, " , value = ", value)
// }
// myArray[0] = 233
// }
// func printSlice(myArray []int) {
// // 引用传递
// // Slice 和 数组相比的一个好处是可变长度,这为形参的参数值长度提供了更多的可能性,更加灵活了
// // 动态数组是指向数组内存的指针(引用)
// for _, value := range myArray {
// fmt.Println("value = ", value)
// }
// myArray[0] = 233
// }
func main() {
// // 固定长度数组
// var myArray1 [10]int
// var myArray2 [10]float32
// myArray3 := [10]int{1, 2, 3, 4}
// myArray4 := [4]int{11, 22, 33, 44}
// // for i := 0; i < 10; i ++ {
// for i := 0; i < len(myArray1); i++ {
// fmt.Println(myArray1[i])
// }
// fmt.Println("===== ===== ===== =====")
// for j := 0; j < len(myArray2); j++ {
// fmt.Println(myArray2[j])
// }
// fmt.Println("===== ===== ===== =====")
// for index, value := range myArray3 {
// fmt.Println("index= ", index, ", value = ", value)
// }
// // 查看数组的数据类型
// fmt.Printf("myArray1 types = %T\n", myArray1)
// fmt.Printf("myArray2 types = %T\n", myArray2)
// fmt.Printf("myArray3 types = %T\n", myArray3)
// fmt.Printf("myArray4 types = %T\n", myArray4)
// fmt.Println("===== ===== ===== =====")
// printArray(myArray4)
// fmt.Println("=====")
// for index, value := range myArray4 {
// fmt.Println("index = ", index, ", value = ", value)
// }
// var myArray5 [10]int
// myArray := []int{1, 2, 3, 4} // 动态数组 切片 slice
// fmt.Printf("myArray type is %T\n", myArray)
// printSlice(myArray)
// fmt.Println("===== ===== ===== =====")
// // printSlice(myArray5)
// for _, value := range myArray {
// fmt.Println("value = ", value)
// }
// // 声明 slice 的 4 种方法
// // 1. 声明 slice1 是一个切片,并且初始化,默认值是 1, 2, 3,长度 len 是 3
// slice1 := []int{1, 2, 3}
// fmt.Printf("len = %d, slice1 = %v\n", len(slice1), slice1)
// // 2. 声明 slice2 是一个切片,但是此时并未给 slice2 分配内存空间
// // 此时无法为 slice2[0] = 1 赋值,会提示越界错误
// var slice2 []int
// // 可以通过 make 开辟内存空间
// slice2 = make([]int, 3)
// slice2[0] = 233
// fmt.Printf("len = %d, slice2 = %v\n", len(slice2), slice2)
// // 3. 声明 slice3 是一个切片,同时为 slice3 分配内存空间,3 个空间,初始化值为 0
// var slice3 []int = make([]int, 3)
// fmt.Printf("len = %d, slice3 = %v\n", len(slice3), slice3)
// // 4. 声明 slice4 是一个切片,同时为 slice4 分配内存空间,4 个空间,初始化值为 0,通过 := 推导出 slice4 是一个切片
// slice4 := make([]int, 4)
// fmt.Printf("len = %d, slice4 = %v\n", len(slice4), slice4)
// // 判断 slice 是否为空
// var slice5 []int
// if slice5 == nil {
// fmt.Println("slice5 is nil,是一个空切片")
// } else {
// fmt.Println("slice5 是有空间的")
// }
// slice 切片的长度是 3,容量是 5
var slice6 = make([]int, 3, 5)
fmt.Printf("len = %d, cap = %d, slice6 = %v\n", len(slice6), cap(slice6), slice6)
// 向 slice6 中添加元素 1,此时 len = 4,cap = 5,[0 0 0 1]
slice6 = append(slice6, 1)
fmt.Printf("len = %d, cap = %d, slice6 = %v\n", len(slice6), cap(slice6), slice6)
slice6 = append(slice6, 2)
fmt.Printf("len = %d, cap = %d, slice6 = %v\n", len(slice6), cap(slice6), slice6)
// 像一个 slice 容量满了的 slice 中追加元素,Golang 会在底层开辟一定量等长的内存空间,如 原来的容量是 5,则现在的容量为 10
// cap = 10
slice6 = append(slice6, 3)
fmt.Printf("len = %d, cap = %d, slice6 = %v\n", len(slice6), cap(slice6), slice6)
fmt.Println("===== ===== ===== ===== =====")
// 如果没指定 cap,则 cap = len
var number2 = make([]int, 3)
fmt.Printf("len = %d, cap = %d, number2 = %v\n", len(number2), cap(number2), number2)
// cap = 6
number2 = append(number2, 111)
fmt.Printf("len = %d, cap = %d, number2 = %v\n", len(number2), cap(number2), number2)
}
slice 截取后,两个 slice 仍然指向相同的内存空间。可以通过 copy() 函数,将两个 slice 指向不同的内存空间。(深拷贝,拷贝一个副本,将底层数组的 slice 一起进行拷贝。)
package mainimport (
"fmt"
)
// func printArray(myArray [4]int) {
// // 值拷贝
// for index, value := range myArray {
// fmt.Println("index = ", index, " , value = ", value)
// }
// myArray[0] = 233
// }
// func printSlice(myArray []int) {
// // 引用传递
// // Slice 和 数组相比的一个好处是可变长度,这为形参的参数值长度提供了更多的可能性,更加灵活了
// // 动态数组是指向数组内存的指针(引用)
// for _, value := range myArray {
// fmt.Println("value = ", value)
// }
// myArray[0] = 233
// }
func main() {
// // 固定长度数组
// var myArray1 [10]int
// var myArray2 [10]float32
// myArray3 := [10]int{1, 2, 3, 4}
// myArray4 := [4]int{11, 22, 33, 44}
// // for i := 0; i < 10; i ++ {
// for i := 0; i < len(myArray1); i++ {
// fmt.Println(myArray1[i])
// }
// fmt.Println("===== ===== ===== =====")
// for j := 0; j < len(myArray2); j++ {
// fmt.Println(myArray2[j])
// }
// fmt.Println("===== ===== ===== =====")
// for index, value := range myArray3 {
// fmt.Println("index= ", index, ", value = ", value)
// }
// // 查看数组的数据类型
// fmt.Printf("myArray1 types = %T\n", myArray1)
// fmt.Printf("myArray2 types = %T\n", myArray2)
// fmt.Printf("myArray3 types = %T\n", myArray3)
// fmt.Printf("myArray4 types = %T\n", myArray4)
// fmt.Println("===== ===== ===== =====")
// printArray(myArray4)
// fmt.Println("=====")
// for index, value := range myArray4 {
// fmt.Println("index = ", index, ", value = ", value)
// }
// var myArray5 [10]int
// myArray := []int{1, 2, 3, 4} // 动态数组 切片 slice
// fmt.Printf("myArray type is %T\n", myArray)
// printSlice(myArray)
// fmt.Println("===== ===== ===== =====")
// // printSlice(myArray5)
// for _, value := range myArray {
// fmt.Println("value = ", value)
// }
// // 声明 slice 的 4 种方法
// // 1. 声明 slice1 是一个切片,并且初始化,默认值是 1, 2, 3,长度 len 是 3
// slice1 := []int{1, 2, 3}
// fmt.Printf("len = %d, slice1 = %v\n", len(slice1), slice1)
// // 2. 声明 slice2 是一个切片,但是此时并未给 slice2 分配内存空间
// // 此时无法为 slice2[0] = 1 赋值,会提示越界错误
// var slice2 []int
// // 可以通过 make 开辟内存空间
// slice2 = make([]int, 3)
// slice2[0] = 233
// fmt.Printf("len = %d, slice2 = %v\n", len(slice2), slice2)
// // 3. 声明 slice3 是一个切片,同时为 slice3 分配内存空间,3 个空间,初始化值为 0
// var slice3 []int = make([]int, 3)
// fmt.Printf("len = %d, slice3 = %v\n", len(slice3), slice3)
// // 4. 声明 slice4 是一个切片,同时为 slice4 分配内存空间,4 个空间,初始化值为 0,通过 := 推导出 slice4 是一个切片
// slice4 := make([]int, 4)
// fmt.Printf("len = %d, slice4 = %v\n", len(slice4), slice4)
// // 判断 slice 是否为空
// var slice5 []int
// if slice5 == nil {
// fmt.Println("slice5 is nil,是一个空切片")
// } else {
// fmt.Println("slice5 是有空间的")
// }
// // slice 切片的长度是 3,容量是 5
// var slice6 = make([]int, 3, 5)
// fmt.Printf("len = %d, cap = %d, slice6 = %v\n", len(slice6), cap(slice6), slice6)
// // 向 slice6 中添加元素 1,此时 len = 4,cap = 5,[0 0 0 1]
// slice6 = append(slice6, 1)
// fmt.Printf("len = %d, cap = %d, slice6 = %v\n", len(slice6), cap(slice6), slice6)
// slice6 = append(slice6, 2)
// fmt.Printf("len = %d, cap = %d, slice6 = %v\n", len(slice6), cap(slice6), slice6)
// // 像一个 slice 容量满了的 slice 中追加元素,Golang 会在底层开辟一定量等长的内存空间,如 原来的容量是 5,则现在的容量为 10
// // cap = 10
// slice6 = append(slice6, 3)
// fmt.Printf("len = %d, cap = %d, slice6 = %v\n", len(slice6), cap(slice6), slice6)
// fmt.Println("===== ===== ===== ===== =====")
// // 如果没指定 cap,则 cap = len
// var number2 = make([]int, 3)
// fmt.Printf("len = %d, cap = %d, number2 = %v\n", len(number2), cap(number2), number2)
// // cap = 6
// number2 = append(number2, 111)
// fmt.Printf("len = %d, cap = %d, number2 = %v\n", len(number2), cap(number2), number2)
// len = 3, cap = 3
s := []int{111, 222, 333}
// 左闭右开 [0, 1)
s1 := s[0:1]
fmt.Printf("s1 = %v \n", s1)
// [0, 2) [111, 222]
s2 := s[0:2]
fmt.Printf("s2 = %v \n", s2)
// 表示截取全部元素
s3 := s[:]
fmt.Printf("s3 = %v \n", s3)
// 默认下限为 0, [111 222]
s4 := s[:2]
fmt.Printf("s4 = %v \n", s4)
// 默认上限为 len() [222 333]
s5 := s[1:]
fmt.Printf("s5 = %v \n", s5)
// slice 截取后,两个 slice 仍然指向相同的内存空间
s1[0] = 888
fmt.Printf("new s = %v \n", s)
fmt.Println("===== ===== ===== ===== =====")
// c2 = [0 0 0]
c2 := make([]int, 3)
// 将 s 中的值依次拷贝值 c2 中
// 此时 c2 与 s 是完全不同的内存空间(新内存空间)
copy(c2, s)
fmt.Printf("c2 = %v \n", c2)
}
可以,此时新截取的变量类型为 slice。
package mainimport (
"fmt"
)
// func printArray(myArray [4]int) {
// // 值拷贝
// for index, value := range myArray {
// fmt.Println("index = ", index, " , value = ", value)
// }
// myArray[0] = 233
// }
// func printSlice(myArray []int) {
// // 引用传递
// // Slice 和 数组相比的一个好处是可变长度,这为形参的参数值长度提供了更多的可能性,更加灵活了
// // 动态数组是指向数组内存的指针(引用)
// for _, value := range myArray {
// fmt.Println("value = ", value)
// }
// myArray[0] = 233
// }
func main() {
// // 固定长度数组
// var myArray1 [10]int
// var myArray2 [10]float32
// myArray3 := [10]int{1, 2, 3, 4}
// myArray4 := [4]int{11, 22, 33, 44}
// // for i := 0; i < 10; i ++ {
// for i := 0; i < len(myArray1); i++ {
// fmt.Println(myArray1[i])
// }
// fmt.Println("===== ===== ===== =====")
// for j := 0; j < len(myArray2); j++ {
// fmt.Println(myArray2[j])
// }
// fmt.Println("===== ===== ===== =====")
// for index, value := range myArray3 {
// fmt.Println("index= ", index, ", value = ", value)
// }
// // 查看数组的数据类型
// fmt.Printf("myArray1 types = %T\n", myArray1)
// fmt.Printf("myArray2 types = %T\n", myArray2)
// fmt.Printf("myArray3 types = %T\n", myArray3)
// fmt.Printf("myArray4 types = %T\n", myArray4)
// fmt.Println("===== ===== ===== =====")
// printArray(myArray4)
// fmt.Println("=====")
// for index, value := range myArray4 {
// fmt.Println("index = ", index, ", value = ", value)
// }
// var myArray5 [10]int
// myArray := []int{1, 2, 3, 4} // 动态数组 切片 slice
// fmt.Printf("myArray type is %T\n", myArray)
// printSlice(myArray)
// fmt.Println("===== ===== ===== =====")
// // printSlice(myArray5)
// for _, value := range myArray {
// fmt.Println("value = ", value)
// }
// // 声明 slice 的 4 种方法
// // 1. 声明 slice1 是一个切片,并且初始化,默认值是 1, 2, 3,长度 len 是 3
// slice1 := []int{1, 2, 3}
// fmt.Printf("len = %d, slice1 = %v\n", len(slice1), slice1)
// // 2. 声明 slice2 是一个切片,但是此时并未给 slice2 分配内存空间
// // 此时无法为 slice2[0] = 1 赋值,会提示越界错误
// var slice2 []int
// // 可以通过 make 开辟内存空间
// slice2 = make([]int, 3)
// slice2[0] = 233
// fmt.Printf("len = %d, slice2 = %v\n", len(slice2), slice2)
// // 3. 声明 slice3 是一个切片,同时为 slice3 分配内存空间,3 个空间,初始化值为 0
// var slice3 []int = make([]int, 3)
// fmt.Printf("len = %d, slice3 = %v\n", len(slice3), slice3)
// // 4. 声明 slice4 是一个切片,同时为 slice4 分配内存空间,4 个空间,初始化值为 0,通过 := 推导出 slice4 是一个切片
// slice4 := make([]int, 4)
// fmt.Printf("len = %d, slice4 = %v\n", len(slice4), slice4)
// // 判断 slice 是否为空
// var slice5 []int
// if slice5 == nil {
// fmt.Println("slice5 is nil,是一个空切片")
// } else {
// fmt.Println("slice5 是有空间的")
// }
// // slice 切片的长度是 3,容量是 5
// var slice6 = make([]int, 3, 5)
// fmt.Printf("len = %d, cap = %d, slice6 = %v\n", len(slice6), cap(slice6), slice6)
// // 向 slice6 中添加元素 1,此时 len = 4,cap = 5,[0 0 0 1]
// slice6 = append(slice6, 1)
// fmt.Printf("len = %d, cap = %d, slice6 = %v\n", len(slice6), cap(slice6), slice6)
// slice6 = append(slice6, 2)
// fmt.Printf("len = %d, cap = %d, slice6 = %v\n", len(slice6), cap(slice6), slice6)
// // 像一个 slice 容量满了的 slice 中追加元素,Golang 会在底层开辟一定量等长的内存空间,如 原来的容量是 5,则现在的容量为 10
// // cap = 10
// slice6 = append(slice6, 3)
// fmt.Printf("len = %d, cap = %d, slice6 = %v\n", len(slice6), cap(slice6), slice6)
// fmt.Println("===== ===== ===== ===== =====")
// // 如果没指定 cap,则 cap = len
// var number2 = make([]int, 3)
// fmt.Printf("len = %d, cap = %d, number2 = %v\n", len(number2), cap(number2), number2)
// // cap = 6
// number2 = append(number2, 111)
// fmt.Printf("len = %d, cap = %d, number2 = %v\n", len(number2), cap(number2), number2)
// // len = 3, cap = 3
// s := []int{111, 222, 333}
// // 左闭右开 [0, 1)
// s1 := s[0:1]
// fmt.Printf("s1 = %v \n", s1)
// // [0, 2) [111, 222]
// s2 := s[0:2]
// fmt.Printf("s2 = %v \n", s2)
// // 表示截取全部元素
// s3 := s[:]
// fmt.Printf("s3 = %v \n", s3)
// // 默认下限为 0, [111 222]
// s4 := s[:2]
// fmt.Printf("s4 = %v \n", s4)
// // 默认上限为 len() [222 333]
// s5 := s[1:]
// fmt.Printf("s5 = %v \n", s5)
// // slice 截取后,两个 slice 仍然指向相同的内存空间
// s1[0] = 888
// fmt.Printf("new s = %v \n", s)
// fmt.Println("===== ===== ===== ===== =====")
// // c2 = [0 0 0]
// c2 := make([]int, 3)
// // 将 s 中的值依次拷贝值 c2 中
// // 此时 c2 与 s 是完全不同的内存空间(新内存空间)
// copy(c2, s)
// fmt.Printf("c2 = %v \n", c2)
var arr1 [5]int
arr1 = [5]int{111, 222, 333, 444, 555}
fmt.Printf("arr1 = %v \n", arr1)
arr2 := arr1[2:4]
fmt.Printf("arr2 = %v \n", arr2)
fmt.Printf("arr1 type = %T \n", arr1)
fmt.Printf("arr2 type = %T \n", arr2)
}