复制功能如何工作?

时间:2015-09-18 02:30:37

标签: go copy slice

我不明白copy函数如何根据文档工作:

  

复制内置函数将元素从源切片复制到   目的地切片。 (作为一种特殊情况,它也会从a复制字节   字符串到一片字节。)源和目标可能重叠。复制   返回复制的元素数,这将是最小值   len(src)和len(dst)。

func copy(dst, src []Type) int

2 个答案:

答案 0 :(得分:9)

该规范还涵盖了内置函数append()copy()Appending to and copying slices。你应该读它,它很清楚。

让我们用简单的例子分析内置copy()函数的文档及其用法。您可以尝试Go Playground上的所有示例。

签名:

func copy(dst, src []Type) int

copy()是一个函数,它有2个参数,一个目标和一个源片,其元素类型相同。它返回一些类型int,它是实际复制的元素数。

  

复制内置函数将元素从源切片复制到目标切片。

copy()会将src切片中的元素复制到dst切片中。

src := []int{10, 11, 12, 13, 14}
dst := []int{0, 1, 2, 3, 4}

n := copy(dst, src)
fmt.Println("n =", n, "src =", src, "dst =", dst)

输出:

n = 5 src = [10 11 12 13 14] dst = [10 11 12 13 14]

它复制了所有5个元素,并且在复制后,目标与元素具有相同的元素。

让我们继续这个例子:

dst = []int{0, 1}

n = copy(dst, src)
fmt.Println("n =", n, "src =", src, "dst =", dst)

输出:

n = 2 src = [10 11 12 13 14] dst = [10 11]

只复制了2个元素,因为目标只有2个元素。

继续:

src = []int{10, 11}
dst = []int{0, 1, 2, 3, 4}

n = copy(dst, src)
fmt.Println("n =", n, "src =", src, "dst =", dst)

输出:

n = 2 src = [10 11] dst = [10 11 2 3 4]

同样,只复制了2个元素,但这次是因为源只有2个元素。

所以copy()只会复制与源或目标一样多的元素,以较小者为准。或者换句话说,尽管源“提供”或目的地可以“容纳”,但以较小者为准。

  

(作为一种特殊情况,它还会将字符串中的字节复制到一个字节片段。)

这意味着,如果目的地为string,则来源也可以是[]byte

str := "Hello World!"
data := make([]byte, 5)
n = copy(data, str)
fmt.Println("n =", n, "str =", str, "data =", data)
fmt.Printf("data as string: %s\n", data)

输出:

n = 5 str = Hello World! data = [72 101 108 108 111]
data as string: Hello

这次来源是stringcopy()复制了string的UTF-8表示的5个字节(这就是Go如何在内存中存储字符串)。

  

来源和目的地可能重叠。

这意味着即使目标是与源切片共享相同底层数组的切片,copy()也能正常工作,并且由源和目标指定的数组部分具有公共部分(重叠)。 / p>

例如:

copy(src, src[1:])
fmt.Println("n =", n, "src =", src)

输出:

n = 4 src = [1 2 3 4 4]

这里我指定了src[1:]作为源,它是没有第一个元素的源(这是reslicing)。由于我排除了第一个元素,copy()的来源有4个元素,因此复制了4个元素。结果是元素被“移位”到少于1的索引(因此第一个元素0现在从切片中消失),并且未触及最后一个元素(因为只复制了4个元素)。

  

复制返回复制的元素数,这将是len(src)和len(dst)的最小值。

我们在上面的例子中看到了这一点。

如果您需要了解有关切片的更多信息:

Go Slices: usage and internals

Arrays, slices (and strings): The mechanics of 'append'

答案 1 :(得分:2)

以下是如何使用内置复制功能的基本示例:

// The source slice
source := []int{1, 2, 3,}

// The destination slice is where things will be copied to
destination := make([]int, len(source))

// The copy function returns a count of how many elements are copied from the source slice to the destination slice
copies := copy(destination, source)

// Some printing
fmt.Printf("copied %d elements\n", copies)  // Outputs: copied 3 elements
fmt.Println("destination slice:", destination)  // Outputs: destination slice: [1 2 3]

Example Playground

如果destination切片的长度为n,且source切片的长度为m,则n< m目标切片将使用n切片的第一个source元素填充:

source := []int{1, 2, 3,}
destination := make([]int, 1) // <-- Notice the 1
copies := copy(destination, source)
fmt.Printf("copied %d elements\n", copies)  // Outputs: copied 1 elements
fmt.Println("destination slice:", destination)  // Outputs: destination slice: [1]

Example Playground

如果你将目标切片声明为像这样的切片文字:

destination := []int{}

长度为0,不会复制任何内容。