[swift2] 스위프트 가드 키워드

Swift 2는 guard다양한 데이터를 준비 할 수 있도록 키워드를 도입했습니다 . 이 웹 사이트 에서 예제는 submitTapped 함수를 보여줍니다.

func submitTapped() {
    guard username.text.characters.count > 0 else {
        return
    }

    print("All good")
}

조건을 guard사용하여 구식 방식으로 사용하는 것과 다른 것이 있는지 궁금합니다 if. 간단한 확인으로 얻을 수없는 이점이 있습니까?



답변

이 기사를 읽으 면서 Guard를 사용하면 큰 이점을 발견 했습니다

여기에서 guard의 사용을 예제와 비교할 수 있습니다 :

이것은 가드가없는 부분입니다.

func fooBinding(x: Int?) {
    if let x = x where x > 0 {
        // Do stuff with x
        x.description
    }

    // Value requirements not met, do something
}
  1. 여기 모든 조건 내에서 원하는 코드를 넣습니다.

    당신은 즉시 이것에 대한 문제를 볼 수는 없지만, 당신이 진술을 실행하기 전에 충족시켜야 할 수많은 조건에 중첩되어 있다면 어떻게 혼란 스러울 수 있는지 상상할 수 있습니다.

이를 정리하는 방법은 먼저 각 점검을 수행하고, 충족되지 않으면 종료하는 것입니다. 이것은 어떤 조건이이 기능을 종료하게되는지 쉽게 이해할 수있게합니다.

그러나 이제 가드를 사용할 수 있으며 일부 문제를 해결할 수 있음을 알 수 있습니다.

