수색…


소개

"선택적 값은 값을 포함하거나 값이 없음을 나타내는 nil을 포함합니다."

발췌 : 애플 Inc. "스위프트 프로그래밍 언어 (Swift 3.1 Edition)."iBooks. https://itun.es/us/k5SW7.l

기본 옵션 사용 사례에는 상수 (let), 루프 내에서 옵션 (if-let) 사용, 메서드 내에서 선택적 값 (guard-let)을 안전하게 래핑 해제 및 스위치 루프의 일부로 포함 (case-let ), 합병 연산자 (??)를 사용하여 nil이면 기본값으로 설정됩니다.

통사론

  • var optionalName : optionalType? // 선택적 유형을 선언합니다. 기본값은 nil입니다.
  • var optionalName : optionalType? = value // 선택적 값을 선언합니다.
  • var optionalName : 옵션 유형! // 암시 적으로 래핑되지 않은 옵션을 선언한다.
  • 선택 과목! // 선택적으로 unwrap 강제 실행

비고

선택 사항에 대한 자세한 내용은 Swift 프로그래밍 언어를 참조하십시오.

선택의 유형

선택 항목은 래퍼 역할을하는 일반 열거 형입니다. 이 랩퍼는 변수가 두 가지 상태 중 하나를 가질 수있게합니다 : 사용자 정의 유형의 값 또는 값의 부재를 나타내는 nil .

이 기능은 Swift에서 특히 중요합니다. 언어의 명시된 디자인 목표 중 하나가 Apple의 프레임 워크와 잘 작동하기 때문입니다. 많은 (대부분) Apple 프레임 워크는 Objective-C 내 프로그래밍 패턴 및 API 디자인의 사용 용이성 및 중요성 때문에 nil 을 사용합니다.

Swift에서 변수가 nil 값을 가지려면 선택 변수 여야합니다. 선택 사항은 ! 또는 ? 변수 유형으로. 예를 들어 Int 선택적으로 만들려면 다음을 사용할 수 있습니다.

var numberOne: Int! = nil
var numberTwo: Int? = nil

? 옵션은 명시 적으로 래핑되지 않아야하며 액세스 할 때 변수에 값이 있는지 여부가 확실하지 않은 경우 사용해야합니다. 예를 들어 문자열을 Int 로 변환 할 때 결과는 선택적인 Int? 문자열이 유효한 숫자가 아닌 경우 nil이 반환되므로

let str1 = "42"
let num1: Int? = Int(str1) // 42

let str2 = "Hello, World!"
let num2: Int? = Int(str2) // nil

! 선택 사항은 자동으로 래핑되지 않으므로 액세스 할 때 변수에 값이 있음을 확신때만 사용해야합니다. 예를 들어, 글로벌 UIButton! viewDidLoad() 에서 초기화되는 변수

//myButton will not be accessed until viewDidLoad is called,
//so a ! optional can be used here
var myButton: UIButton!

override func viewDidLoad(){
    self.myButton = UIButton(frame: self.view.frame)
    self.myButton.backgroundColor = UIColor.redColor()
    self.view.addSubview(self.myButton)
}

선택 사항 언 래핑

Optional의 값에 액세스하려면 래핑을 해제해야합니다.

선택적 바인딩을 사용하여 선택적으로 조건부 랩핑 을 해제 하고 ! 운영자.

조건부로 랩핑을 해제하면 "이 변수에 값이 있습니까?"라고 묻습니다. force unwrapping은 "This variable is a value!"라고 말합니다.

nil 인 변수의 언랩을 강요 하면 옵션 예외 및 충돌 을 언 래핑하는 동안 프로그램에서 예기치 않게 발견 된 nil을 던져 버리므로 사용하는 경우 신중하게 고려해야합니다 ! 적절하다.

var text: String? = nil
var unwrapped: String = text! //crashes with "unexpectedly found nil while unwrapping an Optional value"

안전한 언 래핑을 위해 if-let 문을 사용할 수 있습니다. if-let 문은 래핑 된 값이 nil 이면 예외 또는 충돌을 발생시키지 않습니다.

var number: Int?
if let unwrappedNumber = number {       // Has `number` been assigned a value?
    print("number: \(unwrappedNumber)") // Will not enter this line
} else {
    print("number was not assigned a value")
}

또는 보호 진술 :

var number: Int?
guard let unwrappedNumber = number else {
    return
}
print("number: \(unwrappedNumber)")

unwrappedNumber 변수의 범위는 if-let 문 내부와 guard 블록 외부에 있음에 유의하십시오.

많은 선택 사항의 래핑을 연결할 수 있습니다. 이것은 코드가 올바르게 작동하려면 변수가 더 많이 필요한 경우에 주로 유용합니다.

var firstName:String?
var lastName:String?

if let fn = firstName, let ln = lastName {
    print("\(fn) + \(ln)")//pay attention that the condition will be true only if both optionals are not nil.
}

테스트를 성공적으로 통과하려면 모든 변수의 래핑을 해제해야합니다. 그렇지 않으면 래핑되지 않은 변수와 그렇지 않은 변수를 결정할 방법이 없습니다.

선택 사항을 래핑 한 후 즉시 조건문을 연결할 수 있습니다. 이것은 중첩 된 if - else 문을 의미하지 않습니다!

var firstName:String? = "Bob"
var myBool:Bool? = false

if let fn = firstName, fn == "Bob", let bool = myBool, !bool {
    print("firstName is bob and myBool was false!")
}

Nil 통합 연산자

