Menu
CoddyTech

Khẳng định kiểu

Thuộc phần Giới thiệu về Luau trong hành trình Lua của Coddy. Bài học 74 trên 80.

Bạn đã dùng :: một lần trong chương về enum để coi io.read() là một Direction. Bài học này sẽ giải thích kỹ hơn.

Đôi khi bạn biết nhiều hơn về một giá trị so với trình kiểm tra kiểu của Luau: chẳng hạn, bạn biết một giá trị có kiểu any thực chất là bản ghi người dùng. Ép kiểu (type assertion) (còn gọi là chuyển kiểu (cast)) cho phép bạn bảo trình kiểm tra: “cứ tin mình, hãy coi giá trị này là kiểu này”. Toán tử ép kiểu của Luau là :::

type User = {id: number, username: string}

local raw: any = {id = 42, username = "alice_dev"}
local user = raw :: User
print(user.username) -- Giờ trình kiểm tra đã biết các trường dữ liệu

Ép kiểu chỉ thay đổi điều mà trình kiểm tra kiểu tin tưởng. Thao tác này không làm gì khi chạy chương trình. Nó không bao giờ chuyển đổi giá trị: "5" :: any vẫn là chuỗi "5", không phải số 5 (hãy dùng tonumber để chuyển đổi thực sự). Nó cũng không xác thực giá trị: nếu bạn ép sang sai kiểu, bản thân thao tác ép kiểu sẽ không gây lỗi. Code của bạn chỉ hoạt động sai về sau, khi truy cập các thuộc tính không tồn tại.

Khi nào nên dùng: khi một giá trị có kiểu any (hoặc một kiểu hợp rộng) và bạn thực sự biết cấu trúc của nó. Khi nào không nên dùng: để bỏ qua lỗi kiểu mà bạn không hiểu: lỗi thường báo cho bạn biết về một bug thực sự, còn việc ép kiểu chỉ che giấu bug đó. Nếu có thể xác minh khi chạy chương trình, hãy ưu tiên kiểm tra thực sự (như các điều kiện kiểm tra typeof trong bài học tiếp theo).

challenge icon

Thử thách

Dễ

Đọc một bản ghi có kiểu dữ liệu any.

  1. Viết type User = {id: number, username: string, isActive: boolean}.
  2. Viết local function describeUser(data: any): string, ép kiểu bằng local user = data :: User và trả về `User {user.id}: {user.username} (Active: {user.isActive})`.
  3. In ra describeUser(rawUser2).

Nhấn Chạy code: đầu ra hiển thị User 15: bob_admin (Active: false).

Tự làm thử

-- Các bản ghi thô từ bên ngoài chương trình: có kiểu any
local rawUser1: any = {id = 7, username = "nina_dev", isActive = true}
local rawUser2: any = {id = 15, username = "bob_admin", isActive = false}

-- 1) type User = {...}
-- 2) describeUser(data: any): string, ép kiểu bằng ::
-- 3) in ra describeUser(rawUser2)

Tất cả bài học trong Giới thiệu về Luau

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