Κοινή χρήση τεχνολογίας

[Go series] πίνακας, φέτα και χάρτης

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Συνδέστε το προηγούμενο και το επόμενο

Εισαγάγαμε το εάν και για στο προηγούμενο άρθρο μας. Αυτό δεν πρέπει να εξασκηθεί.continue Δήλωση για τον υπολογισμό του αθροίσματος ζυγών αριθμών εντός του 100. Καθώς γράφουμε κώδικα,continueδήλωση θα μας βοηθήσει να παραλείψουμε ορισμένες επαναλήψεις που δεν χρειάζονται, για παράδειγμα, σε αυτό το παράδειγμα, θα παραλείψουμε όλους τους περιττούς αριθμούς.

  1. sum := 0
  2. for i := 1; i < 100; i++{
  3. if i & 1 == 0 {
  4. continue
  5. }
  6. sum += i
  7. }
  8. fmt.Println("the sum is",sum)

Ξεκινήστε να μαθαίνετε

Στον προγραμματισμό, συχνά χρειάζεται να ασχοληθούμε με ένα σύνολο στοιχείων του ίδιου τύπου, και αυτά τα σύνολα στοιχείων αντιπροσωπεύονται από συγκεκριμένες δομές δεδομένων στη γλώσσα Go. Σήμερα, θα σας παρουσιάσω λεπτομερώς διάφορους τύπους συλλογής στο Go: array, slice και map.

πίνακας

Αρχικά, ας ξεκινήσουμε με πίνακες. Ο πίνακας είναι η πιο βασική δομή δεδομένων στο Go Είναι μια ακολουθία στοιχείων του ίδιου τύπου. Μόλις δηλωθεί ένας πίνακας, το μήκος του δεν μπορεί να αλλάξει. Η δήλωση και η προετοιμασία των πινάκων είναι πολύ απλή,

Δήλωση πίνακα

Όταν δηλώνετε έναν πίνακα, πρέπει να καθορίσετε τον τύπο και το μήκος του πίνακα. Δείτε πώς δηλώνεται ένας πίνακας:

var arrayName [arrayLength]elementType

Για παράδειγμα, δηλώστε έναν ακέραιο πίνακα μήκους 5:

var numbers [5]int
αρχικοποίηση πίνακα

Μπορείτε να αρχικοποιήσετε έναν πίνακα με διάφορους τρόπους:

  • Χρησιμοποιήστε την κυριολεκτική προετοιμασία:
var numbers = [5]int{1, 2, 3, 4, 5}
  • χρήση:=Σύντομη δήλωση:
numbers := [5]int{1, 2, 3, 4, 5}
  • Αυτόματη εξαγωγή συμπερασμάτων μήκους πίνακα:
numbers := [...]int{1, 2, 3, 4, 5}
  • Καθορισμός αρχικοποίησης ευρετηρίου:
numbers := [5]int{0: 1, 4: 5}

Χαρακτηριστικά συστοιχιών

  • Σταθερό μήκος: Το μήκος του πίνακα καθορίζεται όταν δηλώνεται και δεν μπορεί να αλλάξει αργότερα.
  • στοιχεία του ίδιου τύπου: Οι πίνακες μπορούν να περιέχουν μόνο στοιχεία του ίδιου τύπου.
  • κατανομή μνήμης συνεχόμενα: Τα στοιχεία πίνακα εκχωρούνται συνεχόμενα στη μνήμη, γεγονός που καθιστά την πρόσβαση σε στοιχεία πίνακα πολύ αποτελεσματική.

Πρόσβαση σε στοιχεία πίνακα

Μπορείτε να αποκτήσετε πρόσβαση σε στοιχεία σε έναν πίνακα ανά ευρετήριο, ξεκινώντας από το 0:

value := numbers[2] // 获取索引为 2 的元素

Τραβέρσα συστοιχία

μπορείς να χρησιμοποιήσειςforΚάντε βρόχο σε όλα τα στοιχεία ενός πίνακα:

  1. for i, value := range numbers {
  2. fmt.Printf("Index: %d, Value: %dn", i, value)
  3. }

μήκος της συστοιχίας

Μπορείτε να χρησιμοποιήσετε το ενσωματωμένοlenΣυνάρτηση για να λάβετε το μήκος ενός πίνακα:

length := len(numbers)

μηδενική τιμή του πίνακα

