Menu
CoddyTech

Interface rỗng (any)

Thuộc phần Lập trình hướng đối tượng trong hành trình GO của Coddy. Bài học 28 trên 107.

Giao diện rỗng là giao diện không có phương thức (method) nào. Vì mọi kiểu dữ liệu (type) trong Go đều có ít nhất 0 phương thức, nên mọi kiểu dữ liệu đều tự động thỏa mãn giao diện rỗng. Nhờ vậy, giao diện rỗng có thể chứa giá trị thuộc bất kỳ kiểu dữ liệu nào.

var anything interface{}

anything = 42
anything = "hello"
anything = true
anything = []int{1, 2, 3}

Từ Go 1.18, từ khóa any được giới thiệu làm bí danh cho interface{}. Hai cách viết này hoàn toàn có thể thay thế cho nhau, nhưng any dễ đọc hơn.

var value any = "Go is awesome"

Giao diện rỗng hữu ích khi bạn cần xử lý các giá trị có kiểu chưa biết hoặc thay đổi. Các hàm như fmt.Println dùng giao diện này để nhận đối số thuộc bất kỳ kiểu nào:

func PrintAnything(v any) {
    fmt.Println("Value:", v)
}

func main() {
    PrintAnything(100)
    PrintAnything("text")
    PrintAnything(3.14)
}

Tuy nhiên, điều này có một sự đánh đổi. Khi lưu một giá trị trong một interface rỗng, bạn sẽ mất quyền truy cập vào thông tin kiểu dữ liệu cụ thể của nó.

Bạn không thể gọi trực tiếp các phương thức hoặc truy cập các trường nếu chưa trích xuất kiểu dữ liệu bên dưới. Các bài học tiếp theo sẽ hướng dẫn cách lấy kiểu cụ thể từ một interface rỗng bằng cách dùng phép khẳng định kiểu và câu lệnh switch kiểu.

challenge icon

Thử thách

Dễ

Hãy tạo một vật chứa lưu trữ linh hoạt có thể chứa giá trị thuộc bất kỳ kiểu dữ liệu nào bằng cách dùng giao diện rỗng. Bạn sẽ tạo một chiếc hộp đơn giản để minh họa cách any cho phép bạn lưu trữ các kiểu dữ liệu khác nhau trong cùng một cấu trúc.

Bạn sẽ sắp xếp code trong hai tệp:

  • box.go: Định nghĩa một cấu trúc Box với một trường duy nhất là Content, có kiểu any. Tạo hàm khởi tạo NewBox nhận một giá trị thuộc bất kỳ kiểu dữ liệu nào và trả về con trỏ đến một Box chứa giá trị đó. Thêm phương thức Describe trả về chuỗi cho biết nội dung được lưu trong hộp.
  • main.go: Đọc các giá trị khác nhau từ đầu vào, tạo các hộp chứa một số nguyên, một chuỗi và một giá trị boolean, sau đó in nội dung mô tả của từng hộp để cho thấy cùng một kiểu Box có thể chứa các giá trị hoàn toàn khác nhau.

Đầu vào sẽ gồm:

  • Dòng 1: Một giá trị số nguyên
  • Dòng 2: Một giá trị chuỗi
  • Dòng 3: Một giá trị boolean (true hoặc false)

Phương thức Describe của bạn cần trả về một chuỗi theo định dạng sau:

Box contains: [value]

Ví dụ, với các giá trị 42, hello và true, đầu ra của bạn sẽ là:

Box contains: 42
Box contains: hello
Box contains: true

Điểm mấu chốt ở đây là cấu trúc Box duy nhất của bạn có thể lưu trữ một số nguyên, một chuỗi hoặc một giá trị boolean, tất cả là nhờ kiểu any chấp nhận giá trị thuộc bất kỳ kiểu dữ liệu nào. Mỗi hộp chứa một nội dung khác nhau, nhưng tất cả đều có cùng kiểu Box.

Tự làm thử

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func main() {
	reader := bufio.NewReader(os.Stdin)

	// Đọc giá trị số nguyên
	line1, _ := reader.ReadString('\n')
	intVal, _ := strconv.Atoi(strings.TrimSpace(line1))

	// Đọc giá trị chuỗi
	line2, _ := reader.ReadString('\n')
	strVal := strings.TrimSpace(line2)

	// Đọc giá trị boolean
	line3, _ := reader.ReadString('\n')
	boolVal, _ := strconv.ParseBool(strings.TrimSpace(line3))

	// TODO: Tạo một hộp cho mỗi giá trị bằng NewBox
	// TODO: In ra mô tả của từng hộp bằng phương thức Describe

	// Dùng các biến để tránh lỗi biên dịch (xóa các dòng này khi triển khai)
	_ = intVal
	_ = strVal
	_ = boolVal

	// Ví dụ về định dạng đầu ra:
	// fmt.Println(box.Describe())
}
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 Lập trình hướng đối tượng

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