Skip to main content

[Go] nil không là duy nhất, cap(map) = ?

Trong Python, None là giá trị duy nhất thể hiện sự "không có gì", sự "null", thì trong Go, nil lại là nhiều thứ khác nhau.

Go nil có kiểu

Mỗi giá trị nil có kiểu cụ thể.

package main

func main() {
    var s []int
    var m map[string]int

    println(s == nil)
    println(m == nil)
    // println(x == y) // Compile error: ./nil.go:9:15: invalid operation: s == m (mismatched types []int and map[string]int)
}

s và m đều bằng nil, nhưng không bằng nhau.

nil map không phải là vô dụng

var m map[string]int

Khi 1 map chưa được khởi tạo, nó có giá trị là nil. Map là kiểu reference, như pointer hay slices. nil map vẫn đọc giá trị bình thường (giá trị là zero value của kiểu int tức 0):

var m map[string]int
v := m["password"]
println(m)// 0x0
println(v)// 0

nil map không thêm được giá trị.

var m map[string]int
m["age"] = 8

Panic với nội dung

panic: assignment to entry in nil map

goroutine 1 [running]:
main.main()
    /home/hvn/me/familug.github.io/content/nil.go:5 +0x2e

panic: assignment to entry in nil map

nil map giống như empty map khi read, nhưng khác khi write.

var m map[string]int
fmt.Printf("nil: %v\n", m)
// nil: map[]

var e = map[string]int{}
fmt.Printf("empty: %v\n", e)
// empty: map[]

cap(map) bằng mấy?

Các kiểu reference trong Go phải allocation để cấp phát bộ nhớ sử dụng new hoặc make. Dùng make để alloc map hay slice.

It creates slices, maps, and channels only, and it returns an initialized (not zeroed) value of type T (not *T). The reason for the distinction is that these three types represent, under the covers, references to data structures that must be initialized before use. A slice, for example, is a three-item descriptor containing a pointer to the data (inside an array), the length, and the capacity, and until those items are initialized, the slice is nil. For slices, maps, and channels, make initializes the internal data structure and prepares the value for use. https://go.dev/doc/effective_go#allocation_make

Một slice chứa 3 thông tin: pointer tới array phía dưới, length và capacity.

A slice is a descriptor of an array segment. It consists of a pointer to the array, the length of the segment, and its capacity (the maximum length of the segment). https://go.dev/blog/slices-intro

var nilSlice []int
fmt.Printf("%v len %d cap %d\n", nilSlice, len(nilSlice), cap(nilSlice))
// [] len 0 cap 0

var s = make([]int, 0)
fmt.Printf("%v len %d cap %d\n", s, len(s), cap(s))
// [] len 0 cap 0

var a = make([]int, 2, 10)
fmt.Printf("%v len %d cap %d\n", a, len(a), cap(a))
// [0 0] len 2 cap 10

Và dùng make với map:

var m = make(map[string]int)
fmt.Printf("%v len %d cap ?\n", m, len(m))

cap(m) bằng mấy?

fmt.Printf("%v len %d cap %d\n", m, len(m), cap(m))

./nil.go:7:49: invalid argument: m (variable of type map[string]int) for cap

Không dùng được cap với map. Tại sao? vì nó như thế và sẽ không thay đổi.

Sau 12+ năm dùng Go, tác giả bradfitz (golang team (2010-2020)) đã đề xuất thêm cap(map), nhưng đã bị từ chối https://github.com/golang/go/issues/52157.

Tham khảo

Kết luận

Go thật đơn giản, và đầy bất ngờ.

Hết.

HVN at http://pymi.vn and https://www.familug.org.

Ủng hộ tác giả 🍺

Comments

Popular posts from this blog

Tài liệu và hướng dẫn học Python

Để tiết kiệm thời gian, tốt nhất là đi học PyMI Updated: 130617 Sau đây là các tài liệu khuyên dùng: Vì nhiều lý do, nên học python2.7 tại thời điểm hiện tại (giờ là tháng 6/2013 - muốn biết tại sao thì tự tìm hiểu) python 3.5+ (giờ là tháng 2/2017) Chuẩn bị: 1. biết bật tắt máy 2. biết cài python 3. tập gõ 10 ngón - gõ 2 ngón hay 1 ngón cũng không sao, nhưng 10 ngón là cách dễ nhất để gõ nhanh nhất. Tài liệu - Nên dùng tài liệu tại trang chủ của Python làm chính, tham khảo thêm các tài liệu khác tại http://www.familug.org/2016/12/free-ebook.html Căn bản, mới học 1.1 Python PyMI.vn https://pymi.vn/tutorial/ 1.2. Python offical tutorial kết hợp làm bài tập trên HackerRank  (đề bài bằng tiếng Anh, nhưng Google translate 1 lúc cũng ra vì có nhiều ví dụ mẫu đi kèm). Học viên của Pymi.vn có rất nhiều học viên đã tự học với Learn Python the hard way nhưng chưa thấy ai thành công cả. Hai link dưới nên đọc sau khi đã nắm được những phần cơ bản của ngôn ngữ pytho...

The PyMiers

New FAMILUG