Swift không khuyến khích các mẫu lập trình "không an toàn" như union
, tuy nhiên, có một giải pháp thay thế. Đó là một chút xấu xí, nhưng ở đây đi (sử dụng Xcode 7.2) ...
struct VariantA {
var oneField: Int // 8 bytes
struct VariantB {
var firstField: UInt32 // first 4 bytes
var secondField: UInt32 // second 4 bytes
}
var variantB: UnsafeMutablePointer<VariantB> {
mutating get {
func addressOf<U>(something:UnsafePointer<U>)
-> UnsafeMutablePointer<VariantB> {
return UnsafeMutablePointer<VariantB>(something)
}
return addressOf(&oneField)
}
}
}
Bây giờ một kiểm tra nhanh của sizeof(VariantA)
sẽ hiển thị toàn bộ cấu trúc vẫn chiếm chỉ tám byte (đó là một trong 64-bit số nguyên). Nếu bây giờ chúng ta tạo một thể hiện như thế này var a = VariantA(oneField: 1234567890987654321)
thì chúng ta có thể truy vấn các thành phần như thế này a.oneField
sẽ trả về giá trị ban đầu 1,234,567,890,987,654,321 và cũng a.variantB.memory.firstField
sẽ trả về 2,976,652,465 và a.variantB.memory.secondField
sẽ trả về 287,445,236.
Chúng ta có thể thay đổi một trong các thành phần như a.variantB.memory.firstField++
này và sau đó nhận xét rằng điều này thay đổi giá trị ban đầu của a.oneField
để 1,234,567,890,987,654,32 như mong đợi.
Các phần xấu cho tôi là sự xuất hiện của các từ "không an toàn", "con trỏ" và .memory.
cũng như chức năng trợ giúp addressOf
chỉ để khắc phục lỗi trình biên dịch trong Xcode 7.2!
Có lẽ làm việc với các cấu trúc cấp thấp hơn yêu cầu thao tác mức byte như thế này không nên được thực hiện bằng ngôn ngữ cấp cao như Swift. Bạn đã cân nhắc viết phần này của dự án của mình trong một tệp .c? Với tiêu đề cầu nối phù hợp, bạn vẫn có thể thực hiện phần lớn dự án của mình trong Swift.
Nguồn
2015-12-29 16:20:04
Không có hỗ trợ trực tiếp của các công đoàn trong Swift, nhưng bạn có thể sử dụng liệt kê để hoàn thành yêu cầu của mình. – Amit89
Các công đoàn bị phân biệt bởi mọi tiêu chuẩn mã hóa C và C++ đều biết đến con người vì chúng thường được sử dụng để viết mã không di động. Nếu bạn có một sự lựa chọn trong vấn đề, không bao giờ sử dụng một 'union' trong C, và trong mọi trường hợp, giải nén bất kỳ dữ liệu nào được chứa bên trong với các toán tử bit-wise. – marko
@marko, tôi sẽ không đồng ý với tiền đề của bạn. Ví dụ, khi nhận được một tin nhắn, trong đó thông điệp có thể có một vài định dạng khác nhau, nó hầu như luôn được thực hiện như một sự kết hợp của các định dạng đó, thường là trường đầu tiên, không tiêu đề, cho biết loại thông điệp nào được chứa trong phần còn lại của tin nhắn, nơi phần còn lại của tin nhắn được định nghĩa là liên minh của tất cả các loại tin nhắn. – user3629249