programing

Swift: 0에 대한 옵션 테스트

telebox 2023. 4. 27. 22:09
반응형

Swift: 0에 대한 옵션 테스트

저는 Xcode 6 베타 4를 사용하고 있습니다.저는 선택사항을 적절하게 테스트하는 방법을 찾을 수 없는 이상한 상황을 겪고 있습니다.

xyz(선택 사항)가 있는 경우 테스트하는 올바른 방법:

if (xyz) // Do something

또는

if (xyz != nil) // Do something

문서에는 첫 번째 방법으로 하라고 되어 있지만, 때때로 두 번째 방법이 필요하고 컴파일러 오류를 생성하지 않지만, 다른 경우에는 두 번째 방법이 컴파일러 오류를 생성한다는 것을 발견했습니다.

저의 구체적인 예는 swift로 브리지된 GData XML 파서를 사용하는 것입니다.

let xml = GDataXMLDocument(
    XMLString: responseBody,
    options: 0,
    error: &xmlError);

if (xmlError != nil)

여기서, 만약 내가 했다면:

if xmlError

그것은 항상 진실로 돌아올 것입니다.하지만, 만약 내가 한다면,

if (xmlError != nil)

그런 다음 작동합니다(목표-C에서 작동하는 방식).

GData XML과 누락된 옵션을 처리하는 방식에 문제가 있습니까?

Xcode 베타 5에서는 더 이상 다음 작업을 수행할 수 없습니다.

var xyz : NSString?

if xyz {
  // Do something using `xyz`.
}

그러면 다음 오류가 발생합니다.

'BooleanType' 프로토콜을 준수하지 않습니다.의정서'

다음 양식 중 하나를 사용해야 합니다.

if xyz != nil {
   // Do something using `xyz`.
}

if let xy = xyz {
   // Do something using `xy`.
}

다른 답변에 추가하기, 다른 이름의 변수에 할당하는 대신if조건:

var a: Int? = 5

if let b = a {
   // do something
}

다음과 같이 동일한 변수 이름을 재사용할 수 있습니다.

var a: Int? = 5

if let a = a {
    // do something
}

이렇게 하면 작성된 변수 이름이 부족해지는 것을 방지할 수 있습니다.

이것은 Swift에서 지원되는 가변 쉐이딩을 활용합니다.

스위프트 3.0, 4.0

0에 대한 선택적 검사에는 크게 두 가지 방법이 있습니다.다음은 이들을 비교한 예입니다.

만약 있다면

if let0에 대한 선택 사항을 확인하는 가장 기본적인 방법입니다.다른 조건을 쉼표로 구분하여 이 nil 체크에 추가할 수 있습니다.다음 조건으로 이동하려면 변수가 0이 아니어야 합니다.코드에서 합니다.nil 체크필경우다음추조제건거을다합니가서에드코.

외에 만약에 외에면 약에.x if 폐쇄가 되고 0이 됩니다.x_val내부에서 사용할 수 있습니다.그렇지 않으면 다른 폐쇄가 트리거됩니다.

if let x_val = x, x_val > 5 {
    //x_val available on this scope
} else {

}

가드렛

guard let비슷한 일을 할 수 있습니다.그것의 주된 목적은 논리적으로 더 합리적인 것을 만드는 것입니다.변수가 0이 아닌지 확인하고, 그렇지 않으면 기능을 중지합니다. guard let도 있습니다.if let.

은 차는랩않은값이다같음범다것사입니가는용과 같은 할 수 입니다.guard let아래 댓글에 표시된 것처럼. 마지막으로 이 현재 점으로 .return,break,기타.

guard let x_val = x, x_val > 5 else {
    return
}
//x_val available on this scope

옵션을 사용하는 가장 직접적인 방법 중 하나는 다음과 같습니다.

가정하면xyz예를 들어, 선택적 유형입니다.Int?예를들면.

if let possXYZ = xyz {
    // do something with possXYZ (the unwrapped value of xyz)
} else {
    // do something now that we know xyz is .None
}

이 방법으로 당신은 둘 다 테스트할 수 있습니다.xyz에는 값이 포함되어 있으며, 포함되어 있으면 즉시 해당 값으로 작업합니다.

당신의 컴파일러 오류와 관련하여, 타입은UInt8는 선택 사항이 아니므로(not no '?') 로 변환할 수 없습니다.nil작업 중인 변수를 선택 사항으로 간주하기 전에 변수를 선택 사항으로 지정해야 합니다.

빠른 프로그래밍 가이드에서

If 문 및 강제 해제

if 문을 사용하여 옵션에 값이 포함되어 있는지 확인할 수 있습니다.옵션에 값이 있으면 true로 평가되고, 값이 전혀 없으면 false로 평가됩니다.

그래서 가장 좋은 방법은

// swift > 3
if xyz != nil {}

그리고 만약 당신이 그것을 사용한다면.xyzif 스테이트먼트에서.당신이 포장을 풀 수 있는 것보다.xyzin if 문을 상수 변수로 지정합니다.따라서 if 스테이트먼트의 모든 위치를 풀 필요는 없습니다.xyz사용됩니다.

if let yourConstant = xyz {
      //use youtConstant you do not need to unwrap `xyz`
}

이 규약은 다음과 같이 제안됩니다.apple그리고 개발자들이 뒤따를 것입니다.

그래도 선택 사항을 명시적으로 비교해야 합니다.nil또는 옵션 바인딩을 사용하여 추가적으로 값을 추출합니다(즉, 옵션이 부울 값으로 암시적으로 변환되지 않음). Swift 2는 여러 옵션 값으로 작업할 때 종말의 피라미드를 피하는 데 도움이 되는 문장을 추가했습니다.

