Berbagi teknologi

[Go series] array, irisan dan peta

2024-07-12

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

Hubungkan yang sebelumnya dan berikutnya

Kami telah memperkenalkan if dan for pada artikel kami sebelumnya. Ini tidak boleh dilakukan. Mari kita praktikkan cara menggunakannya.continue Pernyataan untuk menghitung jumlah bilangan genap dalam 100. Saat kami menulis kode,continuepernyataan ini akan membantu kita melewati iterasi tertentu yang tidak diperlukan, misalnya pada contoh ini, kita akan melewatkan semua bilangan ganjil.

  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)

Mulailah belajar

Dalam pemrograman, kita sering kali harus berurusan dengan sekumpulan elemen dengan tipe yang sama, dan kumpulan elemen ini diwakili oleh struktur data tertentu dalam bahasa Go. Hari ini, saya akan memperkenalkan Anda pada beberapa tipe koleksi di Go secara detail: array, irisan, dan peta.

Himpunan

Pertama, mari kita mulai dengan array. Array adalah struktur data paling dasar di Go. Ini adalah rangkaian elemen dengan tipe yang sama dengan panjang tetap. Setelah array dideklarasikan, panjangnya tidak dapat diubah. Deklarasi dan inisialisasi array sangat sederhana,

Deklarasikan array

Saat mendeklarasikan array, Anda perlu menentukan tipe array dan panjang array. Berikut cara mendeklarasikan array:

var arrayName [arrayLength]elementType

Misalnya, deklarasikan array integer dengan panjang 5:

var numbers [5]int
inisialisasi array

Anda dapat menginisialisasi array dengan berbagai cara:

  • Gunakan inisialisasi literal:
var numbers = [5]int{1, 2, 3, 4, 5}
  • menggunakan:=Pernyataan singkat:
numbers := [5]int{1, 2, 3, 4, 5}
  • Secara otomatis menyimpulkan panjang array:
numbers := [...]int{1, 2, 3, 4, 5}
  • Tentukan inisialisasi indeks:
numbers := [5]int{0: 1, 4: 5}

Karakteristik array

  • Panjang tetap: Panjang array ditentukan saat dideklarasikan dan tidak dapat diubah di kemudian hari.
  • elemen dengan tipe yang sama: Array hanya dapat berisi elemen dengan tipe yang sama.
  • alokasi memori secara bersamaan: Elemen array dialokasikan secara berdekatan di memori, sehingga pengaksesan elemen array menjadi sangat efisien.

Akses elemen array

Anda dapat mengakses elemen dalam array berdasarkan indeks, mulai dari 0:

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

Melintasi susunan

Anda dapat gunakanforUlangi semua elemen dalam array:

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

panjang larik

Anda dapat menggunakan yang bawaanlenFungsi untuk mendapatkan panjang array:

length := len(numbers)

nilai nol dari array

Jika sebuah array tidak diinisialisasi secara eksplisit, elemen-elemennya secara otomatis disetel ke nilai nol dari tipenya. Misalnya, nilai nol dari array integer adalah 0:

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

Array Multidimensi

Bahasa Go juga mendukung array multidimensi. Berikut ini contoh mendeklarasikan dan menginisialisasi array integer 2x3:

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

Keterbatasan Array

Karena panjang array tetap, hal ini mungkin tidak terlalu fleksibel dalam beberapa kasus. Jika Anda memerlukan koleksi dengan panjang variabel, Anda dapat menggunakan irisan.

mengiris

Berikutnya adalah irisan, yang merupakan tipe bawaan yang lebih fleksibel yang dapat dianggap sebagai array dinamis. Panjang irisan bervariasi dan dibuat berdasarkan array, sehingga memberikan kemudahan lebih. Berikut cara mendeklarasikan dan menginisialisasi sebuah irisan:

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

Dalam bahasa Go, meskipun array dan irisan digunakan untuk menyimpan serangkaian elemen dengan tipe yang sama, keduanya memiliki perbedaan yang signifikan dalam alokasi memori, variabilitas ukuran, dan penggunaan. Berikut adalah perbedaan utama antara array dan irisan:

variabilitas ukuran

  • Himpunan : Ukuran array ditentukan saat dideklarasikan dan tidak dapat diubah di kemudian hari.Ukuran array adalah bagian dari tipenya, jadi[3]intDan[4]intadalah tipe yang berbeda.
  • mengiris : Irisan bersifat dinamis dan dapat membesar atau menyusut saat runtime.Jadi, ukuran irisan bukan bagian dari jenisnya[]intApakah tipe umum untuk semua irisan bilangan bulat.

alokasi memori

  • Himpunan : Array adalah tipe nilai, dan ketika array dilewatkan sebagai parameter fungsi, salinan nilainya akan diteruskan. Artinya, modifikasi array di dalam fungsi tidak mempengaruhi array asli.
  • mengiris : Slice adalah tipe referensi, yang berisi pointer ke array yang mendasarinya, panjang dan kapasitas irisan. Ketika sebuah irisan dilewatkan sebagai parameter fungsi, salinan pointer akan diteruskan, sehingga modifikasi pada irisan dalam fungsi akan mempengaruhi irisan asli.

inisialisasi

  • Himpunan: Saat menginisialisasi array, ukurannya harus ditentukan, dan nilai elemen dapat segera ditetapkan.
  • mengiris: Irisan dapat dilewatkan melalui literal,makeFungsi atau potongan dari array yang akan diinisialisasi, tidak ada ukuran yang ditentukan.

Kode sampel

Berikut adalah contoh inisialisasi untuk array dan irisan:

  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)

Perbedaan fungsional

  • Himpunan: Karena ukuran larik tetap, ukuran larik diketahui pada waktu kompilasi, yang memungkinkan pengalokasian memori untuk larik di tumpukan, dan kompleksitas waktu untuk mengakses elemen larik adalah O(1).
  • mengiris: Mengiris memberikan lebih banyak fleksibilitas denganappend Fungsi menambahkan elemen, atau memperoleh subirisan melalui operasi pemotongan.Array yang mendasari irisan dapat dialokasikan di heap, dan kompleksitas waktu untuk mengakses elemen irisan juga O(1), tetapiappendDapat mengakibatkan realokasi array yang mendasarinya, yang biasanya merupakan operasi O(n).

pemetaan

Terakhir, mari kita lihat pemetaan. Peta adalah array asosiatif di Go yang memetakan kunci ke nilai. Kunci peta dapat berupa jenis apa pun yang didukung oleh operator kesetaraan, seperti bilangan bulat, angka floating point, string, pointer, antarmuka (selama nilai yang terkandung dalam antarmuka sebanding), struktur, dan array. Nilai yang dipetakan dapat berupa jenis apa pun.

Deklarasi dan inisialisasi

mendeklarasikan peta

Sintaks untuk mendeklarasikan peta adalah sebagai berikut:

var mapName map[keyType]valueType

Misalnya, deklarasikan peta dengan kunci sebagai string dan nilai sebagai bilangan bulat:

var scores map[string]int
Inisialisasi peta

Setelah mendeklarasikan peta, Anda harus melewatinyamakeberfungsi untuk menginisialisasinya sehingga dapat digunakan:

scores = make(map[string]int)

Alternatifnya, Anda dapat menggunakan deklarasi singkat dan menginisialisasi:

scores := make(map[string]int)

Anda juga dapat menggunakan literal untuk inisialisasi pada saat deklarasi:

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

Fitur peta

  • keunikan utama: Dalam peta, setiap kunci bersifat unik. Jika Anda mencoba memasukkan kunci yang ada, nilai yang sesuai dengan kunci tersebut akan diperbarui.
  • kekacauan:peta tidak berurutan, dan urutan elemen mungkin berbeda setiap kali peta diiterasi.
  • ukuran dinamis:Ukuran peta bersifat dinamis, Anda dapat menambah atau menghapus pasangan nilai kunci sesuai kebutuhan.
  • tipe referensi: Peta adalah tipe referensi. Saat Anda meneruskan peta ke suatu fungsi, yang sebenarnya Anda teruskan adalah penunjuk ke struktur data yang mendasarinya.

Peta operasi

Tambahkan elemen
scores["alice"] = 90
Dapatkan elemen
value := scores["alice"]

Jika kunci tidak ada, nilai nol untuk tipe nilai tersebut akan dikembalikan.

Periksa apakah kuncinya ada

Anda dapat menggunakan idiom koma -ok untuk memeriksa apakah kuncinya ada di peta:

  1. value, exists := scores["alice"]
  2. if exists {
  3. // 键存在
  4. } else {
  5. // 键不存在
  6. }
Hapus elemen

menggunakandeleteFungsi dapat menghapus pasangan nilai kunci dari peta:

delete(scores, "alice")

Jika kuncinya tidak ada,deleteFungsi ini tidak melakukan apa pun.

Lintasi peta

menggunakanforSebuah loop dapat melintasi semua pasangan nilai kunci di peta:

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

nilai nol peta

Nilai nol dari peta adalahnil .satunil Peta tidak memiliki struktur data dasar dan tidak dapat menambahkan elemen.Sebelum menambahkan elemen ke peta, Anda harus menggunakanmakeInisialisasi itu.

panjang peta

Anda dapat menggunakan yang bawaanlenBerfungsi untuk mendapatkan jumlah pasangan nilai kunci di peta:

length := len(scores)

jenis kunci peta

Kunci peta dapat berupa tipe pembanding apa pun, seperti bilangan bulat, bilangan floating point, string, pointer, antarmuka (selama nilai yang terkandung dalam antarmuka sebanding), struktur, array, dll. Irisan, peta, dan fungsi tidak dapat digunakan sebagai kunci peta karena jenis ini tidak mendukung perbandingan kesetaraan.

Mudah melakukan kesalahan

Dalam bahasa Go, array, irisan, dan peta adalah tiga struktur data yang umum digunakan, yang masing-masing memiliki karakteristik dan pertimbangan berbeda. Berikut beberapa hal yang perlu diperhatikan saat menggunakannya:

Himpunan

  • Hindari penggunaan array yang terlalu besar karena memakan banyak ruang tumpukan dan dapat menyebabkan tumpukan meluap.
  • Array digunakan ketika kumpulan data berukuran tetap diperlukan.

Mengiris

  • Realokasi memori dapat terjadi ketika pemotongan diperluas. Cobalah untuk mengalokasikan kapasitas yang cukup terlebih dahulu untuk menghindari perluasan yang sering.
  • Hindari penggunaan irisan yang terlalu besar karena dapat memakan banyak ruang.
  • Perhatikan bahwa nilai nol dari irisan tersebut adalahnil, perlu diinisialisasi sebelum digunakan.

peta

  • Nilai nol dari peta adalahnilnilPeta tidak dapat digunakan untuk menyimpan pasangan nilai kunci dan harus diinisialisasi sebelum digunakan.
  • Dalam lingkungan bersamaan, operasi baca dan tulis pada peta tidak aman untuk thread dan perlu dilindungi dengan menggunakan kunci mutex atau mekanisme sinkronisasi lainnya.
  • menggunakandeleteMenghapus kunci yang tidak ada tidak menghasilkan kesalahan, namun aman untuk memeriksa apakah kunci tersebut ada.