复制功能如何运作? [关闭]

问题描述 投票:0回答:2

根据文档我不明白

copy
函数是如何工作的:

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

func copy(dst, src []Type) int
go copy slice
2个回答
21
投票

规范还涵盖了内置函数

append()
copy()
附加和复制切片。你应该阅读它;很清楚。

让我们通过简单的例子来分析内置

copy()
函数的文档及其用法。您可以在 Go Playground 上尝试所有示例。

签名:

func copy(dst, src []Type) int

copy()
是一个函数。它有两个参数,一个目标切片和一个源切片,其元素类型相同。它返回一个类型
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]

它复制了所有五个元素,复制后目标与源具有相同的元素。

让我们继续这个例子:

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]

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

继续:

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]

再次,只复制了两个元素,但这次是因为源只有两个元素。

所以

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

这次源是一个

string
copy()
复制了string
UTF-8
表示的五个字节(这就是Go在内存中存储字符串的方式)。

来源和目的地可能重叠。

这意味着即使目标是与源切片共享相同底层数组的切片,并且源和目标指定的数组部分具有公共部分(重叠),

copy()
也能正常工作。

例如:

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

输出:

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

这里我指定了

src[1:]
为source,也就是没有第一个元素的source(这是一个reslicing)。由于我排除了第一个元素,
copy()
的来源有四个元素,所以
4
元素被复制了。结果是元素被“转移”到一个小于 1 的索引(因此第一个元素
0
现在从切片中消失了),最后一个元素没有被触及(因为只复制了四个元素)。

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

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

如果你需要了解更多关于切片的知识:

Go Slices:用法和内部结构

数组、切片(和字符串):“追加”的机制


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]

游乐场示例


如果

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]

游乐场示例


一个问题是,如果您将目标切片声明为这样的切片文字:

destination := []int{}

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

© www.soinside.com 2019 - 2024. All rights reserved.