2015-09-18 4 views
-1

Я не понимаю, как copy функция работает на основе документации:Как работает функция копирования?

копия встроенные функции копирует элементы из кусочка источника в ломтик назначения. (В качестве специального случая он также будет копировать байты из строки в кусок байтов.) Источник и пункт назначения могут перекрываться. Копия возвращает количество скопированных элементов, которое будет минимум len (src) и len (dst).

func copy(dst, src []Type) int 
+5

я понятия не имею, что это ваш вопрос. документ ясен –

ответ

8

Спецификация также охватывает встроенные функции 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] 

Опять же, только два элемента были скопированы, но на этот раз, потому что источник имел только два элемента.

So 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 

Thi s источник времени был string и copy() скопировал 5 байтов представления UTF-8 в string (так как Go хранит строки в памяти).

Источник и пункт назначения могут пересекаться.

Это означает, что copy() работает правильно, даже если пункт назначение является срезом, который разделяет тот же основной массив как срез источника, а часть массива, назначенный источником и назначение имеет общие части (перекрытие).

Например:

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

Вот простой пример того, как использовать встроенную функцию копирования:

// 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 и ничего не будет скопировано.

Смежные вопросы