Swift IF LET는 어떻게 평가 되나요?


90

이 코드는 Swift 사이트와 여기의 다양한 게시물에서 보았고 기본 사항을 파악하려고합니다. 이 라인은 어떻게 평가됩니까?

if let name = optionalName {

나는 그것이 name == 선택적인 이름이 아니기 때문에 혼란 스럽습니다. 그것은 값을 할당하고 있습니다. 그래서 그것이 어떻게 사실을보고하고 당신이 john appleseed를 nil로 바꿀 때 그것이 여전히 동일 할 것이기 때문에 왜 그것이 사실이 아닌가?

var optionalName: String? = "John Appleseed"
var greeting = "Hello!"
if let name = optionalName {
    greeting = "Hello, \(name)"
}

10
Swift 문서에서 "optional binding"을 찾아보십시오 ...
Martin R

3
A는에서 선택적 항목 바라 보았다 자세한 dev.iachieved.it/iachievedit/?p=314 1, if let구문 옵션 바인딩으로 알려져있다.
Joe

답변:


105

본질적으로이 줄은 "새 변수를 name의 비 선택적 버전과 동일 하게 할 수 있다면 optionalName다음을 수행하십시오"라고 말합니다. Martin이 지적했듯이 이것을 Optional Binding 이라고 합니다.

유일한 목적은 선택적 변수에 실제 값이 포함되어 있는지 테스트하고 선택적이 아닌 형식을 임시 변수에 바인딩하는 것입니다. 이것은 옵션을 "언 래핑"하거나 다른 말로 옵션에 포함 된 값에 액세스하는 안전한 방법입니다. 어떤 종류의 평등도 테스트하는 것이 아닙니다. 선택 사항 내에 값이 존재하는지 테스트하는 것입니다.


2
나는 그것을 읽을 때 그것을 읽을 것입니다 .I는 빠른 인트로의 시작 부분에 있으며 설명하지 않습니다. 설명이 완벽합니다. 감사합니다.
DeadZero 2014 년

1
옵션 변수에 다음과 같은 값이 있는지 확인하기 위해 "if let"대신 "! ="를 사용하면 안됩니다.-if optionalName! = nil {greeting = "Hello, (name)"}
Nuibb

4
@Nuibb를 사용할 때 if let값을 선택적 변수가 아닌 변수 ( name이 예에서)에 바인딩 하기 때문 입니다. 이제라는 변수가 없기 때문에 예제가 컴파일되지 않습니다 name. 당신이 당신의 예를 변경 한 경우 사용하는 optionalName이 같은 인쇄 것이다 Hello, Optional("John Appleseed"). nil에 대해 확인한 후 강제 언 래핑을 사용할 수 Hello, \(optionalName!)있지만 확인하지 않고 코드 섹션을 어딘가로 이동하면 오류가 발생하기 쉽습니다.
drewag

30

선택 사항은 설정되거나 설정되지 않습니다 (nil 또는 nil이 아님) ... 중요한 결정을 내릴 수 있습니다. "두 가지 상태 모두에서 올바르게 작동 할 수 있도록 코드를 어떻게 작성해야합니까?" 우리 가 선택 사항 을 푸는 방식이 우리 를 위해 결정하는 것입니다.

설정되지 않은 선택 사항에 대응하는 데 사용할 수있는 몇 가지 방법이 있습니다.

  • 크래시!
  • 값을 기본값으로 설정합니다 (설정되지 않은 경우).
  • 정상적으로 실패합니다. 즉, 아무 작업도하지 않고 값이 설정된 경우 에도 할당합니다.
  • 우아하게 실패합니다. 즉, 아무 것도하지 않지만 값이 설정되어 있으면 무언가를 수행합니다 (단일 할당 이상입니다).

다음은 4 가지 접근 방식입니다.


값이없는 경우 강제 언 래핑 을 사용 하면 충돌이 발생 합니다. 이 값을 갖는 것이 영화 제목과 같이 매우 중요한 경우이 작업을 수행 할 수 있습니다 (모든 영화에는 이름이 있어야 함). 강제 언 래핑에 사용됩니다.!

movieTitle = movie.title!

nil 병합을 사용 하는 것은 더 많은 제어 를 제공하는 또 다른 방법입니다 . 즉, 값이 설정되지 않은 경우 충돌이 발생하지 않으며 설정되지 않은 경우 '아무것도 설정하지 않음'을 의미합니다. 예를 들어 이름이 설정되지 않은 경우 영화의 이름을 untitled_movie로 기본 / 설정 합니다 . ??nil 병합에 사용됩니다.

var movieTitle = movie.title ?? "untitled_Movie"

사용 옵션 체인을 아무것도하지 않습니다하는 경우, 당신은 가치가 없으며, 값을 설정합니다 경우 이 값을 가지고있다. 값을 설정 하는 것이 중요 하지 않은 경우 ( 예 : 배우의 에이전트 이름)에 대해이 작업을 수행합니다 . ?선택적 연결에 사용됩니다.

let agent = movie.leadActor?.agent //would not crash if you don't have a lead actor (optional chaining)
let agent = movie.leadActor!.agent //would crash if you don't have a lead Actor (forced wrapping)  

사용 if-let(또는 guard두 가지 유형의있는 바인딩 옵션 )하는 것은 당신에게 줄 것이다 더 제어 값이 설정되어 있지 않은 경우,이 충돌하지 않습니다. 값이 설정되면 무언가를 할 수 있습니다. 설정되지 않은 경우 else문을 추가 할 수 있습니다 .

if let supportingActor = movie.supportingActor{
print(" The supporting actor is \(supportingActor)}

강제 언 래핑이 다소 권장되지 않으므로 가장 일반적으로 사용되는 언 래핑 방법입니다. 권장되지 않는 이유에 대한 자세한 내용은 여기를 참조 하십시오 . 사이 좋은 비교의 경우 guardif-let참조guard vs. if-let


참고 :

선택적 바인딩과 선택적 체인은 일반적으로 함께 사용됩니다.

if let agent = movie.leadActor?.agent {
ContactInfo = agent.phoneNumber
} // if-let is the optional *binding* part, the movie dot leadActor dot is the optional *chaining*
 

movieTitle이 문자열 이외의 어떤 것도 될 수없고 모든 문자열이 movieTitle에 유효한 상황에서 강제 언 래핑이 권장되지 않는 이유는 무엇입니까? (그리고 나는 "무제 영화"를 원하지 않는다 ""를 원한다) 강제 풀기는이 상황에 대한 유일한 올바른 방법입니다. "강제 풀림은 다소 권장되지 않습니다."라는 부분을 제거 할 수 있다면 좋을 것입니다. 이는 잘못된 정보입니다. .
Andy

네트워크 호출을하고 서버 팀의 일부 개발자가 잘못된 결정을 내렸고 영화 제목을 보내는 것을 잊었다 고 가정합니다. 프로덕션에서 앱이 충돌하도록 하시겠습니까? 아니면 그냥 알 수없는 제목을 쓰시겠습니까? 사실 IMDb의 일부 영화에는 제목이 없습니다. :). 또한 force unwrap은 로깅이나 어설 션을 수행하지 않았 음을 의미합니다. 그 나쁜. 근본 원인이 무엇인지 알 수 없기 때문입니다.
Honey

그것은 짚맨 논쟁입니다. 나는 "항상 강제 풀기 사용"이라고 말한 적이 없습니다. 예제에서 강제 언 래핑을 사용해서는 안된다고해서 모든 예제에서 강제 언 래핑이 권장되지 않는 것은 아닙니다. 나는 당신이 제시 한 네 가지 중에서 강제 언 래핑이 유일한 해결책 인 시나리오를 제공했습니다. 이전 의견에 명시된 시나리오에 대한 더 나은 솔루션을 제공 할 수 있습니까? 그렇지 않은 경우 문맥을 고려하지 않고 다소 낙담하지 않기 때문에 "강제 포장 해제는 다소 권장되지 않음"에 대한 의견을 수정하는 것이 좋습니다.
Andy

당신이 "뭔가를 불이행하는 경우"다음은 더 이상 선택 사항 없습니다

예를 들어 ""값은 스토리 보드에서 생성 된 UILabel 인스턴스의 text 속성에서 나옵니다. 동적으로 생성하면 nil이 될 수 있기 때문에 선택 사항이지만 여기에서는 동적으로 생성하지 않으므로 항상 문자열 값을 포함합니다. . 이 경우 강제 언 래핑을 사용하지 않겠습니까? 대신 if-let으로 래핑을 풀고 기본값 ""과 동일한 값을 제공 하시겠습니까? 당신은 할 수 있지만 그것은 무의미하고 불필요하며 장황합니다. 오류가 발생하더라도 항상 사전을 반환하는 HTTP 라이브러리를 사용하고 있다면 어떨까요? 상황에 따라 다릅니다.
Andy

4

if 구문은 두 가지 조건을 허용합니다. 두 번째, 선택적 바인딩은 부울이 아닙니다. 다음과 같이 작성할 수 있으므로 혼란 스럽습니다.

if let name = optionalName {

하지만

if (let name = optionalName) {

Apple 문서 (Swift 참조) :

조건 의 값은 유형 Bool이거나에 브리지 된 유형이어야합니다 Bool. 조건은 Optional Binding에 설명 된대로 선택적 바인딩 선언 일 수도 있습니다 .


3

if 오류가 발생하는 것 외에는 부울 표현식 만 사용하므로이 코드 스 니펫은

if let name = optionalName {

}else{

}

optionalName이 nil이면 조건은 false이고 else 문이 실행됩니다. 그러나 optionalName에 어떤 값이있는 경우 선택적 값은 이름과 같은 상수 변수에 래핑 해제 / 할당됩니다.


1

약한 참조, 선택적 유형 으로 작업 할 때마다 코드를 안전하게 보호하고 충돌을 피 하려면 사용 하는 것이 더 좋습니다 . 예제는 다음과 같습니다.

var middleName :String? = "some thing"
if let isExistsMiddleName = middleName {
// do some thing here
} else {
// no middle name
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.