Golang 12 : Les tranches
Les tranches
Une tranche est un wrapper utile, flexible et puissant. Les tranches sont des références à des tableaux existants.
La création d'une tranche
Une tranche avec des éléments de type T est représenté par []T
package main
import (
"fmt"
)
func main() {
a := [5]int{53, 95, 23, 22, 67}
var b []int = a[1:5] //creation d'une tranche de a[1] à a[3]
fmt.Println(b)
}
Le syntaxe a[start:end]
crée une tranche d'un tableau a
commençant de l'indice start
à l'indice end - 1
. Dans le programme ci-dessus, a[1:4]
sert à la création d'une tranche qui représente un tableau qui commence de l'indice 1 à 4. Par conséquent la tranche b a comme valeurs [95 23 22 ]
.
Voici une autre méthode de création d'une tranche:
package main
import (
"fmt"
)
func main() {
c := []int{6, 7, 8} //creation d'un tableau retour d'une tranche reference
fmt.Println(c)
}
Dans le programme ci-dessus, c := []int{6, 7, 8} crée un tableau de trois entiers et retourne une tranche référence qui est stockée en c.
La modification d'une tranche
Une tranche n'est qu'une représentation d'un tableau sous-jacent . Toute modification faite sur une tranche va être reflétée dans le tableau sous-jacent .
package main
import (
"fmt"
)
func main() {
darr := [...]int{57, 89, 90, 82, 100, 78, 67, 69, 59}
dslice := darr[2:5]
fmt.Println("tableau avant modification",darr)
for i := range dslice {
dslice[i]++
}
fmt.Println("tableau après modification",darr)
}
Après l'exécution du programme ci-dessus:
tableau avant modification [57 89 90 82 100 78 67 69 59]
tableau après modification [57 89 91 83 101 78 67 69 59]
Quand un nombre de tranches partagent le même tableau sous-jacent, le changement que chacune des tranches effectue va être reflété dans le tableau.
package main
import (
"fmt"
)
func main() {
numa := [3]int{78, 79 ,80}
nums1 := numa[:] //créer une tranche qui contient tous les éléments du tableau
nums2 := numa[:]
fmt.Println("le tableau avant le premier changement",numa)
nums1[0] = 100
fmt.Println("le tableau après la modification de la tranche nums1", numa)
nums2[1] = 101
fmt.Println("le tableau après la modification de la tranche nums2 ", numa)
}
La longueur et la capacité d'une tranche
La longueur d'une tranche est le nombre d'éléments dans une tranche. La capacité d'une tranche est le nombre d'éléments dans le tableau sous-jacent commençant par l'indice à partir duquel la tranche a été créé.
Exemple:
package main
import (
"fmt"
)
func main() {
fruitarray := [...]string{"apple", "orange", "grape", "mango", "water melon", "pine apple", "chikoo"}
fruitslice := fruitarray[1:3]
fmt.Printf("longueur de la tranche %d capacité %d", len(fruitslice), cap(fruitslice))
}
Dans l'exemple ci-dessus, fruitslice
est créé à partir de fruitarray
. Par conséquent, la longueur de fruitslice
est 2.
La longueur de fruitarray
est 7. fruiteslice
est créé de l'indice 1 de fruitarray
. Par conséquent, la capacité de fruitslice
est le nombre d'éléments de fruitarray
commençant de l'indice 1. Par conséquent, la sortie du programme serait longueur de la tranche 2 capacité 6.
Création d'une tranche en utilisant make
func make([]T, len, cap) peut être utilisée pour créer une tranche en passant le type, la longueur et la capacité. Le paramètre de la fonction est optionnel . La fonction make crée un tableau et retourne une tranche qui réfère au tableau.
package main
import (
"fmt"
)
func main() {
i := make([]int, 5, 5)
fmt.Println(i)
}
La fonction append()
Les tranches sont dynamiques contrairement aux tableaux qui ont une taille fixe, on peut ajouter des éléments aux tranches en utilisant la fonction append
, la définition de la fonction append est func append(s []T, x ...T) []T
.
x…T veut dire que le fonction accepte un nombre d'arguments pour le paramètre x. Ce type de fonction s'appelle une fonction variadique.
Quand de nouveaux éléments sont ajoutés à la tranche, un nouveau tableau est créé. Les éléments du tableau existant sont copiés dans le nouveau tableau et une nouvelle référence de la tranche pour le nouveau tableau est retournée.
package main
import (
"fmt"
)
func main() {
cars := []string{"Ferrari", "Honda", "Ford"}
fmt.Println("cars:", cars, "a comme ancienne longueur", len(cars), "et capacité", cap(cars)) //la capacité de cars est 3
cars = append(cars, "Toyota")
fmt.Println("cars:", cars, "a comme nouvelle longueur", len(cars), "et capacité", cap(cars)) //capacité de cars est 6
}
La sortie du programme est:
cars: [Ferrari Honda Ford] a comme ancienne longueur 3 et capacité 3
cars: [Ferrari Honda Ford Toyota] a comme nouvelle longueur 4 et capacité 6
La valeur zéro des tranches est nil
. Une tranche nil
a une longueur et une capacité nulle.
Il est aussi possible de joindre deux tranches en utilisant l'opérateur ...
.
Exemple:
package main
import (
"fmt"
)
func main() {
veggies := []string{"potatoes","tomatoes","brinjal"}
fruits := []string{"oranges","apples"}
food := append(veggies, fruits...)
fmt.Println("food:",food)
}
Passer une tranche à une fonction:
Les tranches peuvent être représentées comme un type de structure.
Exemple:
type slice struct {
Longueur int
Capacite int
ZerothElement *byte
}
Une tranche contient la longueur, la capacité et un pointeur sur l'élément zéro du tableau. Quand une tranche est passée à une fonction, celle-ci est passée par valeur, le pointeur variable va référer au même tableau sous-jacent. Par conséquent, quand une tranche est passée à une fonction comme paramètre, les changements effectués dans une fonction sont aussi visibles à l'extérieur de la fonction.
Exemple:
package main
import (
"fmt"
)
func subtactOne(numbers []int) {
for i := range numbers {
numbers[i] -= 2
}
}
func main() {
nos := []int{8, 7, 6}
fmt.Println("tranche avant l'appel de la fonction", nos)
subtactOne(nos) //la fonction modifie la tranche
fmt.Println("tranche après l'appel de la fonction", nos) //les modifications sont visibles à l'extérieur de la fonction
}
Après l'exécution du programme, on aura:
tranche avant l'appel de la fonction [8 7 6]
tranche après l'appel de la fonction [6 5 4]
Les tranches multidimensionnelles
Une tranche peut être multidimensionnelle:
package main
import (
"fmt"
)
func main() {
pls := [][]string {
{"C", "C++"},
{"JavaScript"},
{"Go", "Rust"},
}
for _, v1 := range pls {
for _, v2 := range v1 {
fmt.Printf("%s ", v2)
}
fmt.Printf("\n")
}
}
la sortie du programme serait:
C C++
JavaScript
Go Rust
L'optimisation de la mémoire
Supposons qu'on un un tableau de grande taille et qu'on ne veut traiter qu'une partie de ce tableau. Par conséquent, on crée une tranche de ce tableau.Le tableau va toujours rester en mémoire tant que la tranche réfère au tableau.
Pour résoudre ce problème. On va utiliser le fonction copy func copy(dst, src []T) int
pour créer une copie de la tranche, comme ça on peut utiliser la nouvelle tranche et le tableau original peut servir à la collection d'éléments.
package main
import (
"fmt"
)
func countries() []string {
countries := []string{"USA", "Singapore", "Germany", "India", "Australia"}
neededCountries := countries[:len(countries)-2]
countriesCpy := make([]string, len(neededCountries))
copy(countriesCpy, neededCountries)
return countriesCpy
}
func main() {
countriesNeeded := countries()
fmt.Println(countriesNeeded)
}
neededCountries := countries[:len(countries)-2]
crée une tranche en éliminant les deux derniers éléments. Le programme ci-dessus copie neededCountries
dans countriesCpy
qui est retourné par la fonction dans la ligne suivante. Maintenant le tableau countries
peut servir de collection d'éléments tant que neededCountries
n'est plus referencé.
Posted on Utopian.io - Rewarding Open Source Contributors
Thank you for the contribution. It has been approved.
You can contact us on Discord.
[utopian-moderator]
Hey @raptorjesus I am @utopian-io. I have just upvoted you!
Achievements
Suggestions
Get Noticed!
Community-Driven Witness!
I am the first and only Steem Community-Driven Witness. Participate on Discord. Lets GROW TOGETHER!
Up-vote this comment to grow my power and help Open Source contributions like this one. Want to chat? Join me on Discord https://discord.gg/Pc8HG9x