nil coalescing 연산자 를 사용하여 값이 nil이 아닌 경우 값의 랩핑을 해제 할 수 있습니다. 그렇지 않으면 다른 값을 제공하십시오.

func fallbackIfNil(str: String?) -> String {
    return str ?? "Fallback String"
}
print(fallbackIfNil("Hi")) // Prints "Hi"
print(fallbackIfNil(nil)) // Prints "Fallback String"

이 연산자는 단락 될 수 있습니다. 즉, 왼쪽 피연산자가 nil이 아닌 경우 오른쪽 피연산자는 평가되지 않습니다.

func someExpensiveComputation() -> String { ... }

var foo : String? = "a string"
let str = foo ?? someExpensiveComputation()

이 예제에서 foo 는 non-nil이므로 someExpensiveComputation() 은 호출되지 않습니다.

여러 개의 nil 병합 명령문을 함께 연결할 수도 있습니다.

var foo : String?
var bar : String?

let baz = foo ?? bar ?? "fallback string"

이 예제에서 bazbaz 이 아닌 경우 foo 의 래핑되지 않은 값을 할당받습니다. 그렇지 않으면 nil이 아닌 경우 unwrapped bar 값이 할당됩니다. 그렇지 않으면 폴백 값이 할당됩니다.

선택적 체인

선택적 체인 을 사용하여 메서드 를 호출하거나 속성 또는 아래 첨자 에 선택적으로 액세스 할 수 있습니다 . 이것은 ? 주어진 선택적 변수와 주어진 멤버 (메서드, 속성 또는 아래 첨자) 사이.

struct Foo {
    func doSomething() {
        print("Hello World!")
    }
}

var foo : Foo? = Foo()

foo?.doSomething() // prints "Hello World!" as foo is non-nil

foo 에 값이 포함되어 있으면 doSomething() 이 호출됩니다. foonil 이면 코드가 자동으로 실패하고 실행을 계속합니다.

var foo : Foo? = nil

foo?.doSomething() // will not be called as foo is nil

(이것은 Objective-C에서 nil 에 메시지를 보내는 것과 비슷한 동작입니다)

Optional Chaining이 그렇게 명명 된 이유는 '선택성'이 호출 / 액세스 회원을 통해 전파되기 때문입니다. 이것이 의미하는 바는 옵션 체인과 함께 사용 된 모든 멤버의 반환 값은 옵션으로 입력되었는지 여부에 관계없이 선택 사항입니다.

struct Foo {
    var bar : Int
    func doSomething() { ... }
}

let foo : Foo? = Foo(bar: 5)
print(foo?.bar) // Optional(5)

여기 foo?.barInt? 반환 Int? bar 는 옵션이 아니지만 foo 자체는 선택 사항입니다.

옵션 성이 전파 될 때 Void? 를 반환하는 메서드는 Void 를 반환 Void? 선택적 체인과 함께 호출 될 때. 이 메소드가 호출되었는지 여부를 판별하는 데 유용 할 수 있습니다 (따라서 선택적 값이있는 경우).

let foo : Foo? = Foo()

if foo?.doSomething() != nil {
    print("foo is non-nil, and doSomething() was called")
} else {
    print("foo is nil, therefore doSomething() wasn't called")
}

여기에 Void? 비교하고 Void? 메서드가 호출되었는지 여부를 결정하기 위해 nil 을 반환한다 (따라서 foo 가 nil이 아닌지 여부).

개요 - 왜 선택적입니까?

종종 프로그래밍 할 때 값이있는 변수와 그렇지 않은 변수를 구분해야합니다. C 포인터와 같은 참조 유형의 경우 null 과 같은 특수 값을 사용하여 변수에 값이 없음을 나타낼 수 있습니다. 정수와 같은 intrinsic 유형의 경우 더 어렵습니다. 지정된 값 (예 : -1)을 사용할 수 있지만이 값의 해석에 의존합니다. 또한 정상적인 사용에서 "특별한"가치를 제거합니다.

이 문제를 해결하기 위해 Swift는 모든 변수를 선택적으로 선언 할 수 있습니다. 이것은? 또는! 유형 뒤에 ( 옵션 유형 참조)

예를 들어,

var possiblyInt: Int?

정수 값을 포함하거나 포함하지 않을 수있는 변수를 선언합니다.

특수 값 nil 은 현재이 변수에 값이 지정되지 않았 음을 나타냅니다.

possiblyInt = 5      // PossiblyInt is now 5
possiblyInt = nil    // PossiblyInt is now unassigned

nil 을 사용하여 할당 된 값을 테스트 할 수도 있습니다.

if possiblyInt != nil {
    print("possiblyInt has the value \(possiblyInt!)")
}

! 의 사용에 유의하십시오 ! 인쇄 문에서 선택적 값을 언랩 합니다.

optionals의 일반적인 사용의 예로서, 숫자가 들어있는 문자열에서 정수를 반환하는 함수를 생각해보십시오. 문자열에 숫자가 아닌 문자가 포함되거나 비어있을 수도 있습니다.

간단한 Int 를 반환하는 함수가 어떻게 실패를 나타낼 수 있습니까? 특정 값을 반환하면 문자열에서 해당 값을 파싱 할 수 없으므로 그렇게 할 수 없습니다.

var someInt
someInt = parseInt("not an integer") // How would this function indicate failure?

그러나 Swift에서는이 함수가 선택적 Int를 반환 할 수 있습니다. 그런 다음 실패는 nil 리턴 값으로 표시됩니다.

var someInt?
someInt = parseInt("not an integer")  // This function returns nil if parsing fails
if someInt == nil {
    print("That isn't a valid integer")
}


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow