Failable Initializer

Swift เวอร์ชั่น 1.1 ที่มากับ Xcode 6.1 นั้น มีฟีเจอร์ใหม่ที่ชื่อว่า Failable Initializer แล้วมันคืออะไร จะเห็นว่าตอนที่เราสร้าง Class, Struct หรือ Enum บน Swift ขึ้นมานั้น เราสามารถเขียน init method เพื่อกำหนดค่าเริ่มต้นของ property ได้ แต่การทำ Initialization นั้นก็ใช่ว่าจะสำเร็จเสมอไป เช่นตัวอย่าง Initialization method ของ UIImage บน Cocoa Framework แบบนี้


จะเกิดอะไรขึ้น ถ้า sampleImage.png ไม่มีอยู่จริง หรือไม่สามารถอ่านไฟล์นี้ได้ด้วยเหตุผลอื่นๆ บน Swift 1.1 ก็เลยใช้ Failable Initializer ซึ่งจะให้ค่าที่ส่งกลับมาอยู่ในรูปแบบของ Optional Value นั่นหมายความว่าสิ่งที่เราสร้างขึ้นมาอาจจะเป็น nil ก็ได้ ถ้าการทำ Initialization ไม่สมบูรณ์ ซึ่งเวลาจะใช้งานก็ควรจะทำแบบนี้ (ในกรณีที่เป็นรูปที่ไม่แน่ใจว่ามีอยู่จริงหรือไม่ เช่น หลังจากที่ดาวน์โหลดรูปภาพจาก Internet)


อย่างที่เคยพูดไปใน Blog ก่อนๆ ว่า Instance ใน Swift แบ่งออกเป็น 2 ประเภทคือ Reference Type (Class) และ Value Type (Struct, Enum) ในการใช้ Failable Initialize นั้น เราจะมาว่ากันที่ฝั่งของ Value Type กันก่อน

ตัวอย่างโค้ดของการทำ Failable Initialize ก็ตามนี้ครับ เริ่มจาก Struct กันก่อน 


ไม่มีอะไรน่าตกใจเลย เพียงเราใส่ ? (question mark) ไว้ท้าย init เราก็จะสามารถส่งค่า nil กลับเป็นผลลัพธ์ของการ Initialization ได้แล้ว Enum ก็ทำคล้ายๆ กัน


หรือตัวอย่างที่เจอกันบ่อยๆ (และจะใช้เป็นตัวอย่างใน Blog นี้ด้วย) คือการรับข้อมูลจากทางฝั่ง Backend (API, Web Service อะไรก็ว่าไป) แล้วนำข้อมูลมาสร้าง Custom Object เพื่อนำไปใช้งานต่อไป

ในการใช้ Failable Initialize กับ Class (Reference Type) นั้นจะแตกต่างออกไปสักหน่อย โดยในโค้ดการทำ Failable Initialize กับ Struct (Value Type) ด้านบน จะเห็นว่าเราสามารถที่จะส่งค่า nil กลับ (initialization failure) จากส่วนไหนก็ได้ ในตัวอย่างคือตรวจสอบและส่งค่า nil กลับก่อนที่ species จะถูกกำหนดค่าเสียอีก

แต่บน Class จะต่างออกไปโดยเราจะสามารถส่งค่า nil กลับได้ (initialization failure) ก็ต่อเมื่อ property ทั้งหมดถูกกำหนดค่าเริ่มต้นไปแล้วเท่านั้น เช่นแบบนี้


แต่มันก็ดูไม่ค่อยเข้าท่าเท่าไหร่ ที่เราจะต้อง Execute สิ่งที่ไม่จำเป็น เช่นในตัวอย่างแรกเราจะต้อง assign empty string ให้ name ไปก่อน แล้วพอเช็คว่า name ที่ถูกส่งมาเป็น empty ก็ส่งค่า nil กลับ ดังนั้น empty string เมื่อกี้ก็ใส่ไปโดยที่ไม่รู้จะใส่ไปทำไม หรือตัวอย่างที่สองคือ กำหนดค่าไปก่อนเลย แล้วค่อยมาเช็ค นั่นยิ่งแล้วใหญ่เลย ดังนั้นวิธีที่เหมาะสมก็เลยตกอยู่ที่การใช้ Implicitly Unwrapped Optional แบบนี้


นั่นคือ name จะมีค่าเป็น nil จนกระทั่งถูกกำหนดค่าอะไรบางอย่างให้ในการทำ Initialization ดูแล้วโค้ดมันเข้าใจง่าย และตรงไปตรงมาขึ้นเยอะ ซึ่งเราก็สามารถส่งค่า nil กลับก่อนที่จะกำหนดค่าลงไปที่ name property ได้เหมือนตัวอย่างแรก ส่วนเวลานำไปใช้งาน ก็อย่างที่บอกในตอนต้นว่า มันส่งค่ากลับเป็น Optional ดังนั้นก็ต้องตรวจสอบด้วย `if let` keyword แบบนี้ จบละ

Popular posts from this blog

[Android Dev] การติดตั้ง Eclipse+AndroidSDK เพื่อพัฒนาโปรแกรมบน Android

12 วิธี การบริการและดูแลลูกค้าในร้าน Starbucks

5 TED Talk ที่จะช่วยให้คุณทำงานดีขึ้น