4.slice

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]\n", len(slice), cap(slice))
	for i := range slice {
		fmt.Printf("[%d] %p %s\n",
			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("*************************\n")

	// 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("*************************\n")

	// 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]\n", len(slice), cap(slice))
	for i := range slice {
		fmt.Printf("[%d] %p %s\n",
			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]\tIndex[%d]\t\tCap[%d - %2.f%%]\n",
				&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\n", 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("**************************\n")
	for _, u := range u3 {
		fmt.Printf("%+v\n", u)
	}

}

// display can accept and display multiple values of user types.
func display(users ...user) {
	fmt.Println("**************************\n")
	for _, u := range users {
		fmt.Printf("%+v\n", 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]\n", 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]\n", 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]\n", len(slice), cap(slice))
	for index, value := range slice {
		fmt.Printf("[%d] %p %s\n",
			index,
			&slice[index],
			value)
	}
	fmt.Print("--------------------\n")
}
/*
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
--------------------

*/

posted on 2018-03-16 20:57  cucy_to  阅读(146)  评论(0编辑  收藏  举报

导航