Εάν ένας πίνακας δεν έχει αρχικοποιηθεί ρητά, τα στοιχεία του ορίζονται αυτόματα στη μηδενική τιμή του τύπου τους. Για παράδειγμα, η μηδενική τιμή ενός ακέραιου πίνακα είναι 0:

var numbers [5]int // 所有元素都是 0

Πολυδιάστατοι πίνακες

Η γλώσσα Go υποστηρίζει επίσης πολυδιάστατους πίνακες. Το παρακάτω είναι ένα παράδειγμα δήλωσης και προετοιμασίας ενός ακέραιου πίνακα 2x3:

  1. var matrix [2][3]int
  2. matrix = [2][3]int{{1, 2, 3}, {4, 5, 6}}

Περιορισμοί Πίνακες

Δεδομένου ότι το μήκος του πίνακα είναι σταθερό, αυτό μπορεί να μην είναι πολύ ευέλικτο σε ορισμένες περιπτώσεις. Εάν χρειάζεστε μια συλλογή μεταβλητού μήκους, μπορείτε να χρησιμοποιήσετε φέτες.

φέτα

Ακολουθεί το slice, το οποίο είναι ένας πιο ευέλικτος ενσωματωμένος τύπος που μπορεί να θεωρηθεί ως ένας δυναμικός πίνακας. Το μήκος της φέτας είναι μεταβλητό και δημιουργείται με βάση έναν πίνακα, παρέχοντας μεγαλύτερη ευκολία. Δείτε πώς μπορείτε να δηλώσετε και να αρχικοποιήσετε ένα slice:

  1. s := make([]int, 3) // 创建一个长度为3的整型切片
  2. s[0] = 1 // 切片元素赋值
  3. s[1] = 2
  4. s[2] = 3
  5. s = append(s, 4) // 向切片追加元素

Στη γλώσσα Go, αν και οι πίνακες και οι φέτες χρησιμοποιούνται και οι δύο για την αποθήκευση μιας σειράς στοιχείων του ίδιου τύπου, έχουν σημαντικές διαφορές στην κατανομή μνήμης, τη μεταβλητότητα μεγέθους και τη χρήση. Ακολουθούν οι κύριες διαφορές μεταξύ πινάκων και κομματιών:

μεταβλητότητα μεγέθους

  • πίνακας : Το μέγεθος ενός πίνακα καθορίζεται όταν δηλώνεται και δεν μπορεί να αλλάξει αργότερα.Το μέγεθος ενός πίνακα είναι μέρος του τύπου του, άρα[3]intκαι[4]intείναι διαφορετικοί τύποι.
  • φέτα : Οι φέτες είναι δυναμικές και μπορούν να αυξηθούν ή να συρρικνωθούν κατά το χρόνο εκτέλεσης.Το μέγεθος μιας φέτας δεν είναι μέρος του τύπου της, έτσι[]intΕίναι ο κοινός τύπος για όλες τις φέτες ακέραιων αριθμών.

κατανομή μνήμης

  • πίνακας : Οι πίνακες είναι τύποι τιμών και όταν ένας πίνακας μεταβιβάζεται ως παράμετρος συνάρτησης, μεταβιβάζεται ένα αντίγραφο της τιμής του. Αυτό σημαίνει ότι οι τροποποιήσεις στον πίνακα μέσα στη συνάρτηση δεν επηρεάζουν τον αρχικό πίνακα.
  • φέτα : Το Slice είναι ένας τύπος αναφοράς, ο οποίος περιέχει έναν δείκτη στον υποκείμενο πίνακα, το μήκος και τη χωρητικότητα της φέτας. Όταν ένα slice μεταβιβάζεται ως παράμετρος συνάρτησης, μεταβιβάζεται ένα αντίγραφο του δείκτη, επομένως οι τροποποιήσεις στο slice εντός της συνάρτησης θα επηρεάσουν το αρχικό slice.

αρχικοποίηση

  • πίνακας: Κατά την προετοιμασία ενός πίνακα, πρέπει να καθοριστεί το μέγεθός του και οι τιμές στοιχείων μπορούν να εκχωρηθούν αμέσως.
  • φέτα: Οι φέτες μπορούν να περάσουν από κυριολεκτικά,makeΛειτουργία ή αποκοπή από έναν πίνακα για προετοιμασία, χωρίς καθορισμένο μέγεθος.

Δείγμα κώδικα

Ακολουθούν παραδείγματα αρχικοποίησης για πίνακες και φέτες:

  1. // 数组
  2. var arr [3]int = [3]int{1, 2, 3}
  3. // 切片
  4. var slice []int = []int{1, 2, 3}
  5. // 或者使用 make 函数
  6. slice := make([]int, 3)

