В Swift эти битовые поля выражаются в виде наборов опций, которые являются типами, которые соответствуют протоколу OptionSet
. Вот пример для вашего варианта использования:
struct Veggies: OptionSet {
let rawValue: UInt32
static let lettuce = Veggies(rawValue: 1 << 0)
static let cucumber = Veggies(rawValue: 1 << 1)
static let tomato = Veggies(rawValue: 1 << 2)
static let sweetcorn = Veggies(rawValue: 1 << 3)
static let onion = Veggies(rawValue: 1 << 4)
}
let someVeggies: Veggies = [.lettuce, .tomato]
print(someVeggies) // => Veggies(rawValue: 5)
print(Veggies.onion.rawValue) // => 16
Наборы параметров лучше, чем просто использование их необработанных значений, по двум причинам:
1) Они стандартизуют названия дел и предоставляют согласованный и простой способ взаимодействия с этими значениями.
2) OptionSet
происходит от протокола SetAlgebra
и предоставляет реализации по умолчанию для многих полезных методов, таких как union
, intersection
, subtract
, contains
и т. Д.
Однако я бы предостерег от этой схемы. Наборы опций полезны только тогда, когда есть действительно небольшое количество флагов (менее 64), которые нельзя предвидеть расширением. Они действительно просты, не могут хранить какую-либо полезную нагрузку, кроме «x существует или нет», и они в первую очередь предназначены для случаев использования, которые имеют очень высокую чувствительность к производительности и использованию памяти, что в наши дни происходит очень редко. Я бы рекомендовал вместо этого использовать обычные объекты (класс Veggie, хранение имени и любые другие соответствующие данные).