Połącz dwa plastry w Go

Próbuję połączyć plasterek [1, 2] i plasterek [3, 4]. Jak mogę to zrobić w Go?

Próbowałem:

append([]int{1,2}, []int{3,4})

Ale dostał:

cannot use []int literal (type []int) as type int in append

Jednakże dokumentacja wydaje się wskazywać, że jest to możliwe, czego mi brakuje?

slice = append(slice, anotherSlice...)
Author: icza, 2013-04-27

6 answers

Dodaj kropki po drugim plasterku:

//---------------------------vvv
append([]int{1,2}, []int{3,4}...)

Jest to jak każda inna funkcja zmienna.

func foo(is ...int) {
    for i := 0; i < len(is); i++ {
        fmt.Println(is[i])
    }
}

func main() {
    foo([]int{9,8,7,6,5}...)
}
 451
Author: 4 revs, 3 users 84%user1106925,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-05 19:40:00

Dodawanie i kopiowanie plasterków

Funkcja zmienna append dodaje zero lub więcej wartości x do s typu S, który musi być typem slice i zwraca wynik slice, również typu S. Wartości x są przekazywane do parametru typ ...T gdzie T jest typem elementu S i odpowiednio obowiązują zasady przekazywania parametrów. W szczególnym przypadku append akceptuje również pierwszy argument przypisywalny do typu []byte z drugim argument o string, po którym następuje .... Ten formularz dołącza bajty sznurek.

append(s S, x ...T) S  // T is the element type of S

s0 := []int{0, 0}
s1 := append(s0, 2)        // append a single element     s1 == []int{0, 0, 2}
s2 := append(s1, 3, 5, 7)  // append multiple elements    s2 == []int{0, 0, 2, 3, 5, 7}
s3 := append(s2, s0...)    // append a slice              s3 == []int{0, 0, 2, 3, 5, 7, 0, 0}

Przekazywanie argumentów do ... parametry

Jeśli {[14] } jest zmienna z parametrem końcowym typu ...T, to w funkcja argument jest odpowiednikiem parametru typu []T. Na każde wywołanie f, argument przekazywany do parametru końcowego jest nowym wycinek typu []T, którego kolejne elementy są rzeczywistymi argumentami, które muszą być możliwość przypisania do Typu T. Długość plastra wynosi dlatego liczba argumentów związanych z parametrem końcowym i może różnią się dla każdej strony połączeń.

Odpowiedzią na twoje pytanie jest przykład s3 := append(s2, s0...) w specyfikacji języka programowania Go. Na przykład,

s := append([]int{1, 2}, []int{3, 4}...)
 53
Author: peterSO,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-27 12:18:59

Nic przeciwko innym odpowiedziom, ale znalazłem krótkie wyjaśnienie w docs łatwiej zrozumiałe niż przykłady w nich:

Func append

func append(slice []Type, elems ...Type) []Type wbudowany dodatek funkcja dodaje elementy do końca plasterka. Jeśli ma wystarczającą pojemność, miejsce docelowe jest resliced, aby pomieścić nowe elementy. Jeśli tak się nie stanie, zostanie przydzielona nowa tablica bazowa. Dołącz zwraca zaktualizowany plasterek. Dlatego konieczne jest store the wynik dodawania, często w zmiennej trzymającej sam wycinek:

slice = append(slice, elem1, elem2)
slice = append(slice, anotherSlice...)

Jako szczególny przypadek, legalne jest dołączanie ciągu znaków do kawałka bajtu, tak:

slice = append([]byte("hello "), "world"...)
 23
Author: fiatjaf,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-17 02:03:45

Myślę, że ważne jest, aby zaznaczyć i wiedzieć, że jeśli plasterek docelowy (plasterek, do którego dołączasz) ma wystarczającą pojemność, dołączenie stanie się "na miejscu", poprzez reslicing miejsca docelowego (reslicing do zwiększ jego długość, aby móc pomieścić elementy dodatkowe).

Oznacza to, że jeśli miejsce docelowe zostało utworzone przez krojenie większej tablicy lub plasterka, który ma dodatkowe elementy poza długością wynikowego plasterka, mogą one uzyskać nadpisane.

