이 코드 줄로 시도하고 있습니다.
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 % 확신 하고 변수를 강제로 풀기 위해 nil
add !
를 반환하지 않을 것입니다.
다른 경우에는 값이 확실하지 않은 경우 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
조건이 충족되지 않으면 제어를 반환하는 조건부 구조입니다.
특정 값이 존재하지 않는 경우 를 반환 할 수 있으므로 많은 상황에서 guard
over if let
block 을 사용하는 것을 선호 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
}