논리 AND 연산자 &&와 함께 Swift if let 사용


93

if let선택적 nil을 확인한 다음 언 래핑 하기 위해 구문을 속기로 사용할 수 있다는 것을 알고 있습니다 .

그러나 논리 AND 연산자를 사용하여 다른 표현식과 결합하고 싶습니다 &&.

예를 들어, 여기에서는 선택적으로 연결하여 내 rootViewController를 tabBarController로 언 래핑하고 선택적으로 다운 캐스트합니다. 그러나 중첩 된 if 문을 사용하기보다 결합하고 싶습니다.

if let tabBarController = window!.rootViewController as? UITabBarController {
    if tabBarController.viewControllers.count > 0 {
        println("do stuff")
     }
 }

결합 기부 :

if let tabBarController = window!.rootViewController as? UITabBarController &&
    tabBarController.viewControllers.count > 0 {
        println("do stuff")
     }
}

위의 컴파일 오류 가 해결되지 않은 식별자 'tabBarController'사용

단순화 :

if let tabBarController = window!.rootViewController as? UITabBarController && true {
   println("do stuff")
}

이렇게하면 컴파일 오류가 발생 합니다. 조건부 바인딩의 Bound 값은 Optional 유형이어야합니다 . 다양한 구문 변형을 시도한 결과 각각 다른 컴파일러 오류가 발생합니다. 나는 아직 순서와 괄호의 조합을 찾지 못했습니다.

따라서 문제는 가능합니까? 그렇다면 올바른 구문은 무엇입니까?

내가 함께이 작업을 수행 할 수 있습니다 if진술 하지switch 문 또는 삼항 ?연산자.


질문에 오류 메시지를 제공하는 것은 항상 좋은 생각입니다.
zaph

이 실험을 좋아하는 사람들을위한 더 간단한 문var foo : Int? = 10; if let bar = foo { if bar == 10 { println("Great success!") }}
DarkDust

사용할 때 오류 메시지 if let bar = foo && bar == 10Use of unresolved identifier "bar"( bar물론 두 번째 )입니다.
DarkDust 2014-08-08