Aby zademonstrować, zobacz ten przykład:

a := [10]int{1, 2}
fmt.Printf("a: %v\n", a)

x, y := a[:2], []int{3, 4}
fmt.Printf("x: %v, y: %v\n", x, y)
fmt.Printf("cap(x): %v\n", cap(x))

x = append(x, y...)
fmt.Printf("x: %v\n", x)

fmt.Printf("a: %v\n", a)

Output (try it on the Go Playground):

a: [1 2 0 0 0 0 0 0 0 0]
x: [1 2], y: [3 4]
cap(x): 10
x: [1 2 3 4]
a: [1 2 3 4 0 0 0 0 0 0]

Stworzyliśmy tablicę" backing " a o długości 10. Następnie tworzymy x docelowy plasterek wycinając tę tablicę a, y plasterek jest tworzony za pomocą literała złożonego []int{3, 4}. Teraz, gdy dodamy y do x, wynik jest oczekiwany [1 2 3 4], ale co może być zaskakujące, to że tablica podkładowa a również się zmieniła, ponieważ pojemność x jest 10, co wystarcza do dołączenia y do niego, więc {[7] } jest resliced, który również użyje tej samej tablicy podkładowej a, a append() skopiuje do niej elementy y.

Jeśli chcesz tego uniknąć, możesz użyć pełnego wyrażenia slice , które ma postać

a[low : high : max]

, który konstruuje plasterek, a także kontroluje pojemność wynikowego plasterka, ustawiając go na max - low.

Zobacz zmodyfikowany przykład (jedyna różnica polega na tym, że tworzymy x jak to: x = a[:2:2]:

a := [10]int{1, 2}
fmt.Printf("a: %v\n", a)

x, y := a[:2:2], []int{3, 4}
fmt.Printf("x: %v, y: %v\n", x, y)
fmt.Printf("cap(x): %v\n", cap(x))

x = append(x, y...)
fmt.Printf("x: %v\n", x)

fmt.Printf("a: %v\n", a)

Output (try it on the Go Playground )

a: [1 2 0 0 0 0 0 0 0 0]
x: [1 2], y: [3 4]
cap(x): 2
x: [1 2 3 4]
a: [1 2 0 0 0 0 0 0 0 0]

Jak widzisz, otrzymujemy ten sam wynik x, ale tablica nośna a nie zmieniła się, ponieważ pojemność x była "tylko" 2 (dzięki pełnemu wyrażeniu slice a[:2:2]). Aby to zrobić, przydzielana jest nowa tablica pomocnicza, która może przechowywać elementy zarówno x, jak i y, które różnią się od a.

 13
Author: icza,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-16 21:34:55

append([]int{1,2}, []int{3,4}...) zadziała. Przekazywanie argumentów do parametrów ....

Jeśli f jest zmienny z końcowym parametrem p typu ...T, to w obrębie f Typ p jest równoważny typowi []T.

Jeśli f jest wywoływane bez rzeczywistych argumentów dla p, wartość przekazywana do p wynosi nil.

W Przeciwnym Razie przekazywana wartość jest nowym wycinkiem typu []T z nową tablicą bazową, której kolejne elementy są rzeczywistymi argumentami, do których wszystkie muszą być przypisane T. Długość i pojemność wycinka jest więc liczbą argumentów związanych z p i może się różnić dla każdego miejsca wywołania.

Biorąc pod uwagę funkcję i wywołania

func Greeting(prefix string, who ...string)
Greeting("nobody")
Greeting("hello:", "Joe", "Anna", "Eileen")
 0
Author: BaSO4,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-07 08:38:52

Append( ) i ...

Dwa plastry mogą być łączone za pomocą append metoda w standardowej bibliotece golang. Co jest podobne do działania funkcji variadic. Więc musimy użyć ...

package main

import (
    "fmt"
)

func main() {
    x := []int{1, 2, 3}
    y := []int{4, 5, 6}
    z := append([]int{}, append(x, y...)...)
    fmt.Println(z)
}

Wyjście powyższego kodu jest: [1 2 3 4 5 6]

 0
Author: ASHWIN RAJEEV,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-04 08:52:29