Λειτουργικές διαφορές

  • πίνακας: Εφόσον το μέγεθος είναι σταθερό, το μέγεθος του πίνακα είναι γνωστό κατά το χρόνο μεταγλώττισης, γεγονός που καθιστά δυνατή την κατανομή μνήμης για τον πίνακα στη στοίβα και η χρονική πολυπλοκότητα της πρόσβασης στα στοιχεία του πίνακα είναι O(1).
  • φέτα: Ο τεμαχισμός παρέχει μεγαλύτερη ευελιξίαappend Η συνάρτηση προσθέτει στοιχεία ή αποκτά υποτμήματα μέσω λειτουργιών τεμαχισμού.Ο υποκείμενος πίνακας του slice μπορεί να εκχωρηθεί στο σωρό και η χρονική πολυπλοκότητα της πρόσβασης στα στοιχεία slice είναι επίσης O(1), αλλάappendΜπορεί να οδηγήσει σε ανακατανομή του υποκείμενου πίνακα, που είναι συνήθως μια λειτουργία O(n).

χαρτογράφηση

Τέλος, ας δούμε τη χαρτογράφηση. Ένας χάρτης είναι ένας συσχετιστικός πίνακας στο Go που αντιστοιχίζει κλειδιά σε τιμές. Τα κλειδιά του χάρτη μπορούν να είναι οποιουδήποτε τύπου που υποστηρίζονται από τον τελεστή ισότητας, όπως ακέραιοι, αριθμοί κινητής υποδιαστολής, συμβολοσειρές, δείκτες, διεπαφές (εφόσον οι τιμές που περιέχονται στη διεπαφή είναι συγκρίσιμες), δομές και πίνακες. Η αντιστοιχισμένη τιμή μπορεί να είναι οποιουδήποτε τύπου.

Δήλωση και αρχικοποίηση

δηλώσει χάρτη

Η σύνταξη για τη δήλωση ενός χάρτη είναι η εξής:

var mapName map[keyType]valueType

Για παράδειγμα, δηλώστε έναν χάρτη με κλειδιά ως συμβολοσειρές και τιμές ως ακέραιους αριθμούς:

var scores map[string]int
Αρχικοποίηση χάρτη

Αφού δηλώσετε χάρτη, πρέπει να περάσετεmakeσυνάρτηση για την αρχικοποίησή του ώστε να μπορεί να χρησιμοποιηθεί:

scores = make(map[string]int)

Εναλλακτικά, μπορείτε να χρησιμοποιήσετε μια σύντομη δήλωση και να αρχικοποιήσετε:

scores := make(map[string]int)

Μπορείτε επίσης να χρησιμοποιήσετε κυριολεκτικά για αρχικοποίηση τη στιγμή της δήλωσης:

  1. scores := map[string]int{
  2. "alice": 90,
  3. "bob": 85,
  4. "charlie": 88,
  5. }

Χαρακτηριστικά του χάρτη

  • βασική μοναδικότητα: Σε έναν χάρτη, κάθε κλειδί είναι μοναδικό Αν προσπαθήσετε να εισαγάγετε ένα υπάρχον κλειδί, θα ενημερώσει την τιμή που αντιστοιχεί στο κλειδί.
  • διαταραχήΤο :map δεν είναι ταξινομημένο και η σειρά των στοιχείων μπορεί να είναι διαφορετική κάθε φορά που επαναλαμβάνεται ο χάρτης.
  • δυναμικό μέγεθος:Το μέγεθος του χάρτη είναι δυναμικό, μπορείτε να προσθέσετε ή να αφαιρέσετε ζεύγη κλειδιών-τιμών όπως απαιτείται.
  • τύπος αναφοράς: Ο χάρτης είναι ένας τύπος αναφοράς Όταν μεταβιβάζετε χάρτη σε μια συνάρτηση, αυτό που μεταβιβάζετε πραγματικά είναι ένας δείκτης στην υποκείμενη δομή δεδομένων.

Χάρτης λειτουργίας

Προσθήκη στοιχείου
scores["alice"] = 90
Λήψη στοιχείου
value := scores["alice"]

Εάν το κλειδί δεν υπάρχει, θα επιστραφεί μια μηδενική τιμή για αυτόν τον τύπο τιμής.

Ελέγξτε αν υπάρχει κλειδί

