C API와의 상호 작용에 대한 Apple의 설명서에서 C NS_ENUM
스타일 열거를 Swift 열거로 가져 오는 방법을 설명합니다 . 이것은 의미가 있으며 Swift의 열거 형은 다음과 같이 쉽게 제공됩니다.enum
값 유형 자체 작성 방법을 쉽게 볼 수 있습니다.
아래에 NS_OPTIONS
표시된 C 스타일 옵션 에 대해 다음과 같이 말합니다 .
Swift는
NS_OPTIONS
매크로 로 표시된 옵션도 가져옵니다 . 옵션은 수입 열거에 유사하게 동작하는 반면, 옵션은 다음과 같은 몇 가지 비트 연산을 지원할 수&
,|
및~
. Objective-C에서 상수 0 (0
)으로 설정된 빈 옵션을 나타냅니다 . Swift에서는nil
옵션이 없음을 나타내는 데 사용 하십시오.
options
Swift에 값 유형 이없는 경우 C 스타일 옵션 변수를 작성하여 어떻게 작업 할 수 있습니까?
답변
스위프트 3.0
Swift 2.0과 거의 동일합니다. OptionSetType의 이름이 OptionSet으로 바뀌 었으며 열거 형은 규칙에 따라 소문자로 작성됩니다.
struct MyOptions : OptionSet {
let rawValue: Int
static let firstOption = MyOptions(rawValue: 1 << 0)
static let secondOption = MyOptions(rawValue: 1 << 1)
static let thirdOption = MyOptions(rawValue: 1 << 2)
}
none
옵션 을 제공하는 대신 Swift 3 권장 사항은 단순히 빈 배열 리터럴을 사용하는 것입니다.
let noOptions: MyOptions = []
다른 사용법 :
let singleOption = MyOptions.firstOption
let multipleOptions: MyOptions = [.firstOption, .secondOption]
if multipleOptions.contains(.secondOption) {
print("multipleOptions has SecondOption")
}
let allOptions = MyOptions(rawValue: 7)
if allOptions.contains(.thirdOption) {
print("allOptions has ThirdOption")
}
스위프트 2.0
Swift 2.0에서 프로토콜 확장은이를위한 보일러 플레이트의 대부분을 처리하며, 이제는이를 준수하는 구조체로 가져옵니다 OptionSetType
. ( RawOptionSetType
Swift 2 베타 2부터 사라졌습니다.) 선언이 훨씬 간단합니다.
struct MyOptions : OptionSetType {
let rawValue: Int
static let None = MyOptions(rawValue: 0)
static let FirstOption = MyOptions(rawValue: 1 << 0)
static let SecondOption = MyOptions(rawValue: 1 << 1)
static let ThirdOption = MyOptions(rawValue: 1 << 2)
}
이제 다음과 함께 세트 기반 시맨틱을 사용할 수 있습니다 MyOptions
.
let singleOption = MyOptions.FirstOption
let multipleOptions: MyOptions = [.FirstOption, .SecondOption]
if multipleOptions.contains(.SecondOption) {
print("multipleOptions has SecondOption")
}
let allOptions = MyOptions(rawValue: 7)
if allOptions.contains(.ThirdOption) {
print("allOptions has ThirdOption")
}
스위프트 1.2
(스위프트에 의해 수입 된 목표 – C 옵션을 보면 UIViewAutoresizing
예를 들어,), 우리는 옵션이로 선언 된 것을 볼 수 있습니다 struct
해당 프로토콜을 준수 RawOptionSetType
차례에 부합 함을 선언에서에 _RawOptionSetType
, Equatable
, RawRepresentable
, BitwiseOperationsType
,와 NilLiteralConvertible
. 우리는 다음과 같이 우리 자신을 만들 수 있습니다 :
struct MyOptions : RawOptionSetType {
typealias RawValue = UInt
private var value: UInt = 0
init(_ value: UInt) { self.value = value }
init(rawValue value: UInt) { self.value = value }
init(nilLiteral: ()) { self.value = 0 }
static var allZeros: MyOptions { return self(0) }
static func fromMask(raw: UInt) -> MyOptions { return self(raw) }
var rawValue: UInt { return self.value }
static var None: MyOptions { return self(0) }
static var FirstOption: MyOptions { return self(1 << 0) }
static var SecondOption: MyOptions { return self(1 << 1) }
static var ThirdOption: MyOptions { return self(1 << 2) }
}
이제 MyOptions
Apple 문서에 설명 된 것처럼 이 새로운 옵션 세트를 처리 할 수 있습니다. enum
유사한 구문을 사용할 수 있습니다 .
let opt1 = MyOptions.FirstOption
let opt2: MyOptions = .SecondOption
let opt3 = MyOptions(4)
또한 옵션이 작동 할 것으로 예상되는 것처럼 작동합니다.
let singleOption = MyOptions.FirstOption
let multipleOptions: MyOptions = singleOption | .SecondOption
if multipleOptions & .SecondOption != nil { // see note
println("multipleOptions has SecondOption")
}
let allOptions = MyOptions.fromMask(7) // aka .fromMask(0b111)
if allOptions & .ThirdOption != nil {
println("allOptions has ThirdOption")
}
찾기 / 바꾸기없이 Swift 옵션 세트를 생성 하는 생성기를 만들었습니다 .
최신 : Swift 1.1 베타 3 수정.
답변
Xcode 6.1 베타 2는 RawOptionSetType
프로토콜 을 일부 변경했습니다 (이 Airspeedvelocity 블로그 항목 및 Apple 릴리스 정보 참조). ).
Nate Cooks 예제를 기반으로 업데이트 된 솔루션이 있습니다. 다음과 같이 자신의 옵션 세트를 정의 할 수 있습니다.
struct MyOptions : RawOptionSetType, BooleanType {
private var value: UInt
init(_ rawValue: UInt) { self.value = rawValue }
// MARK: _RawOptionSetType
init(rawValue: UInt) { self.value = rawValue }
// MARK: NilLiteralConvertible
init(nilLiteral: ()) { self.value = 0}
// MARK: RawRepresentable
var rawValue: UInt { return self.value }
// MARK: BooleanType
var boolValue: Bool { return self.value != 0 }
// MARK: BitwiseOperationsType
static var allZeros: MyOptions { return self(0) }
// MARK: User defined bit values
static var None: MyOptions { return self(0) }
static var FirstOption: MyOptions { return self(1 << 0) }
static var SecondOption: MyOptions { return self(1 << 1) }
static var ThirdOption: MyOptions { return self(1 << 2) }
static var All: MyOptions { return self(0b111) }
}
그런 다음 변수를 정의하기 위해 다음과 같이 사용할 수 있습니다.
let opt1 = MyOptions.FirstOption
let opt2:MyOptions = .SecondOption
let opt3 = MyOptions(4)
비트를 테스트하려면 다음과 같이하십시오.
let singleOption = MyOptions.FirstOption
let multipleOptions: MyOptions = singleOption | .SecondOption
if multipleOptions & .SecondOption {
println("multipleOptions has SecondOption")
}
let allOptions = MyOptions.All
if allOptions & .ThirdOption {
println("allOptions has ThirdOption")
}
답변
설명서의 Swift 2.0 예제 :
struct PackagingOptions : OptionSetType {
let rawValue: Int
init(rawValue: Int) { self.rawValue = rawValue }
static let Box = PackagingOptions(rawValue: 1)
static let Carton = PackagingOptions(rawValue: 2)
static let Bag = PackagingOptions(rawValue: 4)
static let Satchel = PackagingOptions(rawValue: 8)
static let BoxOrBag: PackagingOptions = [Box, Bag]
static let BoxOrCartonOrBag: PackagingOptions = [Box, Carton, Bag]
}
답변
Swift 2 (현재 Xcode 7 베타의 일부로 베타)에서 NS_OPTIONS
스타일 유형을 새 OptionSetType
유형의 하위 유형으로 가져옵니다 . 새로운 프로토콜 확장 기능과 OptionSetType
표준 라이브러리에서 구현 된 방식 덕분에 OptionsSetType
가져온 동일한 함수와 메소드를 확장 하고 가져 오는 고유 한 유형을 선언 할 수 있습니다.NS_OPTIONS
스타일 유형 .
그러나 이러한 함수는 더 이상 비트 산술 연산자를 기반으로하지 않습니다. C에서 비 독점 부울 옵션 세트를 사용하려면 필드에서 마스킹 및 비트 비트가 필요합니다. 정말, 옵션 세트는 것입니다 세트 … 고유 항목의 모음. 따라서 배열 리터럴 구문에서 생성,와 같은 쿼리 ,으로 마스킹 등 OptionsSetType
의 SetAlgebraType
프로토콜 에서 모든 메소드를 가져 옵니다 .contains
intersection
답변
//Swift 2.0
//create
struct Direction : OptionSetType {
let rawValue: Int
static let None = Direction(rawValue: 0)
static let Top = Direction(rawValue: 1 << 0)
static let Bottom = Direction(rawValue: 1 << 1)
static let Left = Direction(rawValue: 1 << 2)
static let Right = Direction(rawValue: 1 << 3)
}
//declare
var direction: Direction = Direction.None
//using
direction.insert(Direction.Right)
//check
if direction.contains(.Right) {
//`enter code here`
}
답변
Objective-C와 상호 운용 할 필요가없고 Swift에서 비트 마스크 의 표면 의미 를 원한다면, 일반적인 Swift 열거 형으로이를 수행 할 수있는 BitwiseOptions라는 간단한 “라이브러리”를 작성했습니다.
enum Animal: BitwiseOptionsType {
case Chicken
case Cow
case Goat
static let allOptions = [.Chicken, .Cow, .Goat]
}
var animals = Animal.Chicken | Animal.Goat
animals ^= .Goat
if animals & .Chicken == .Chicken {
println("Chick-Fil-A!")
}
등등. 실제 비트는 여기에서 뒤집 히지 않습니다. 이들은 불투명 한 값에 대해 설정된 작업입니다. 여기서 요점을 찾을 수 있습니다 .
답변
Rickster가 이미 언급했듯이 Swift 2.0에서 OptionSetType 을 사용할 수 있습니다 . NS_OPTIONS 유형은 OptionSetType
프로토콜에 따라 가져 오며 옵션에 대한 설정 인터페이스를 제공합니다.
struct CoffeeManipulators : OptionSetType {
let rawValue: Int
static let Milk = CoffeeManipulators(rawValue: 1)
static let Sugar = CoffeeManipulators(rawValue: 2)
static let MilkAndSugar = [Milk, Sugar]
}
이 작업 방식을 제공합니다.
struct Coffee {
let manipulators:[CoffeeManipulators]
// You can now simply check if an option is used with contains
func hasMilk() -> Bool {
return manipulators.contains(.Milk)
}
func hasManipulators() -> Bool {
return manipulators.count != 0
}
}