วิธีหนึ่งจะทำการปิดทางเลือกในอย่างรวดเร็วได้อย่างไร?


93

ฉันพยายามประกาศอาร์กิวเมนต์ใน Swift ซึ่งจะปิดทางเลือก ฟังก์ชันที่ฉันประกาศมีลักษณะดังนี้:

class Promise {

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

}

แต่ Swift บ่นว่า "Bound value in a conditional must be an Optional type" ซึ่งมีการประกาศ "if let"


พิจารณาใช้การปิดเพียงครั้งเดียวที่มีพารามิเตอร์
catanore

คำตอบ:


113

คุณควรใส่การปิดทางเลือกในวงเล็บ สิ่งนี้จะกำหนดขอบเขตตัว?ดำเนินการอย่างเหมาะสม

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

คุณรู้หรือไม่ว่าเหตุผลที่ต้องใส่ไว้ในวงเล็บคืออะไร?
Marcosc

5
อาจเพื่อลบความคลุมเครือ หากการปิดทางเลือกต้องมีค่าส่งคืนอาจทำให้เกิดความสับสนว่า()->Int?หมายถึงอะไร
Cezar

3
นอกจากนี้จากหนังสือ Swift:“ เมื่อประกาศประเภทที่เป็นทางเลือกอย่าลืมใช้วงเล็บเพื่อกำหนดขอบเขต? ตัวดำเนินการ ตัวอย่างเช่นในการประกาศอาร์เรย์ที่เป็นทางเลือกของจำนวนเต็มให้เขียนคำอธิบายประกอบประเภทเป็น (Int [])? เขียน Int []? ทำให้เกิดข้อผิดพลาด”
Cezar

@Cezar คุณช่วยอธิบายหน่อยได้ไหมว่าทำไมถึงใช้ "ตัวเลือกการปิด" ฉันอยากรู้ว่าทำไม
iLearner

@Cezar ไม่ได้อยู่บน mac ในขณะนี้ดังนั้นไวยากรณ์ของฉันอาจจะปิดเล็กน้อย แต่จำไว้ว่า?มันเป็นเพียงแค่น้ำตาลOptional<T>เท่านั้นดังนั้นคุณสามารถเขียน `func แล้ว (onFulfilled: () -> (), onReject: Optional <() -> ()>) {`` ถ้าอย่างนั้นคุณก็ไม่จำเป็นต้องมีสิ่งพิเศษ()แม้ว่า IMO ()?จะสวยกว่าก็ตาม นอกจากนี้คุณสามารถทำให้สวยขึ้นได้ด้วยตัวพิมพ์เช่น typealias RejectHandler = () -> () func then(onFulfilled: ()->(), onReject: RejectHandler?) {
Andrew Carter

63

ในการทำให้โค้ดสั้นลงเราสามารถใช้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: { ... })

ไม่จำเป็นต้องมี Swift ที่ยอดเยี่ยม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.