다시 말해서, 이제 당신의 옵션은 명시적으로 다음을 확인하는 것을 포함합니다.nil:

if xyz != nil {
    // Do something with xyz
}

선택적 바인딩:

if let xyz = xyz {
    // Do something with xyz
    // (Note that we can reuse the same variable name)
}

그리고.guard문:

guard let xyz = xyz else {
    // Handle failure and then exit this code block
    // e.g. by calling return, break, continue, or throw
    return
}

// Do something with xyz, which is now guaranteed to be non-nil

일반적인 선택적 바인딩은 두 개 이상의 선택적 값이 있을 때 어떻게 들여쓰기를 더 크게 할 수 있는지 확인합니다.

if let abc = abc {
    if let xyz = xyz {
        // Do something with abc and xyz
    }        
}

다음을 사용하여 이 중첩을 피할 수 있습니다.guard문:

guard let abc = abc else {
    // Handle failure and then exit this code block
    return
}

guard let xyz = xyz else {
    // Handle failure and then exit this code block
    return
}

// Do something with abc and xyz

스위프트 5 프로토콜 확장

다음은 프로토콜 확장을 사용하여 선택적 nil 검사를 쉽게 인라인화할 수 있는 방법입니다.

import Foundation

public extension Optional {

    var isNil: Bool {

        guard case Optional.none = self else {
            return false
        }

        return true

    }

    var isSome: Bool {

        return !self.isNil

    }

}

사용.

var myValue: String?

if myValue.isNil {
    // do something
}

if myValue.isSome {
    // do something
}

구체적으로 다루지 않은 한 가지 옵션은 Swift의 무시된 값 구문을 사용하는 것입니다.

if let _ = xyz {
    // something that should only happen if xyz is not nil
}

확인해보니 이게 마음에 듭니다.nil스위프트와 같은 현대 언어에서는 어울리지 않는 느낌이 듭니다.어울리지 않게 느껴지는 이유는nil기본적으로 보초 값입니다.우리는 현대 프로그래밍에서 거의 모든 곳에서 보초병을 제거했습니다.nil그것도 가야 할 것 같아요.

에 에.if 때 할 수 .

func f(x: String?) -> String {
    return x == nil ? "empty" : "non-empty"
}

사용 이외의 또 다른 접근 방식if또는guard은 확장하는 입니다.Optional 포함:

extension Optional {

    func ifValue(_ valueHandler: (Wrapped) -> Void) {
        switch self {
        case .some(let wrapped): valueHandler(wrapped)
        default: break
        }
    }

}

ifValue옵션이 0이 아닐 때는 마감을 수신하고 인수로 값을 사용하여 이를 호출합니다.다음과 같은 방식으로 사용됩니다.

var helloString: String? = "Hello, World!"

helloString.ifValue {
    print($0) // prints "Hello, World!"
}

helloString = nil

helloString.ifValue {
    print($0) // This code never runs
}

당신은 아마도 사용해야 할 것입니다.if또는guard그러나 그것들은 스위프트 프로그래머들이 사용하는 가장 전통적인 (따라서 친숙한) 접근법이기 때문입니다.

선택적.

또한 사용할 수 있습니다.

nil-coalescing operator(a ?? b 선택 )의 을 해제합니다.a▁it가 포함되어 ,a값또는반환을 합니다.a 기값b한다면a이라nil식 a는 항상 선택적 유형입니다.그표은라는 b되어 있는 형식과 해야 합니다.a.

let value = optionalValue ?? defaultValue

한다면optionalValue이라nil으로 자으로값할다니합당에 합니다.defaultValue

이제 다음과 같은 일을 신속하게 할 수 있으며, 이를 통해 목표-c를 약간 되찾을 수 있습니다.if nil else

if textfieldDate.text?.isEmpty ?? true {

}

Swift 5.7 이후:

if let xyz {
    // Do something using `xyz` (`xyz` is not optional here) 
} else {
    // `xyz` was nil
}
var xyz : NSDictionary?

// case 1:
xyz = ["1":"one"]
// case 2: (empty dictionary)
xyz = NSDictionary() 
// case 3: do nothing

if xyz { NSLog("xyz is not nil.") }
else   { NSLog("xyz is nil.")     }

이 테스트는 모든 경우에 예상대로 작동했습니다.참고로, 브래킷은 필요 없습니다.().

만약 당신이 조건부를 가지고 있고 포장을 풀고 비교하고 싶다면, 다음과 같이 복합 부울식의 단락 평가를 이용하는 것은 어떻습니까?

if xyz != nil && xyz! == "some non-nil value" {

}

물론, 이것은 다른 제안된 게시물들처럼 읽을 수는 없지만, 다른 제안된 해결책들보다 다소 간결하고 작업을 수행합니다.

다른 사용자도 사전 작업을 찾고 선택사항(nil) 작업을 시도하는 경우.

 let example : [Int:Double?] = [2: 0.5]
 let test = example[0]

당신은 결국 더블 타입이 될 것입니다.

코드를 계속 진행하려면 병합을 사용하면 됩니다.

 let example : [Int:Double?] = [2: 0.5]
 let test = example[0] ?? nil

이제 더블만 있는 거예요?

이건 완전히 논리적이지만, 제가 잘못 검색한 거예요, 다른 사람에게 도움이 될 수도 있어요.

언급URL : https://stackoverflow.com/questions/25097727/swift-testing-optionals-for-nil

반응형