Golang cơ bản (Phần 3: Array, Slices, Maps)
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 string
và value 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 nil
thì run time panic
sẽ xảy ra. Do đó nếu ta có một map là nil
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:
All rights reserved