Result Builder — nó là gì, cú pháp và ứng dụng

Tác giả: IT Sectr Đã đăng: 2026-06-20 Thời gian đọc: 8 phút

Result Builder là một thuộc tính Swift được triển khai thông qua giao thức @resultBuilder, biến đổi một chuỗi các biểu thức thành một giá trị tổng hợp. Trình biên dịch chuyển đổi các khối mã có cấu trúc điều khiển if, for, switch thành các lời gọi phương thức tĩnh của builder — buildBlock, buildEither, buildArray. Theo đề xuất Swift Evolution SE-0289 (2022), result builders cho phép tạo DSL khai báo bên trong Swift mà không cần trình phân tích cú pháp bên ngoài. Ví dụ nổi tiếng nhất là @ViewBuilder trong SwiftUI, nơi phần thân view được xây dựng từ các phần tử có điều kiện và lặp theo phong cách khai báo.

Những điểm chính

  • Result Builder — một thuộc tính Swift biến đổi chuỗi biểu thức thành giá trị kết quả thông qua các phương thức tĩnh của builder
  • @ViewBuilder — ví dụ nổi tiếng nhất: nó biến đổi nhiều view thành một biểu diễn tổng hợp duy nhất TupleView
  • Cấu trúc điều khiển — builder hỗ trợ if/else, switch, for-in thông qua các phương thức buildOptional, buildEither, buildArray
  • Builder tùy chỉnh có thể được tạo cho DSL riêng của bạn — HTML, CSS, cấu hình, truy vấn
  • Swift 5.4 đã mở rộng hỗ trợ result builders cho các hàm và tham số hàm — giờ bạn có thể áp dụng builder cho một đối số closure

Result Builder là gì?

Result Builder (trước đây gọi là function builders) là một cơ chế Swift cho phép biến đổi một chuỗi các biểu thức được phân cách bằng dấu xuống dòng thành một giá trị duy nhất. Nó được khai báo bằng thuộc tính @resultBuilder áp dụng cho một cấu trúc triển khai các phương thức chuyển đổi tĩnh.

Trước result builders, cú pháp khai báo của SwiftUI body là không thể. Thay vì một danh sách view nhỏ gọn, các nhà phát triển phải viết thủ công các lời gọi TupleView. Result Builder tự động bọc mỗi biểu thức, hỗ trợ rẽ nhánh và vòng lặp, ẩn đi sự phức tạp của việc kết hợp khỏi nhà phát triển.

Theo Swift Evolution SE-0289, được chấp nhận vào năm 2022, result builder là sự phát triển của ý tưởng function builders (SE-0258, Swift 5.1). Các thay đổi chính: đổi tên từ @_functionBuilder thành @resultBuilder và mở rộng sang tham số hàm, cho phép sử dụng builder cho bất kỳ đối số closure nào, không chỉ phần thân view.

Sử dụng result builders khi bạn cần cung cấp cho người dùng thư viện của mình một cú pháp khai báo để xây dựng các cấu trúc phức tạp — cấu hình, truy vấn, thành phần UI — mà không cần viết mã lắp ráp mệnh lệnh.

Result Builder hoạt động như thế nào

Trình biên dịch Swift biến đổi mỗi khối mã được đánh dấu bằng @resultBuilder thành một chuỗi các lời gọi phương thức tĩnh của builder. Hãy xem một builder đơn giản nối chuỗi:

swift
@resultBuilder
struct StringBuilder {
    static func buildBlock(_ parts: String...) -> String {
        parts.joined(separator: " ")
    }
}

Sử dụng builder này — mỗi chuỗi trên một dòng riêng được nối với một khoảng trắng:

swift
@StringBuilder
func greeting() -> String {
    "Hello"
    "World"
    "from"
    "Swift"
}
// Trình biên dịch biến đổi điều này thành:
// StringBuilder.buildBlock("Hello", "World", "from", "Swift")
// Kết quả: "Hello World from Swift"

Trình biên dịch nhóm các biểu thức liên tiếp và truyền chúng dưới dạng tham số variadic cho buildBlock. Nếu một if xuất hiện giữa các biểu thức, trình biên dịch gọi buildOptional hoặc buildEither để rẽ nhánh. Đối với vòng lặp for-in, nó gọi buildArray. Như vậy, mã Swift thông thường được biến đổi thành một chuỗi các lời gọi xây dựng giá trị cuối cùng.

Các phương thức builder: buildBlock, buildOptional, buildEither

