package main
import "fmt"
func main() {
// Create a slice with a length of 5 elements.
slice := make([]string, 5)
slice[0] = "Apple"
slice[1] = "Orange"
slice[2] = "Banana"
slice[3] = "Grape"
slice[4] = "Plum"
// You can't access an index of a slice beyond its length.
//
slice[5] = "Runtime error"
// Error: panic: runtime error: index out of range
fmt.Println(slice)
}
Reference Types
// Sample program to show the components of a slice. It has a
// length, capacity and the underlying array.
//示例程序以显示切片的组件。它有一个
//长度、容量和底层数组。
package main
import "fmt"
func main() {
// Create a slice with a length of 5 elements and a capacity of 8.
slice := make([]string, 5, 8)
slice[0] = "Apple"
slice[1] = "Orange"
slice[2] = "Banana"
slice[3] = "Grape"
slice[4] = "Plum"
inspectSlice(slice)
}
// inspectSlice exposes the slice header for review.
func inspectSlice(slice []string) {
fmt.Printf("Length[%d], Capacity[%d]
", len(slice), cap(slice))
for i := range slice {
fmt.Printf("[%d] %p %s
",
i,
&slice[i],
slice[i])
}
}
Taking slices of slices
// Sample program to show how to takes slices of slices to create different
// views of and make changes to the underlying array.
//示例程序演示如何使用切片来创建不同的切片。
//对底层数组的视图进行修改。
package main
import "fmt"
func main() {
// Create a slice with a length of 5 elements and a capacity of 8.
slice1 := make([]string, 5, 8)
slice1[0] = "Apple"
slice1[1] = "Orange"
slice1[2] = "Banana"
slice1[3] = "Grape"
slice1[4] = "Plum"
inspectSlice(slice1)
// Take a slice of slice1. We want just indexes 2 and 3.
// Parameters are [starting_index : (starting_index + length)]
slice2 := slice1[2:4]
inspectSlice(slice2)
fmt.Println("*************************
")
// Change the value of the index 0 of slice2.
slice2[0] = "CHANGED"
// Display the change across all existing slices.
inspectSlice(slice1)
inspectSlice(slice2)
fmt.Println("*************************
")
// Make a new slice big enough to hold elements of slice 1 and copy the
// values over using the builtin copy function.
slice3 := make([]string, len(slice1))
copy(slice3, slice1)
inspectSlice(slice3)
}
// inspectSlice exposes the slice header for review.
func inspectSlice(slice []string) {
fmt.Printf("Length[%d] Capacity[%d]
", len(slice), cap(slice))
for i := range slice {
fmt.Printf("[%d] %p %s
",
i,
&slice[i],
slice[i])
}
}
/*
Length[5] Capacity[8]
[0] 0xc420088000 Apple
[1] 0xc420088010 Orange
[2] 0xc420088020 Banana
[3] 0xc420088030 Grape
[4] 0xc420088040 Plum
Length[2] Capacity[6]
[0] 0xc420088020 Banana
[1] 0xc420088030 Grape
*************************
Length[5] Capacity[8]
[0] 0xc420088000 Apple
[1] 0xc420088010 Orange
[2] 0xc420088020 CHANGED
[3] 0xc420088030 Grape
[4] 0xc420088040 Plum
Length[2] Capacity[6]
[0] 0xc420088020 CHANGED
[1] 0xc420088030 Grape
*************************
Length[5] Capacity[5]
[0] 0xc4200840f0 Apple
[1] 0xc420084100 Orange
[2] 0xc420084110 CHANGED
[3] 0xc420084120 Grape
[4] 0xc420084130 Plum
*/
Appending slices
// Sample program to show how to grow a slice using the built-in function append
// and how append grows the capacity of the underlying array.
//示例程序演示如何使用内置的函数append来生成一个切片。
//以及append如何增加底层数组的容量。
package main
import "fmt"
func main() {
// Declare a nil slice of strings.
var data []string
// Capture the capacity of the slice.
lastCap := cap(data)
// Append ~100k strings to the slice.
for record := 1; record <= 102400; record++ {
// Use the built-in function append to add to the slice.
data = append(data, fmt.Sprintf("Rec: %d", record))
// When the capacity of the slice changes, display the changes.
if lastCap != cap(data) {
// Calculate the percent of change. 计算变化的百分比。
capChg := float64(cap(data)-lastCap) / float64(lastCap) * 100
// Save the new values for capacity. 保存容量的新值。
lastCap = cap(data)
// Display the results.
fmt.Printf("Addr[%p] Index[%d] Cap[%d - %2.f%%]
",
&data[0],
record,
cap(data),
capChg)
}
}
}
/*
Addr[0xc42000e1d0] Index[1] Cap[1 - +Inf%]
Addr[0xc42000a060] Index[2] Cap[2 - 100%]
Addr[0xc4200560c0] Index[3] Cap[4 - 100%]
Addr[0xc42008c000] Index[5] Cap[8 - 100%]
Addr[0xc42008e000] Index[9] Cap[16 - 100%]
Addr[0xc420090000] Index[17] Cap[32 - 100%]
Addr[0xc420088400] Index[33] Cap[64 - 100%]
Addr[0xc420092000] Index[65] Cap[128 - 100%]
Addr[0xc420094000] Index[129] Cap[256 - 100%]
Addr[0xc420096000] Index[257] Cap[512 - 100%]
Addr[0xc42009a000] Index[513] Cap[1024 - 100%]
Addr[0xc4200a0000] Index[1025] Cap[1280 - 25%]
Addr[0xc4200aa000] Index[1281] Cap[1704 - 33%]
Addr[0xc4200c2000] Index[1705] Cap[2560 - 50%]
Addr[0xc4200d0000] Index[2561] Cap[3584 - 40%]
Addr[0xc4200e4000] Index[3585] Cap[4608 - 29%]
Addr[0xc4200fc000] Index[4609] Cap[6144 - 33%]
Addr[0xc42011e000] Index[6145] Cap[7680 - 25%]
Addr[0xc420144000] Index[7681] Cap[9728 - 27%]
Addr[0xc420176000] Index[9729] Cap[12288 - 26%]
Addr[0xc4201b6000] Index[12289] Cap[15360 - 25%]
Addr[0xc420204000] Index[15361] Cap[19456 - 27%]
Addr[0xc420268000] Index[19457] Cap[24576 - 26%]
Addr[0xc4202e6000] Index[24577] Cap[30720 - 25%]
Addr[0xc420382000] Index[30721] Cap[38400 - 25%]
Addr[0xc420444000] Index[38401] Cap[48128 - 25%]
Addr[0xc42056a000] Index[48129] Cap[60416 - 26%]
Addr[0xc420656000] Index[60417] Cap[75776 - 25%]
Addr[0xc42077e000] Index[75777] Cap[94720 - 25%]
Addr[0xc42056a000] Index[94721] Cap[118784 - 25%]
*/
Slices and References
// Sample program to show how one needs to be careful when appending
// to a slice when you have a reference to an element.
//示例程序演示如何在追加时小心谨慎。
//当你对一个元素有一个引用时,你可以把它切成一片。
package main
import "fmt"
func main() {
// Declare a slice of integers with 7 values.
x := make([]int, 7)
// Random starting counters.
for i := 0; i < 7; i++ {
x[i] = i * 100
}
// Set a pointer to the second element of the slice.
twohundred := &x[1]
// Append a new value to the slice.
x = append(x, 800)
// Change the value of the second element of the slice.
x[1]++
// Display the value that the pointer points to and the
// second element of the slice.
fmt.Println("Pointer:", *twohundred, "Element", x[1])
}
Strings and slices
// Sample program to show how strings have a UTF-8 encoded byte array.
//示例程序演示字符串如何使用UTF-8编码的字节数组。
package main
import (
"fmt"
"unicode/utf8"
)
func main() {
// Declare a string with both chinese and english characters.
s := "世界 means world"
// UTFMax is 4 -- up to 4 bytes per encoded rune. UTFMax是4——每个编码的符文最多4字节。
var buf [utf8.UTFMax]byte
// Iterate over the string.
for i, r := range s {
// Capture the number of bytes for this rune. 捕获这个符文的字节数。
rl := utf8.RuneLen(r)
// Calculate the slice offset for the bytes associated 计算相关字节的片偏移量。
// with this rune.
si := i + rl
// Copy of rune from the string to our buffer. 从字符串拷贝到我们的缓冲区。
copy(buf[:], s[i:si])
// Display the details.
fmt.Printf("%2d: %q; codepoint: %#6x; encoded bytes: %#v
", i, r, r, buf[:rl])
}
}
/*
0: '世'; codepoint: 0x4e16; encoded bytes: []byte{0xe4, 0xb8, 0x96}
3: '界'; codepoint: 0x754c; encoded bytes: []byte{0xe7, 0x95, 0x8c}
6: ' '; codepoint: 0x20; encoded bytes: []byte{0x20}
7: 'm'; codepoint: 0x6d; encoded bytes: []byte{0x6d}
8: 'e'; codepoint: 0x65; encoded bytes: []byte{0x65}
9: 'a'; codepoint: 0x61; encoded bytes: []byte{0x61}
10: 'n'; codepoint: 0x6e; encoded bytes: []byte{0x6e}
11: 's'; codepoint: 0x73; encoded bytes: []byte{0x73}
12: ' '; codepoint: 0x20; encoded bytes: []byte{0x20}
13: 'w'; codepoint: 0x77; encoded bytes: []byte{0x77}
14: 'o'; codepoint: 0x6f; encoded bytes: []byte{0x6f}
15: 'r'; codepoint: 0x72; encoded bytes: []byte{0x72}
16: 'l'; codepoint: 0x6c; encoded bytes: []byte{0x6c}
17: 'd'; codepoint: 0x64; encoded bytes: []byte{0x64}
*/
Variadic functions 可变的函数
// Sample program to show how to declare and use variadic functions.
//示例程序演示如何声明和使用变量函数。
package main
import "fmt"
// user is a struct type that declares user information.
type user struct {
id int
name string
}
func main() {
// Declare and initialize a value of type user.
u1 := user{
id: 1432,
name: "Betty",
}
// Declare and initialize a value of type user.
u2 := user{
id: 4367,
name: "Janet",
}
// Display both user values.
display(u1, u2)
// Create a slice of user values.
u3 := []user{
{24, "Bill"},
{32, "Joan"},
}
// Display all the user values from the slice.
display(u3...)
change(u3...)
fmt.Println("**************************
")
for _, u := range u3 {
fmt.Printf("%+v
", u)
}
}
// display can accept and display multiple values of user types.
func display(users ...user) {
fmt.Println("**************************
")
for _, u := range users {
fmt.Printf("%+v
", u)
}
}
// change show how the backing array is shared
func change(users ...user) {
users[1] = user{99, "Same Backing Array"}
}
/*
**************************
{id:1432 name:Betty}
{id:4367 name:Janet}
**************************
{id:24 name:Bill}
{id:32 name:Joan}
**************************
{id:24 name:Bill}
{id:99 name:Same Backing Array}
*/
Range mechanics
// Sample program to show how the for range has both value and pointer semantics.
//示例程序,以显示for range如何具有值和指针语义。
package main
import "fmt"
func main() {
// Using the value semantic form of the for range.
// 使用for range的值语义形式。
five := []string{"Annie", "Betty", "Charley", "Doug", "Edward"}
for _, v := range five {
five = five[:2]
fmt.Printf("v[%s]
", v)
}
// Using the pointer semantic form of the for range.
// 使用for range的指针语义形式。
five = []string{"Annie", "Betty", "Charley", "Doug", "Edward"}
for i := range five {
five = five[:2]
fmt.Printf("v[%s]
", five[i])
}
}
// Sample program to show how to use a third index slice.
//示例程序演示如何使用第三个索引片。
package main
import "fmt"
func main() {
// Create a slice of strings with different types of fruit. 用不同种类的水果制作一段绳子。
slice := []string{"Apple", "Orange", "Banana", "Grape", "Plum"}
inspectSlice(slice)
// Take a slice of slice. We want just index 2 切片。我们只需要指数2。
takeOne := slice[2:3]
inspectSlice(takeOne)
// Take a slice of just index 2 with a length and capacity of 1 取一个长度和容量为1的索引2。
takeOneCapOne := slice[2:3:3] // Use the third index position to
inspectSlice(takeOneCapOne) // set the capacity to 1.
// Append a new element which will create a new
// underlying array to increase capacity.
// 附加一个新元素,它将创建一个新元素。
// 基础阵列增加容量。
takeOneCapOne = append(takeOneCapOne, "Kiwi")
inspectSlice(takeOneCapOne)
}
// inspectSlice exposes the slice header for review. 检查切片公开了切片头以便进行检查。
func inspectSlice(slice []string) {
fmt.Printf("Length[%d] Capacity[%d]
", len(slice), cap(slice))
for index, value := range slice {
fmt.Printf("[%d] %p %s
",
index,
&slice[index],
value)
}
fmt.Print("--------------------
")
}
/*
Length[5] Capacity[5]
[0] 0xc4200840f0 Apple
[1] 0xc420084100 Orange
[2] 0xc420084110 Banana
[3] 0xc420084120 Grape
[4] 0xc420084130 Plum
--------------------
Length[1] Capacity[3]
[0] 0xc420084110 Banana
--------------------
Length[1] Capacity[1]
[0] 0xc420084110 Banana
--------------------
Length[2] Capacity[2]
[0] 0xc42000a060 Banana
[1] 0xc42000a070 Kiwi
--------------------
*/