Swift zniechęca "niebezpieczne" wzorce programowania, takie jak union
, jednak istnieje obejście. To trochę brzydki, ale tu idzie (używając 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)
}
}
}
Teraz szybkie sprawdzenie sizeof(VariantA)
pokaże cała struktura nadal trwa tylko osiem bajtów (co jest jednym 64-bitowa liczba całkowita). Jeśli teraz stworzymy instancję taką jak ta var a = VariantA(oneField: 1234567890987654321)
, możemy zapytać komponenty takie jak ten a.oneField
, które zwrócą początkową wartość 1,234,567,890,987,654,321, a także a.variantB.memory.firstField
zwróci 2,976,652,465, a a.variantB.memory.secondField
zwróci 287,445,236.
Możemy zmienić jeden z komponentów jak ten a.variantB.memory.firstField++
a następnie zauważyć, że zmienia oryginalną wartość a.oneField
do 1,234,567,890,987,654,32 , jak oczekiwano.
Brzydkie części to dla mnie słowa "niebezpieczny", "wskaźnik" i .memory.
, a także ta pomocnicza funkcja addressOf
, która jest dostępna tylko po to, aby przezwyciężyć błąd kompilatora w Xcode 7.2!
Być może praca ze strukturami niższego poziomu, które wymagają takiej manipulacji na poziomie bajtowym, nie powinna odbywać się w języku wysokiego poziomu, jak na przykład Swift. Czy rozważałeś napisanie tej części swojego projektu w pliku .c? Dzięki odpowiedniemu nagłówkowi pomostowemu możesz nadal wykonywać większość projektu w Swift.
Nie ma bezpośredniego wsparcia dla związków w Swift, ale można użyć wyliczenia, aby spełnić swoje wymagania. – Amit89
Związki są disfavoured przez prawie każdego standardu kodowania C i C++ znanego człowiekowi, ponieważ są one tak często używane do pisania nieprzenośny kod. Jeśli masz wybór w tej sprawie, nigdy nie używaj "unii" w C, a we wszystkich przypadkach rozpakuj dane zawarte w operacjach bitowych. – marko
@ marko, musiałbym nie zgodzić się z twoim założeniem. Na przykład podczas odbierania wiadomości, w której wiadomość może mieć jeden z kilku różnych formatów, prawie zawsze jest ona implementowana jako zjednoczenie tych formatów, zazwyczaj tam, gdzie pierwsze, nie nagłówkowe pole wskazuje, który typ wiadomości zawiera się w pozostałej części. wiadomość, gdzie resztę wiadomości definiuje się jako połączenie wszystkich typów wiadomości. – user3629249