Μπορείτε να χρησιμοποιήσετε το κόμμα -ok για να ελέγξετε αν το κλειδί υπάρχει στον χάρτη:

  1. value, exists := scores["alice"]
  2. if exists {
  3. // 键存在
  4. } else {
  5. // 键不存在
  6. }
Διαγραφή στοιχείου

χρήσηdeleteΗ συνάρτηση μπορεί να αφαιρέσει ένα ζεύγος κλειδιού-τιμής από τον χάρτη:

delete(scores, "alice")

Εάν το κλειδί δεν υπάρχει,deleteΗ συνάρτηση δεν κάνει τίποτα.

Διασχίστε τον χάρτη

χρήσηforΈνας βρόχος μπορεί να διασχίσει όλα τα ζεύγη κλειδιών-τιμών στον χάρτη:

  1. for key, value := range scores {
  2. fmt.Printf("%s: %dn", key, value)
  3. }

μηδενική τιμή χάρτη

Η μηδενική τιμή του χάρτη είναιnil .έναςnil Ένας χάρτης δεν έχει υποκείμενη δομή δεδομένων και δεν μπορεί να προσθέσει στοιχεία.Πριν προσθέσετε στοιχεία στον χάρτη, πρέπει να χρησιμοποιήσετεmakeΑρχικοποιήστε το.

μήκος χάρτη

Μπορείτε να χρησιμοποιήσετε το ενσωματωμένοlenΛειτουργία για να λάβετε τον αριθμό των ζευγών κλειδιών-τιμών στον χάρτη:

length := len(scores)

τύπος κλειδιού χάρτη

Τα κλειδιά του χάρτη μπορούν να είναι οποιουδήποτε συγκρίσιμου τύπου, όπως ακέραιοι, αριθμοί κινητής υποδιαστολής, συμβολοσειρές, δείκτες, διεπαφές (εφόσον οι τιμές που περιέχονται στη διεπαφή είναι συγκρίσιμες), δομές, πίνακες κ.λπ. Οι φέτες, οι χάρτες και οι συναρτήσεις δεν μπορούν να χρησιμοποιηθούν ως πλήκτρα χάρτη, επειδή αυτοί οι τύποι δεν υποστηρίζουν συγκρίσεις ισότητας.

Εύκολο να κάνεις λάθη

Στη γλώσσα Go, οι πίνακες, οι φέτες και οι χάρτες είναι τρεις κοινώς χρησιμοποιούμενες δομές δεδομένων, καθεμία από τις οποίες έχει διαφορετικά χαρακτηριστικά και εκτιμήσεις. Ακολουθούν ορισμένα σημεία που πρέπει να προσέξετε κατά τη χρήση τους:

Πίνακας

  • Αποφύγετε τη χρήση υπερβολικά μεγάλων συστοιχιών καθώς καταλαμβάνουν πολύ χώρο στοίβας και μπορεί να προκαλέσουν υπερχείλιση στοίβας.
  • Οι πίνακες χρησιμοποιούνται όταν απαιτείται συλλογή δεδομένων σταθερού μεγέθους.

Φέτα

  • Η ανακατανομή της μνήμης μπορεί να συμβεί όταν επεκτείνεται ο τεμαχισμός. Προσπαθήστε να εκχωρήσετε εκ των προτέρων αρκετή χωρητικότητα για να αποφύγετε τη συχνή επέκταση.
  • Αποφύγετε τη χρήση φετών που είναι πολύ μεγάλες καθώς μπορεί να πιάσουν πολύ χώρο στο σωρό.
  • Σημειώστε ότι η μηδενική τιμή της φέτας είναιnil, πρέπει να αρχικοποιηθεί πριν από τη χρήση.

χάρτης

  • Η μηδενική τιμή του χάρτη είναιnilnilΟ χάρτης δεν μπορεί να χρησιμοποιηθεί για την αποθήκευση ζευγών κλειδιού-τιμής και πρέπει να αρχικοποιηθεί πριν από τη χρήση.
  • Σε ένα ταυτόχρονο περιβάλλον, οι λειτουργίες ανάγνωσης και εγγραφής στο χάρτη δεν είναι ασφαλείς για νήμα και πρέπει να προστατεύονται χρησιμοποιώντας κλειδαριές mutex ή άλλους μηχανισμούς συγχρονισμού.
  • χρήσηdeleteΗ διαγραφή ενός κλειδιού που δεν υπάρχει δεν δημιουργεί σφάλμα, αλλά είναι ασφαλές να ελέγξετε εάν το κλειδί υπάρχει.