Mỗi result builder định nghĩa một tập hợp các phương thức tĩnh mà trình biên dịch gọi trong quá trình chuyển đổi. Các phương thức chính:

Phương thứcMục đíchKhi nào được gọi
buildBlockKết hợp một chuỗi biểu thứcCho mỗi khối không có rẽ nhánh
buildOptionalXử lý if không có elseKhi có if không có else
buildEither(first:)Nhánh đầu tiên của if-elseKhi ifelse
buildEither(second:)Nhánh thứ hai của if-elseKhi ifelse
buildArrayXử lý vòng lặp for-inKhi có for-in
buildExpressionBiến đổi các biểu thức riêng lẻCho mỗi biểu thức trước khi truyền vào buildBlock
buildFinalResultChuyển đổi cuối cùngTrước khi trả về từ closure

Một triển khai tối thiểu chỉ yêu cầu buildBlock với tham số variadic — đủ cho các khối không có rẽ nhánh. Thêm buildOptionalbuildEither bao gồm hỗ trợ cấu trúc điều kiện, và buildArray cho vòng lặp. Theo Tài liệu Swift (2025), nên triển khai tất cả các phương thức để đạt độ linh hoạt tối đa của DSL.

buildExpression cho phép chấp nhận các biểu thức thuộc kiểu khác nhau và chuyển đổi chúng thành một kiểu builder duy nhất. Ví dụ, trong @ViewBuilder, buildExpression chấp nhận Text, Image, Button và chuyển đổi chúng thành kiểu View chung.

Tạo Result Builder tùy chỉnh

Hãy xem xét việc tạo một builder để xây dựng chuỗi HTML. DSL này sẽ cho phép viết HTML khai báo trực tiếp trong Swift:

swift
@resultBuilder
enum HTMLBuilder {
    static func buildBlock(_ components: String...) -> String {
        components.joined()
    }

    static func buildOptional(_ component: String?) -> String {
        component ?? ""
    }

    static func buildEither(first component: String) -> String {
        component
    }

    static func buildEither(second component: String) -> String {
        component
    }

    static func buildArray(_ components: [String]) -> String {
        components.joined()
    }
}

Sử dụng builder tùy chỉnh để tạo HTML:

swift
func div(@HTMLBuilder _ content: () -> String) -> String {
    "<div>\(content())</div>"
}

func p(_ text: String) -> String {
    "<p>\(text)</p>"
}

let page = div {
    p("Hello")
    p("World")

    if showFooter {
        p("Chân trang")
    }
}
// Kết quả: <div><p>Hello</p><p>World</p><p>Footer</p></div>

Theo bài viết “Building Custom Result Builders in Swift” từ Swift.org (2025), builder tùy chỉnh được sử dụng trong các thư viện để xây dựng tệp cấu hình, thành phần UI, ánh xạ dữ liệu và thậm chí truy vấn cơ sở dữ liệu — bất cứ nơi nào cần cú pháp khai báo với hỗ trợ rẽ nhánh.

@ViewBuilder trong SwiftUI

@ViewBuilder là một result builder được tích hợp trong SwiftUI, áp dụng cho tham số content của hầu hết các view chứa: VStack, HStack, ZStack, Group, List và thuộc tính body. Nó cho phép viết nhiều view trên các dòng riêng biệt mà không cần dấu phẩy hay trình bao bọc.

@ViewBuilder triển khai tất cả các phương thức result builder, bao gồm hỗ trợ if-else, switchfor-in. Khi điều kiện đúng, buildEither(first:) trả về một view; khi sai, buildEither(second:) trả về một view khác. Cả hai nhánh phải trả về cùng kiểu, nhưng SwiftUI sử dụng AnyView nội bộ hoặc xóa kiểu thông qua ConditionalContent.

swift
struct GreetingView: View {
    let isLoggedIn: Bool

    var body: some View {
        VStack {
            Image(systemName: "person.circle")
            Text("Hồ sơ")
                .font(.title)

            if isLoggedIn {
                Text("Chào mừng trở lại!")
                    .foregroundColor(.green)
            } else {
                Button("Đăng nhập") { }
            }
        }
    }
}

Nếu không có @ViewBuilder, cùng một mã sẽ yêu cầu Group cho mỗi phần có điều kiện hoặc sử dụng AnyView, làm giảm hiệu suất. @ViewBuilder tự động chọn biểu diễn hiệu quả nhất — ConditionalContent hoặc TupleView — cho mỗi tổ hợp.