Objective C의 firstObject를 사용하여 위의 예제를 다음과 같이 단축 할 수있었습니다. if let navigationController = tabBarController.viewControllers.bridgeToObjectiveC (). firstObject as? UINavigationController {
Max MacLeod 2014 년

1
1. bridgeToObjectiveC베타 5에서 사라졌습니다 (일반 용도로 사용되지 않았을 가능성이 높음). 2. 어쨌든 firstSwift의 내장 Array유형 에 대한 메소드 가 있습니다 .
rickster 2014-08-09

답변:


143

Swift 1.2 부터는 이제 가능합니다 . 스위프트 1.2 엑스 코드 6.3 베타 릴리스 노트 상태 :

if let을 사용한보다 강력한 선택적 언 래핑 — if let 구조는 이제 여러 옵션을 한 번에 언 래핑 할 수있을뿐만 아니라 중간에 부울 조건을 포함 할 수 있습니다. 이를 통해 불필요한 중첩없이 조건부 제어 흐름을 표현할 수 있습니다.

위의 명령문을 사용하면 구문은 다음과 같습니다.

if let tabBarController = window!.rootViewController as? UITabBarController where tabBarController.viewControllers.count > 0 {
        println("do stuff")
}

이것은 where절을 사용합니다 .

또 다른 예는, 이번에는 캐스팅 AnyObjectInt옵션을 풀기, 그리고 풀어 옵션이 조건을 충족하는지 확인 :

if let w = width as? Int where w < 500
{
    println("success!")
}

현재 Swift 3를 사용하는 사람들을 위해 "where"는 쉼표로 대체되었습니다. 따라서 동등한 것은 다음과 같습니다.

if let w = width as? Int, w < 500
{
    println("success!")
}

2
이것은 선택된 답이되어야합니다.
Francis.Beauchamp

예, 이제 변경되었습니다. 그 당시 Bryan의 대답은 정확했습니다
Max MacLeod

58

에서 스위프트 3 최대 MacLeod 씨의 예는 다음과 같습니다

if let tabBarController = window!.rootViewController as? UITabBarController, tabBarController.viewControllers.count > 0 {
    println("do stuff")
}

where로 대체되었다,


10
그래서, &&를위한 것입니다 || ?
jeet.chanchawat

9
@ jeet.chanchawat 논리적 OR 은이 컨텍스트에서 의미가 없습니다. if let선택 사항이 성공적으로 풀리고 새 변수 이름에 할당 된 경우에만 진행할 수 있습니다. 당신이 말했다면 당신 OR <something else>은 쉽게 if let. 논리적 OR의 경우, 그냥 정상을 수행 if하고 본문 내부에서 첫 번째 개체가 해당 지점에서 여전히 선택 사항이라는 사실을 처리합니다 (래핑되지 않음).
jhabbott

37

Max의 대답은 정확하며이를 수행하는 한 가지 방법입니다. 다음과 같이 작성하면 다음 사항에 유의하십시오.

if let a = someOptional where someBool { }

someOptional표현 먼저 해결 될 것입니다. 실패하면 someBool표현식이 평가되지 않습니다 (예상대로 단락 평가).

이것을 다른 방법으로 작성하려면 다음과 같이 할 수 있습니다.

if someBool, let a = someOptional { }

이 경우 someBool먼저 평가되고 true로 평가되는 경우에만 someOptional식이 평가됩니다.


5

Swift 4 , 사용하겠습니다.

let i = navigationController?.viewControllers.index(of: self)
if let index = i, index > 0, let parent = navigationController?.viewControllers[index-1] {
    // access parent
}

4

불가능합니다.

에서 스위프트 문법

IF 문의 문법

if-statement → if -condition code-block else-clause­o

if 조건 → 표현식 | 선언

else 절 → else 코드 블록 | else if 문

if 문의 조건 값은 BooleanType 프로토콜을 따르는 유형을 가져야합니다. 조건은 선택적 바인딩에 설명 된대로 선택적 바인딩 선언 일 수도 있습니다.

if-condition은 표현식 또는 선언 이어야합니다 . 표현과 선언을 모두 가질 수는 없습니다.

let foo = bar은 선언이며을 준수하는 값으로 평가되지 않습니다 BooleanType. 상수 / 변수를 선언합니다 foo.

원래 솔루션은 충분하며 조건을 결합하는 것보다 훨씬 더 읽기 쉽습니다.


하지만 확실히 "if let"-유효한 Swift 구문-표현식과 선언 둘 다입니까?
Max MacLeod

@MaxMacLeod let foo = bar는 표현이 아닌 선언입니다. 당신은 할 수 없습니다let boolValue = (let foo = bar)
Bryan Chen

좋습니다.하지만 Swift 가이드 (11 페이지)를 인용하면 예는 다음과 같습니다. if let name = optionalName. optionalName은 선택 사항이 아닌 경우 true로 평가되는 표현식이어야합니다. 그러면 문의 두 번째 부분이 시작되어 래핑되지 않은 옵션이 이름에 할당됩니다. 따라서 질문은 "optionalName이 선택 사항이 아닙니다"가 표현식 인 경우 논리적 AND로 확장 할 수 있다는 것입니다. Btw 나는 그것이 할 수 없다는 점에서 아마도 당신이 옳다고 생각합니다.
Max MacLeod

-1

나는 당신의 원래 제안이 너무 나쁘지 않다고 생각합니다. (메시 어) 대안은 다음과 같습니다.

if ((window!.rootViewController as? UITabBarController)?.viewControllers.count ?? 0) > 0 {
    println("do stuff")
}

1
하지만 당신은 캐스트에 코드를 필요 tabBarController다시
브라이언 첸
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.