func fooGuard(x: Int?) {
    guard let x = x where x > 0 else {
        // Value requirements not met, do something
        return
    }

    // Do stuff with x
    x.description
}
  1. 원하지 않는 상태가 아닌 원하는 상태를 확인합니다. 이것은 다시 assert와 유사합니다. 조건이 충족되지 않으면 guard의 else 문이 실행되어 기능에서 벗어날 수 있습니다.
  2. 조건이 통과되면 여기에서 선택적 변수가 보호문이 호출 된 범위 내에서 자동으로 랩핑 해제됩니다 (이 경우 fooGuard (_ 🙂 함수).
  3. 불량 사례를 조기에 확인하여 기능을보다 읽기 쉽고 유지 보수하기 쉽게 만듭니다.

이 같은 패턴은 선택 사항이 아닌 값에도 적용됩니다.

func fooNonOptionalGood(x: Int) {
    guard x > 0 else {
        // Value requirements not met, do something
        return
    }

    // Do stuff with x
}

func fooNonOptionalBad(x: Int) {
    if x <= 0 {
        // Value requirements not met, do something
        return
    }

    // Do stuff with x
}

여전히 궁금한 점이 있으면 전체 기사 : Swift guard statement를 읽으십시오 .

마무리

마지막으로, 읽고 테스트 한 결과 가드를 사용하여 옵션을 풀면

그 래핑되지 않은 값은 나머지 코드 블록에서 사용할 수 있도록 유지됩니다.

.

guard let unwrappedName = userName else {
    return
}

print("Your username is \(unwrappedName)")

래핑되지 않은 값은 if 블록 안에서만 사용할 수 있습니다.

if let unwrappedName = userName {
    print("Your username is \(unwrappedName)")
} else {
    return
}

// this won't work – unwrappedName doesn't exist here!
print("Your username is \(unwrappedName)")


답변

달리 if, guard그 블록에 외부로부터 액세스 할 수있는 변수를 생성한다. Optionals를 많이 풀면 유용합니다 .


답변

실제로 두 가지 큰 이점이 guard있습니다. 다른 사람들이 언급했듯이, 하나는 운명의 피라미드를 피하고 if let있습니다. 서로의 내부에 중첩 된 많은 성가신 말들이 점점 더 오른쪽으로 이동합니다.

다른 장점은 구현하려는 논리가 ” if not let“보다 ” if let { } else” 보다 많다는 것 입니다.

예를 들면 다음과 같습니다. 구현하고 싶다고 가정 해 봅시다 . 실행 간 축소를 제공하는 위치 와 그 accumulate사이의 교차점 입니다. 여기에 있습니다 :mapreduceguard

extension Sliceable where SubSlice.Generator.Element == Generator.Element {

    func accumulate(combine: (Generator.Element,Generator.Element)->Generator.Element) -> [Generator.Element] {
        // if there are no elements, I just want to bail out and
        // return an empty array
        guard var running = self.first else { return [] }

        // running will now be an unwrapped non-optional
        var result = [running]

        // dropFirst is safe because the collection
        // must have at least one element at this point
        for x in dropFirst(self) {
            running = combine(running, x)
            result.append(running)
        }
        return result
    }

}


let a = [1,2,3].accumulate(+)  // [1,3,6]
let b = [Int]().accumulate(+)  // []

가드 없이 어떻게 작성 first하겠습니까? 하지만 여전히 사용 하면 선택 사항이 반환됩니까? 이 같은:

extension Sliceable where SubSlice.Generator.Element == Generator.Element {

    func accumulate(combine: (Generator.Element,Generator.Element)->Generator.Element) -> [Generator.Element] {

        if var running = self.first  {
            var result = [running]

            for x in dropFirst(self) {
                running = combine(running, x)
                result.append(running)
            }
            return result
        }
        else {
            return []
        }
    }

}

여분의 중첩은 성가 시지만 멀리 떨어져 if있는 else것이 논리적이지 않습니다 . 빈 경우에 대해 조기 종료를 한 다음 가능성이없는 것처럼 나머지 기능을 계속 사용하는 것이 훨씬 더 읽기 쉽습니다.


답변

조건을 사용하여 충족 guard되면 guard블록 내에 선언 된 변수 가 나머지 코드 블록에 노출 되어 해당 범위로 들어갑니다. 이전에 언급했듯이 중첩 된 if let명령문 과 함께 유용 합니다.

guard 는 else 문에서 리턴 또는 스로우 를 요구합니다 .

Guard를 사용하여 JSON 구문 분석

아래는 if-let 대신 guard를 사용하여 JSON 객체를 구문 분석하는 방법의 예입니다. 다음은 놀이터 파일이 포함 된 블로그 항목에서 발췌 한 내용입니다.

Swift 2에서 Guard를 사용하여 JSON 구문 분석 방법

func parseJSONWithGuard(data : [String : AnyObject]) throws -> Developer {

    guard let firstname = data["First"] as? String  else {
        return Developer() // we could return a nil Developer()
    }

    guard let lastname = data["Last"] as? String else {
        throw ParseError.BadName // or we could throw a custom exception and handle the error
    }

    guard let website = data["WebSite"] as? String else {
        throw ParseError.BadName
    }

    guard let iosDev = data["iosDeveloper"] as? Bool else {
        throw ParseError.BadName
    }



    return Developer(first: firstname, last: lastname, site: website, ios: iosDev)

}

놀이터 다운로드 : 가드 놀이터

더 많은 정보:

다음은 The Swift Programming Language Guide 에서 발췌 한 내용입니다 .

가드 문의 조건이 충족되면 가드 문의 닫는 중괄호 후에 코드 실행이 계속됩니다. 조건의 일부로 선택적 바인딩을 사용하여 값이 지정된 변수 또는 상수는 guard 문이 나타나는 나머지 코드 블록에 대해 사용할 수 있습니다.

해당 조건이 충족되지 않으면 else 분기 내부의 코드가 실행됩니다. 해당 분기는 보호문을 표시하는 코드 블록을 종료하기 위해 제어를 전송해야합니다. 리턴, 중단 또는 계속과 같은 제어 전송 문으로이를 수행하거나 리턴되지 않는 함수 또는 메소드를 호출 할 수 있습니다. fatalError ()로.


답변

한 가지 장점은 많은 중첩 된 if let진술을 제거한다는 것입니다 . “피라미드 오브 둠”섹션 15:30에 관한 WWDC “Swift의 새로운 기능”비디오를 참조하십시오.


답변

경비원을 사용하는 경우

UITextField 요소가 몇 개 있거나 다른 유형의 사용자 입력이있는 뷰 컨트롤러가있는 경우 textField.text의 선택을 해제하여 내부의 텍스트 (있는 경우)를 가져와야한다는 것을 즉시 알 수 있습니다. isEmpty는 입력을하지 않으면 텍스트 필드가 단순히 nil을 반환합니다.

따라서 랩핑을 해제하고 결국 서버 엔드 포인트에 게시하는 함수에 전달하는 몇 가지가 있습니다. 우리는 서버 코드가 nil 값을 처리하거나 실수로 잘못된 값을 서버에 보내지 않기를 원하므로 먼저 입력 값을 가드로 랩 해제합니다.

func submit() {
    guard let name = nameField.text else {
        show("No name to submit")
        return
    }

    guard let address = addressField.text else {
        show("No address to submit")
        return
    }

    guard let phone = phoneField.text else {
        show("No phone to submit")
        return
    }

    sendToServer(name, address: address, phone: phone)
}

func sendToServer(name: String, address: String, phone: String) {
  ...
}

서버 통신 기능은 선택 사항이 아닌 문자열 값을 매개 변수로 사용하므로 가드 언 래핑을 미리 알 수 있습니다. 언 래핑 (unwrapping)은 블록 내에서 사용할 값을 언 랩핑하는 경우 unwrapping에 익숙하기 때문에 약간 직관적이지 않습니다. 여기에 guard 문은 연관된 블록을 가지고 있지만 실제로는 else 블록입니다. 즉, unwrapping이 실패하면 수행하는 작업입니다. 값은 명령문 자체와 동일한 컨텍스트로 바로 래핑되지 않습니다.

// 우려의 분리

가드없이

가드를 사용하지 않으면 우리는 피라미드의 운명 과 비슷한 코드 더미를 갖게 됩니다. 양식에 새 필드를 추가하거나 코드를 읽기 쉽게 만들 수는 없습니다. 들여 쓰기는 따르기가 어려울 수 있으며, 특히 각 포크마다 다른 많은 문장이 있습니다.

func nonguardSubmit() {
    if let name = nameField.text {
        if let address = addressField.text {
            if let phone = phoneField.text {
                sendToServer(name, address: address, phone: phone)
            } else {
                show("no phone to submit")
            }
        } else {
            show("no address to submit")
        }
    } else {
        show("no name to submit")
    }
}

예, let 문을 쉼표로 구분 된 단일 문으로 묶으면 이러한 모든 문을 결합 할 수도 있지만 어떤 문이 실패했는지 파악하여 사용자에게 메시지를 표시하는 기능을 잃게됩니다.

https://thatthinginswift.com/guard-statement-swift/


답변

가드를 사용하면 우리의 강렬함이 분명합니다. 특정 조건이 만족되지 않으면 나머지 코드를 실행하고 싶지 않습니다. 여기서 우리는 체인을 확장 할 수 있습니다. 아래 코드를 살펴보십시오.

guard let value1 = number1, let value2 = number2 else { return }
 // do stuff here