Closure Parameter

ช่วงนี้งานเยอะมาก ไม่ค่อยได้ update และอัด video tutorial สักเท่าไหร่ ช่วงนี้หยุดหลายวันมีเวลาได้เขียน blog บ้าง เอาละเข้าเรื่องเลยดีกว่า

Closure ในภาษา Swift ก็เหมือนกับ Block ในภาษา Objective-C อธิบายสั้นๆมันก็คือ รูปแบบหนึ่งของฟังก์ชันที่ต้องไม่มีชื่อ เมื่อเราเขียนโปรแกรมด้วยภาษา swift สักระยะหนึ่ง ก็จะได้ใช้ closure อย่างแน่นอน สำหรับโพสต์นี้ผมคงไม่ได้มาอธิบายว่า อะไรคือ closure แต่จะพูดถึง สไตล์ การเขียนเพื่อทำให้โค้ดมันอ่านง่ายมากขึ้น สำหรับคนที่เพิ่งหัดเขียน swift ก็ควรจะศึกษา closure ไว้นะครับ เพราะยังไงก็ต้องได้ใช้แน่นอน

ปกติการใช้ closure มักจะเห็นได้บ่อยกับฟังก์ชันคือ ตัวฟังก์ชันมักจะรับ closure เข้ามาเป็นพารามิเตอร์ เช่น ฟังก์ชัน sort ของ Array

เมื่อพิจารณาจากฟังก์ชัน sort ก็จะเห็นว่าตัวแปร isOrderedBefore นั้นเป็น closure ที่รับพารามิเตอร์สองตัว เป็นสตริง และส่งค่ากลับเป็น Bool เมื่อเรียกใช้งานฟังก์ชัน sort ก็จะมีลักษณะดังนี้

โดยทั่วๆไป ฟังก์ชันที่มี closure เป็นพารามิเตอร์ตัวสุดท้าย มักจะเขียนในลักษณะ trailing closure ดังนี้

การใช้ trailing closure นี้ก็ทำให้โค้ดสั้น กระชับ มากขึ้น

ในภาษา swift การใช้ closure นั้นมีประโยชน์มาก และเขียนลดรูปให้สั้นลงได้หลายแบบ แต่อย่างไรก็ตาม ถ้าหากฟังก์ชันรับพารามิเตอร์ ที่เป็น closure สัก 2 ตัว ก็จะเริ่มเกิดปัญหา คือ โค้ด มันอ่านยากกกกกก เช่นฟังก์ชัน animateWithDuration ของ UIView ซึ่งมีหน้าตาดังนี้

จากตัวอย่างจะเห็นว่า ฟังก์ชันนี้รับพารามิเตอร์มาด้วยกัน 3 ตัวคือ

  1. duration: NSTimInterVal
  2. animation: () -> Void
  3. completion: ((Bool) -> Void)?)

เมื่อเรียกใช้งาน โค้ดจะมีลักษณะดังนี้

ในครั้งแรกที่เห็น ผมเชื่อว่า หลายคน งง บอกตรงๆว่าแรกๆ ผมก็งง ถ้าคุณไม่งง แสดงว่าคุณได้เข้าใจ closure ในระดับดีมาก แต่สำหรับคนที่งงว่า โค้ดมันทำอะไร ถ้าลองถ้าพิจารณาอย่างคร่าวๆ ก็พอจะเห็นว่า โค้ดนี้  view จะเปลี่ยนขนาดของ frame จากนั้น view ก็จะเรียกเมธอด removeFromeSuperView

ทำไงดี ให้โค้ดมันอ่านง่ายขึ้น ?

คือบางคนอาจจะใช้ tab เว้นวรรคเพื่อช่วยให้โค้ดมันดูเป็นระเบียบอ่านง่ายขึ้น แต่ในลักษณะแบบนี้ ผมเห็นว่า tab มันไม่ค่อยได้ช่วยอะไรสักเท่าไหร่ และถึงเราจะเขียนแบบ trailing closure มันก็ได้แค่พารามิเตอร์สุดท้าย ผมก็ยังมองว่ามันอ่านยากอยู่ดี

สำหรับตัวผมเอง มีเทคนิค 2 อย่าง ที่คิดว่า ทำให้โค้ดมันอ่านง่ายขึ้น

  • อย่างแรกคือตัวแปร closure ขึ้นมา
  • สองก็คือประกาศฟังก์ชัน

เนื่องจาก swift นั้นได้ให้ function/closure เป็น first class variable ดังนั้น เราจึงสามารถประกาศตัวแปรให้เป็น function/closure ได้ ซึ่งการประกาศตัวแปรให้เก็บ closure นี้ก็จะมีการประกาศตัวแปรลักษณะแบบนี้

เมื่อนำโค้ด ฟังก์ชัน dissmiss มาเขียนใหม่ก็จะได้ว่า

ส่วนวิธีที่สอง ก็คล้ายกับวิธีการแรก คือใช้การประกาศฟังก์ชันแทน

แม้ว่าโค้ดที่เขียนใหม่ทั้งสองจะเขียนยาว กว่าเดิม แต่จะเห็นได้ว่า โค้ด ที่เขียนไปนั้น อ่านง่ายกว่าเดิมเยอะมาก

สุดท้ายแล้วสไตล์ในการเขียนโปรแกรมนั้นมันก็ขึ้นอยู่กับแต่ละคนครับ บางคนอาจจะไม่ชอบสไตล์แบบนี้เพราะมันเขียนเยอะกว่าเดิม หรือถ้าใครมีเทคนิคอื่นๆก็แนะนำกันมาได้ครับ