신속하게 선택적 폐쇄를 만드는 방법은 무엇입니까?


93

선택적 클로저를 취하는 Swift에서 인수를 선언하려고합니다. 내가 선언 한 함수는 다음과 같습니다.

class Promise {

 func then(onFulfilled: ()->(), onReject: ()->()?){       
    if let callableRjector = onReject {
      // do stuff! 
    }
 }

}

그러나 Swift는 "if let"이 선언 된 "조건부의 바운드 값은 선택 유형이어야합니다"라고 불평합니다.


매개 변수가있는 하나의 클로저 만 사용하는 것이 좋습니다.
catanore

답변:


113

선택적 클로저는 괄호로 묶어야합니다. 이것은 ?운영자의 범위를 적절하게 지정합니다 .

func then(onFulfilled: ()->(), onReject: (()->())?){       
    if let callableRjector = onReject {
      // do stuff! 
    }
 }

괄호로 묶어야하는 이유가 무엇인지 알고 있습니까?
Marcosc 2014-06-24

5
아마도 모호성을 제거하기 위해서 일 것입니다. 선택적 클로저에 반환 값이 있으면 ()->Int?의미 가 혼동 될 수 있습니다.
Cezar

3
또한 Swift 책에서 :“선택적 유형을 선언 할 때 괄호를 사용하여? 운영자. 예를 들어, 선택적 정수 배열을 선언하려면 유형 주석을 (Int []) ?; Int [] 작성 중? 오류가 발생합니다.”
Cezar

@Cezar "선택적 폐쇄"를 사용하는 이유와 위치에 대해 설명해 주시겠습니까?이 사실을 알고 싶습니다.
iLearner

@Cezar 현재 Mac에서는 아니기 때문에 구문이 약간 벗어 났을 수 있지만 ?실제로 Optional<T>는를 위한 설탕 이라는 것을 기억하십시오 . 따라서`func then (onFulfilled : ()-> (), onReject : Optional <() -> ()>) {`그러면 ()IMO ()?가 더 예쁘지 만 여분의 . 또한 다음과 같은 typealias로 더 예쁘게 만들 수 있습니다 typealias RejectHandler = () -> () func then(onFulfilled: ()->(), onReject: RejectHandler?) {
Andrew Carter

62

코드를 더 짧게 만들기 위해 호출 할 때 매개 변수 및 선택적 체인에 nil대한 기본값으로 사용할 수 있습니다 .onReject?()

func then(onFulfilled: ()->(), onReject: (()->())? = nil) {
  onReject?()
}

이렇게하면 함수 onReject를 호출 할 때 매개 변수 를 생략 할 수 있습니다 then.

then({ /* on fulfilled */ })

후행 클로저 구문을 사용하여 onReject매개 변수를 then함수 에 전달할 수도 있습니다 .

then({ /* on fulfilled */ }) {
  // ... on reject
}

여기에 대한 블로그 게시물 이 있습니다.


34

이 "선택적"클로저가 아무 작업도 수행하지 않아야한다고 가정하기 때문에 빈 클로저가있는 매개 변수를 기본값으로 사용할 수 있습니다.

func then(onFulfilled: ()->(), onReject: ()->() = {}){       
    // now you can call your closures
    onFulfilled()
    onReject()
}

이 함수는 이제 onReject콜백을 사용하거나 사용하지 않고 호출 할 수 있습니다.

then({ ... })
then({ ... }, onReject: { ... })

스위프트의 대단한 필요가 없습니다 Optionals?!


이것은 좋은 해결책입니다!
Roland T.

6

아마도 더 깨끗한 방법 일 것입니다. 특히 클로저에 복잡한 매개 변수가있을 때.

typealias SimpleCallBack = () -> ()

class Promise {

func then(onFulfilled: SimpleCallBack, onReject: SimpleCallBack?){       
    if let callableRjector = onReject {
        // do stuff! 
    }
}

}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.