Menu
CoddyTech

Kiểm tra map nil

Thuộc phần Logic và luồng điều khiển trong hành trình GO của Coddy. Bài học 28 trên 68.

Trong Go, một từ điển có thể có trạng thái đặc biệt gọi là nil. Từ điển nil về cơ bản là một từ điển chưa được khởi tạo và không trỏ đến đâu trong bộ nhớ. Bạn cần hiểu khái niệm này vì nếu cố thêm khóa vào từ điển nil, chương trình sẽ hoảng loạn và gặp sự cố.

Dưới đây là cách một map nil xuất hiện và trông như thế nào:

var myMap map[string]int
// myMap có giá trị nil tại thời điểm này

Khi khai báo một biến map mà không khởi tạo, Go tự động đặt nó thành nil. Bạn có thể đọc an toàn từ một map nil (nó sẽ trả về giá trị không), nhưng nếu thử ghi vào đó, chương trình sẽ gặp panic:

// Thao tác này an toàn, trả về 0
value := myMap["key"]

// Thao tác này sẽ gây panic!
myMap["key"] = 42

Để tránh vấn đề này, bạn luôn nên kiểm tra xem một từ điển có phải là nil hay không trước khi thêm khóa vào đó. Cách kiểm tra rất đơn giản:

if myMap == nil {
    myMap = make(map[string]int)
}
myMap["key"] = 42 // Giờ thao tác này đã an toàn

Kiểm tra đơn giản này giúp chương trình không bị lỗi khi làm việc với các từ điển có thể chưa được khởi tạo, giúp code của bạn ổn định và đáng tin cậy hơn.

challenge icon

Thử thách

Dễ

Tạo một hệ thống khởi tạo map an toàn để ngăn lỗi panic bằng cách kiểm tra map có nil hay không trước khi ghi dữ liệu. Thử thách này cho thấy tầm quan trọng của việc xác thực trạng thái map trước khi thực hiện các thao tác có thể làm chương trình bị crash.

Bạn sẽ nhận hai đầu vào:

  • Một chuỗi biểu thị số thao tác (ví dụ: "5")
  • Một chuỗi chứa các thao tác, được phân tách bằng dấu phẩy. Mỗi thao tác nêu tên map mà thao tác đó sử dụng:
    • "check:[map_name]"
    • "init:[map_name]"
    • "add:[map_name]:[key]:[value]"
    Ví dụ: "check:scores,init:scores,add:scores:Alice:95,add:scores:Bob:87,check:grades"

Nhiệm vụ của bạn là:

  1. Tạo hai biến map có kiểu map[string]int, tên là scores và grades, nhưng không khởi tạo chúng (chúng sẽ là nil)
  2. Xử lý lần lượt từng thao tác trong chuỗi đầu vào:
  3. Với thao tác "check":
    • Kiểm tra map được chỉ định có nil hay không
    • In ra "Map [map_name] is nil" nếu map là nil
    • In ra "Map [map_name] is initialized" nếu map không phải nil
  4. Với thao tác "init":
    • Khởi tạo map được chỉ định bằng make(map[string]int)
    • In ra "Initialized map [map_name]"
  5. Với thao tác "add":
    • Trước tiên, kiểm tra map có nil hay không
    • Nếu map là nil, in ra "Cannot add to nil map [map_name]"
    • Nếu map không phải nil, thêm cặp khóa-giá trị rồi in ra "Added [key]:[value] to [map_name]"
  6. Phân tích các thao tác bằng cách tách chuỗi đầu vào:
    • Tách theo dấu phẩy để lấy từng thao tác riêng lẻ
    • Với mỗi thao tác, tách theo dấu hai chấm để lấy loại thao tác và các tham số
    • Chuyển chuỗi giá trị thành số nguyên với thao tác add
  7. Sau khi xử lý tất cả thao tác, hiển thị trạng thái cuối cùng của cả hai map:
    • Với mỗi map, nếu map là nil: "Final state - [map_name]: nil"
    • Với mỗi map, nếu map đã được khởi tạo: "Final state - [map_name]: [count] entries", trong đó count là số cặp khóa-giá trị
    • In scores trước và grades sau, bất kể thứ tự các thao tác đã sử dụng chúng

Dùng package strconv để chuyển chuỗi giá trị thành số nguyên với thao tác add. Thử thách này cho thấy việc kiểm tra map có nil hay không trước khi ghi dữ liệu giúp ngăn lỗi panic khi chạy và làm cho code của bạn vững chắc, đáng tin cậy hơn.

Tự làm thử

package main

import (
	"fmt"
	"strconv"
	"strings"
)

func main() {
	// Đọc đầu vào
	var numOpsStr string
	var operationsStr string
	fmt.Scanln(&numOpsStr)
	fmt.Scanln(&operationsStr)
	
	// Khai báo các map mà không khởi tạo (chúng sẽ là nil)
	var scores map[string]int
	var grades map[string]int
	
	// Tách các thao tác theo dấu phẩy
	operations := strings.Split(operationsStr, ",")
	
	// TODO: Viết code của bạn bên dưới
	// Xử lý lần lượt từng thao tác
	// Xử lý các thao tác "check", "init" và "add"
	// Với thao tác add, dùng strconv.Atoi() để chuyển chuỗi giá trị thành số nguyên
	
	// In ra trạng thái cuối cùng của cả hai map
	// Kiểm tra các map là nil hay đã khởi tạo rồi in ra cho phù hợp
}
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Logic và luồng điều khiển

Tự luyện tập: Trình biên dịch Go online