Hạn chế của Result Builder

Hạn chế đầu tiên là số lượng biểu thức tối đa trong buildBlock. Thư viện chuẩn Swift định nghĩa các nạp chồng buildBlock cho 2–10 biểu thức. Nếu một khối có hơn 10 biểu thức, trình biên dịch sẽ đưa ra lỗi. Giải pháp là nhóm qua Group hoặc VStack để chia thành các khối con.

Hạn chế thứ hai là thiếu hỗ trợ cho biến và phép gán bên trong khối builder. Bạn không thể khai báo let x = 5 bên trong @ViewBuilder. Tất cả biểu thức phải là biểu thức trả về giá trị kiểu builder. Đối với tính toán trung gian, hãy sử dụng tính toán bên ngoài builder hoặc buildExpression hỗ trợ các kiểu khác nhau.

Hạn chế thứ ba là sự phức tạp khi gỡ lỗi. Lỗi biên dịch bên trong result builder thường tạo ra thông báo khó hiểu, đặc biệt khi kiểu không khớp trong các nhánh if/else. Sử dụng kiểu trả về rõ ràng và AnyView để gỡ lỗi, mặc dù cái sau làm giảm hiệu suất. Theo Hacking with Swift (2025), mẹo thực tế — hãy bắt đầu với một builder đơn giản không rẽ nhánh và dần dần thêm hỗ trợ cấu trúc điều kiện.

Câu hỏi thường gặp

Result Builder trong Swift là gì?

Result Builder là một thuộc tính Swift biến đổi chuỗi biểu thức thành giá trị kết quả thông qua phương thức tĩnh. Nó cho phép tạo DSL khai báo, ví dụ nổi tiếng nhất là @ViewBuilder trong SwiftUI để xây dựng hệ thống phân cấp view mà không cần mã mệnh lệnh.

Làm thế nào để tạo Result Builder riêng?

Khai báo một cấu trúc với thuộc tính @resultBuilder và triển khai ít nhất phương thức buildBlock. Để hỗ trợ điều kiện, thêm buildOptionalbuildEither; cho vòng lặp, thêm buildArray. Sử dụng thuộc tính builder trước tham số closure trong hàm.

Những phương thức nào bắt buộc cho Result Builder?

Chỉ buildBlock là bắt buộc. Tất cả các phương thức khác — buildOptional, buildEither, buildArray, buildExpression, buildFinalResult — là tùy chọn và thêm hỗ trợ cho các cấu trúc tương ứng. Càng nhiều phương thức được triển khai, DSL càng linh hoạt.

Tại sao @ViewBuilder là một Result Builder?

@ViewBuilder là một triển khai cụ thể của result builder cho giao thức View. Nó được định nghĩa trong SwiftUI như một cấu trúc với thuộc tính @resultBuilder, cung cấp phương thức buildBlock cho số lượng view khác nhau (TupleView), buildEither cho ConditionalContent và buildArray cho ForEach.

Có giới hạn số lượng biểu thức trong builder không?

, các nạp chồng buildBlock tiêu chuẩn hỗ trợ tối đa 10 biểu thức. Khi vượt quá, hãy sử dụng các container lồng nhau (Group, VStack) để chia thành các khối con. Một builder tùy chỉnh có thể định nghĩa buildBlock variadic không giới hạn.

Tóm tắt

  • Result Builder — một thuộc tính Swift biến đổi chuỗi biểu thức thành một giá trị duy nhất thông qua phương thức tĩnh của builder
  • Trình biên dịch thay thế khối mã bằng các lời gọi buildBlock, buildEither, buildOptional, buildArray tùy theo cấu trúc điều khiển
  • @ViewBuilder — result builder tích hợp của SwiftUI cho phép viết mã khai báo hệ thống phân cấp view với hỗ trợ điều kiện và vòng lặp
  • Builder tùy chỉnh được sử dụng để xây dựng DSL: HTML, cấu hình, truy vấn — bất kỳ cấu trúc nào hưởng lợi từ cú pháp khai báo
  • Hạn chế: tối đa 10 biểu thức trong buildBlock, không thể khai báo biến, lỗi biên dịch khó hiểu khi kiểu không khớp
  • Swift 5.4+ — builder có thể được áp dụng cho tham số hàm, mở rộng trường hợp sử dụng ngoài phần thân view

Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay

IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.

Thảo luận dự án

Đọc thêm