[swift] 선택적 변수 인쇄

이 코드 줄로 시도하고 있습니다.

class Student {
    var name: String
    var age: Int?

    init(name: String) {
        self.name = name
    }

    func description() -> String {
        return age != nil ? "\(name) is \(age) years old." : "\(name) hides his age."
    }
}

var me = Student(name: "Daniel")
println(me.description())
me.age = 18
println(me.description())

위의 코드는 다음과 같이 생성합니다.

Daniel hides his age.
Daniel is Optional(18) years old.

내 질문은 왜 옵션 (18)이 거기에 있고 옵션을 제거하고 인쇄 만 할 수 있습니까?

Daniel is 18 years old.



답변

옵션이 실제로 무엇인지 이해해야합니다. 많은 Swift 초보자 var age: Int?는 나이가 가치가있을 수도 있고 없을 수도있는 Int 라고 생각 합니다. 그러나 나이는 Int를 가질 수도 있고 가지지 않을 수도있는 Optional이라는 것을 의미합니다.

description()함수 내 에서 Int를 인쇄하지 않고 대신 Optional을 인쇄합니다. Int를 인쇄하려면 Optional을 풀어야합니다. “옵션 바인딩”을 사용하여 옵션을 풀 수 있습니다.

if let a = age {
 // a is an Int
}

옵션에 개체가 있다고 확신하는 경우 “강제 래핑 해제”를 사용할 수 있습니다.

let a = age!

또는 귀하의 예에서 설명 함수에 nil에 대한 테스트가 이미 있으므로 다음과 같이 변경할 수 있습니다.

func description() -> String {
    return age != nil ? "\(name) is \(age!) years old." : "\(name) hides his age."
}


답변

선택 사항은 값이 유형에 해당하는지 Swift가 완전히 확신하지 못함을 의미합니다. 예를 들어 Int? 이는 Swift가 숫자가 Int인지 완전히 확신하지 못함을 의미합니다.

이를 제거하려면 세 가지 방법을 사용할 수 있습니다.

1) 유형이 확실하면 느낌표를 사용하여 다음과 같이 강제로 풀 수 있습니다.

// Here is an optional variable:

var age: Int?

// Here is how you would force unwrap it:

var unwrappedAge = age!

선택 사항을 강제로 풀고 nil과 같으면 다음 충돌 오류가 발생할 수 있습니다.

여기에 이미지 설명 입력

이것이 반드시 안전하지는 않으므로 유형과 값이 확실하지 않은 경우 충돌을 방지 할 수있는 방법은 다음과 같습니다.

방법 2와 3은이 문제를 방지합니다.

2) 암시 적으로 언 래핑 된 옵션

 if let unwrappedAge = age {

 // continue in here

 }

래핑되지 않은 유형은 이제 Int 가 아니라 Int입니까? .

3) 가드 진술

 guard let unwrappedAge = age else {
   // continue in here
 }

여기에서 계속해서 언 래핑 된 변수를 사용할 수 있습니다. 변수의 유형을 확신하는 경우에만 강제로 풀기 (! 사용)를 확인하십시오.

프로젝트에 행운을 빕니다!


답변

테스트 / 디버깅을 위해 항상 nil값 을 테스트 할 필요없이 선택 사항을 문자열로 출력하고 싶기 때문에 사용자 지정 연산자를 만들었습니다.

나는 다른 질문에서이 대답을 읽은 후에 일을 더욱 개선했습니다 .

fileprivate protocol _Optional {
    func unwrappedString() -> String
}

extension Optional: _Optional {
    fileprivate func unwrappedString() -> String {
        switch self {
        case .some(let wrapped as _Optional): return wrapped.unwrappedString()
        case .some(let wrapped): return String(describing: wrapped)
        case .none: return String(describing: self)
        }
    }
}

postfix operator ~? { }
public postfix func ~? <X> (x: X?) -> String {
    return x.unwrappedString
}

분명히 연산자 (및 그 속성)는 원하는대로 조정할 수 있거나 대신 함수로 만들 수 있습니다. 어쨌든 다음과 같은 간단한 코드를 작성할 수 있습니다.

var d: Double? = 12.34
print(d)     // Optional(12.34)
print(d~?)   // 12.34
d = nil
print(d~?)   // nil

다른 사람의 프로토콜 아이디어를 통합하면 옵션 체인을 사용할 때 종종 발생하는 중첩 된 옵션에서도 작동합니다. 예를 들면 :

let i: Int??? = 5
print(i)              // Optional(Optional(Optional(5)))
print("i: \(i~?)")    // i: 5


답변

최신 정보

간단히 me.age ?? "Unknown age!". 3.0.2에서 작동합니다.

이전 답변

강제 언 래핑없이 (무시 마하 시그널 / 크래시 없음)이를 수행하는 또 다른 좋은 방법은 다음과 같습니다.

(result["ip"] ?? "unavailable").description.

result["ip"] ?? "unavailable" 작업도 있어야하지만 그렇지 않습니다. 적어도 2.2에서는

물론 “사용할 수 없음”을 적합한 것으로 바꾸십시오 : “없음”, “찾을 수 없음”등


답변

age!대신 선택적 사용을 풀려면 age. 현재 당신은 nil. 그래서 Optional.


답변

신속하게 어떤 경우 에는 그럴 Optional수 있습니다 nil. a variable가 항상 어떤 값을 가질 것이라고 100 % 확신 하고 변수를 강제로 풀기 위해 niladd !를 반환하지 않을 것입니다.

다른 경우에는 값이 확실하지 않은 경우 if let블록 을 추가 하거나 guard값이 있는지 확인하십시오. 그렇지 않으면 충돌이 발생할 수 있습니다.

대한 if let블록 :

if let abc = any_variable {
 // do anything you want with 'abc' variable no need to force unwrap now.
}

대한 guard문 :

guard 조건이 충족되지 않으면 제어를 반환하는 조건부 구조입니다.

특정 값이 존재하지 않는 경우 를 반환 할 수 있으므로 많은 상황에서 guardover if letblock 을 사용하는 것을 선호 function합니다. 변수가 존재하기 위해 정수인 함수가있을 때와 같이 가드 문에서 확인할 수 있고 반환이 존재하지 않습니다. 즉;

guard let abc = any_variable else { return }

변수가 존재하면 가드 범위 밖의 함수에서 ‘abc’를 사용할 수 있습니다.


답변

age은 선택적 유형입니다. Optional<Int>따라서 nil과 비교하면 값이 있거나없는 경우 매번 false를 반환합니다. 값을 얻으려면 선택 사항을 풀어야합니다.

귀하의 예에서는 값이 포함되어 있는지 알지 못하므로 대신 사용할 수 있습니다.

if let myAge = age {
    // there is a value and it's currently undraped and is stored in a constant
}
else {
   // no value
}