+3

Golang cơ bản (Phần 3: Array, Slices, Maps)

Mayfest2023 ContentCreator

Chúng ta cùng tiếp tục với series Golang cơ bản này nhé. Ở phần này chúng ta sẽ tìm hiểu về:

  • Array
  • Slices
  • Maps

Bắt đầu thôi 😄

Array

Mảng (Array) là tập hợp của các phần tử có cùng một kiểu dữ liệu. Nếu các phần tử trong mảng có type khác nhau Go sẽ không thực thi được, ví dụ một mảng chứa cả chuỗi và số nguyên sẽ không được coi là hợp lệ trong Go.

Ví dụ khai báo một array hợp lệ trong Go:

var arr [10]int

Trong đó arr là tên array và có 10 phần tử có kiểu dữ liệu là int. Trong trường hợp này arr là một mảng số nguyên nên tất cả các phần tử của arr được gán bằng 0.

Cũng giống các ngôn ngữ khác, chỉ số của một mảng bắt đầu từ 0 và kết thúc ở length - 1.

Cùng chạy thử ví dụ sau nhé:

package main

import "fmt"

func main() {  
    var arr [10]int // int array with length 10
    arr[0] = 1 // array index starts at 0
    arr[6] = 2
    fmt.Println(arr)
}

Output:

[1 0 0 0 0 0 2 0 0 0]

Ngoài ra chúng ta còn có thể khai báo ngắn như sau:

arr := [5]int{1, 2, 3, 4, 5}

Việc khai báo ngắn không nhất thiết tất cả các phần tử trong một mảng phải được gán một giá trị, các phân tử không được khai báo vẫn sẽ được gán bằng 0 hoặc type là string thì sẽ bằng rỗng.

Mảng trong Go là các loại giá trị và không phải là loại tham chiếu. Điều này có nghĩa là khi chúng được gán cho một biến mới, một bản copy của bản gốc sẽ được gán cho biến mới này. Nếu thay đổi được thực hiện trên biến mới, nó sẽ không xét lại trong mảng ban đầu. Ví dụ như:

package main

import "fmt"

func main() {  
    a := [5]int{1, 2, 3, 4, 5}
    b := a // a copy of a is assigned to b
    b[0] = 6
    b[1] = 7
    fmt.Println("a is ", a)
    fmt.Println("b is ", b) 
}

Output:

a is  [1 2 3 4 5]
b is  [6 7 3 4 5]

Để xác định độ dài của mảng thì ta dùng function len với tham số là mảng cần xác định.

Để lặp một mảng trong Go bằng cách sử dụng range của vòng lặp for.

for i, v := range arr {
    //range returns both the index and value
}

Mặc dù các mảng trông có vẻ gọn nhưng chiều dài của chúng có giới hạn cố định. Độ dài của mảng không thể tăng.

Thực tế trong Go, slices phổ biến hơn so với mảng thông thường.

Slices

Slices cũng là một kiểu dữ liệu dạng tập hợp như array, các phần tử trong slices cũng được đánh chỉ số. Điểm khác biệt giữa slices và array là số phần tử trong slices có thể thay đổi được. Chúng ta khai báo một slice như sau:

var s []int

Chúng ta có thể tạo slice từ một array bằng cú pháp arr[start: end] sẽ tạo ra một slice từ mảng arr bắt đầu từ vị trí start đến end - 1, ví dụ:

package main

import "fmt"

func main() {
	arr := [5]int{1, 2, 3, 4, 5}
	var s []int = arr[1:4] //creates a slice from arr[1] to arr[3]
	fmt.Println(s)
}

Output:

[2 3 4]

Sửa đổi một slice:

package main

import "fmt"

func main() {
	arr := [5]int{1, 2, 3, 4, 5}
	var s []int = arr[1:4] // [2, 3, 4]
	for i, _ := range s {
		s[i]++
	}
	fmt.Println(s) // [3, 4, 5]
	fmt.Println(arr) // [1, 3, 4, 5, 5]
}

Độ dài của 1 slice tương tự với array là số lượng phần tử có trong slice đó, sử dụng function len(slice) với tham số là slice cần xác định. Sức chứa của slice là chỉ số lượng phần tử cơ bản bắt đầu từ mục mà slice đó được tạo ra. Sử dụng function cap(slice)

Tạo slice sử dụng make với cú pháp make([]T, len, cap) truyền vào type, độ dài và sức chứa. Function make tạo ra một mảng và trả về một slice tham chiếu. Ví dụ: i := make([]int, 5, 5)

Như mình có giới thiệu thì Slice có sự linh động và các phần tử mới có thể thêm vào Slice bằng cách sử dụng function append.

package main

import "fmt"

func main() {  
    a := []int{1, 2, 3}
    fmt.Println("a:", a)
    a = append(a, 4)
    fmt.Println("a:", a)
}

Output:

a: [1 2 3]
a: [1 2 3 4]

Maps

Map là một kiểu dữ liệu được dựng sẵn trong Go, một map là tập hợp các cặp key/value (khóa/giá trị) trong đó một value được liên kết với một key. Value chỉ được truy xuất bởi key tương ứng.

Khai báo 1 map như sau :

var m map[string]int

Hoặc chúng ta có thể sử dụng make để khai báo 1 map:

m := make(map[string]int)

2 cách code trên đều khởi tạo một map có tên là m với các key kiểu stringvalue kiểu int.

Ở cách khai báo đầu tiên giá trị rỗng của map được gọi là nil. Nếu ta cố gắng thêm các phần tử vào một map nilthì run time panic sẽ xảy ra. Do đó nếu ta có một mapnil thì nó phải được khởi tạo và cấp phát vùng nhớ bằng hàm make, sau đó mới có thể thêm phần tử vào map.

Ví dụ:

package main

import "fmt"

func main() {  
    var m map[string]int // khai bao cach 1, map la nil
    if m == nil {
        fmt.Println("map la nil")
        m = make(map[string]int)
    }
}

Việc gán giá trị và truy xuất giá trị trong map cũng tương tự với array và slice, chỉ khác là thay vì chúng ta dùng index thì bây giờ chúng ta dùng key của map.

Ví dụ:

package main

import  "fmt"

func main() {  
    info := make(map[string]string)
    info["name"] = "Nguyen Van Huy"
    info["Country"] = "Viet Nam"
    fmt.Println("info map contents:", info)
}

Output:

info map contents: map[Country:Viet Nam name:Nguyen Van Huy]

Sau khi chúng ta đã thêm được một số phần tử vào map, tiếp theo hãy cùng truy xuất chúng ra nhé. Cú pháp để truy xuất phần tử của map: map[key]

Ví dụ:

package main

import "fmt"

func main() {
	info := map[string]int{
		"A": 1,
		"B": 2,
	}
	info["C"] = 3
	fmt.Println("A is", info["A"])
	fmt.Println("D is", info["D"])
}

Nếu bạn truy xuất 1 phần tử không có trong map thì map sẽ trả về giá trị tương ứng với kiểu dữ liệu của phần tử đó, trong trường hợp này map sẽ trả về kết quả là 0.

Output:

A is 1
D is 0

Nếu chúng ta muốn biết một key có tốn tại trong map hay không thì phải làm thế nào? Cú pháp sẽ như sau:

value, ok := map[key]

Để xóa phần tử trong map, chúng ta sẽ dùng hàm delete(): delete(map, key)

Tương tự với array hay slide thì để xác định chiều dài của map chúng ta sẽ dùng hàm len()

Để duyệt qua tất cả các phần tử của map chúng ta sử dụng range của vòng lặp for:

package main

import "fmt"

func main() {
	info := map[string]int{
		"A": 1,
		"B": 2,
	}
	info["C"] = 3
	for key, value := range info {
        fmt.Printf("info[%s] = %d\n", key, value)
    }
}

Output:

info[A] = 1
info[B] = 2
info[C] = 3

Tổng kết:

Các bạn hãy nhớ theo dõi mình để câp nhật các phần tiếp theo về series golang cơ bản này nhé. Cảm ơn các bạn rất nhiều ❤️

Tài liệu tham khảo:

https://golangbot.com/learn-golang-series/


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí