web-dev-qa-db-fra.com

Concaténer deux tranches dans Go

J'essaie de combiner la tranche [1, 2] et la tranche [3, 4]. Comment puis-je faire cela dans Go?

J'ai essayé:

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

mais j'ai:

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

Cependant, la documentation semble indiquer que c'est possible, que me manque-t-il?

slice = append(slice, anotherSlice...)
307
Kevin Burke

Ajouter des points après la deuxième tranche:

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

C'est comme n'importe quelle autre fonction variadique.

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

func main() {
    foo([]int{9,8,7,6,5}...)
}
531
user1106925

Ajout et copie de tranches

La fonction variable append ajoute zéro ou plusieurs valeurs x à s de type S, qui doit être un type de tranche, et renvoie le résultat slice, également de type S. Les valeurs x sont passées à un paramètre de type ...TT est le type d'élément de S et le .__ respectif. les règles de passage de paramètres s'appliquent. Append accepte également comme cas particulier un premier argument assignable au type []byte avec un second argument de string type suivi de .... Ce formulaire ajoute les octets du chaîne.

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}

Passer des arguments à ... paramètres

Si f est variable avec le type de paramètre final ...T, dans le function, l'argument est équivalent à un paramètre de type []T. À à chaque appel de f, l'argument transmis au paramètre final est un nouveau tranche de type []T dont les éléments successifs sont les arguments réels, qui doivent tous être assignables au type T. La longueur de la tranche est donc le nombre d'arguments liés au paramètre final et may diffèrent pour chaque site d’appel.

La réponse à votre question est l'exemple s3 := append(s2, s0...) dans la spécification de langage de programmation Go . Par exemple,

s := append([]int{1, 2}, []int{3, 4}...)
57
peterSO

Rien contre les autres réponses, mais j'ai trouvé la brève explication dans les docs plus compréhensible que les exemples qu’ils contiennent:

func append

func append(slice []Type, elems ...Type) []Type La fonction intégrée append fonction ajoute des éléments à la fin d'une tranche. Si cela suffit. capacité, la destination est redimensionnée pour accueillir les nouveaux éléments . Si ce n'est pas le cas, un nouveau tableau sous-jacent sera alloué. Ajouter renvoie la tranche mise à jour. Il est donc nécessaire de stocker le fichier résultat de append, souvent dans la variable contenant la tranche elle-même:

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

En tant que cas particulier, il est légal d'ajouter une chaîne à une tranche d'octet, comme ça:

slice = append([]byte("hello "), "world"...)
23
fiatjaf

Je pense qu’il est important de souligner et de savoir que si la tranche de destination (la tranche à laquelle vous ajoutez) a une capacité suffisante, l’ajout se fera "sur place" en redimensionnant la destination (redimensionnement pour augmenter sa longueur afin de pouvoir accueillir les éléments annexes).

Cela signifie que si la destination a été créée en découpant un tableau ou une tranche plus volumineux comportant des éléments supplémentaires au-delà de la longueur de la tranche résultante, ils peuvent être écrasés.

Pour démontrer, voir cet exemple:

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)

Sortie (essayez-le sur 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]

Nous avons créé un tableau "de sauvegarde" a de longueur 10. Ensuite, nous créons la tranche de destination x en découpant ce tableau a. La tranche y est créée à l'aide du []int{3, 4} littéral composite. Maintenant, lorsque nous ajoutons y à x, le résultat est le [1 2 3 4] attendu, mais il peut être surprenant que le tableau de sauvegarde a ait également changé, car la capacité de x est 10, ce qui suffit pour ajouter y, et donc x utilisez également le même tableau de sauvegarde a, et append() y copiera les éléments de y.

Si vous voulez éviter cela, vous pouvez utiliser un expression de tranche complète qui a la forme

a[low : high : max]

qui construit une tranche et contrôle également la capacité de la tranche résultante en la définissant sur max - low.

Voir l'exemple modifié (la seule différence est que nous créons x comme ceci: 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)

Sortie (essayez-le sur 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]

Comme vous pouvez le constater, nous obtenons le même résultat x mais le tableau de sauvegarde a n'a pas changé, car la capacité de x était "seulement" 2 (grâce à l'expression complète de la tranche a[:2:2]). Donc, pour effectuer l’ajout, un nouveau tableau de sauvegarde est alloué qui peut stocker les éléments de x et y, ce qui est différent de a.

18
icza

fonction append () et opérateur spread

Deux tranches peuvent être concaténées à l’aide de la méthodeappenddans la bibliothèque golang standard. Ce qui est similaire à l'opération variadic. Nous devons donc utiliser ...

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)
}

la sortie du code ci-dessus est: [1 2 3 4 5 6]

3
ASHWIN RAJEEV

append([]int{1,2}, []int{3,4}...) fonctionnera. Passer des arguments aux paramètres ....

Si f est variable avec un paramètre final p de type ...T, alors dans f, le type de p est équivalent au type []T

Si f est invoqué sans aucun argument réel pour p, la valeur transmise à p est nil

Sinon, la valeur transmise est une nouvelle tranche de type []T avec un nouveau tableau sous-jacent dont les éléments successifs sont les arguments réels, qui doivent tous être assignables à T. La longueur et la capacité de la tranche correspondent donc au nombre d'arguments liés à p et peuvent différer pour chaque site d'appel.

Compte tenu de la fonction et des appels

func Greeting(prefix string, who ...string)
Greeting("nobody")
Greeting("hello:", "Joe", "Anna", "Eileen")
0
BaSO4