Generics Function in Swift

Pattaravadee Luamsomboon
2 min readJan 21, 2019

สวัสดีชาวโลก วันนี้เราจะมาแชร์อะไรที่มีสาระเกี่ยวกับการ Coding ฝั่ง iOS ซะหน่อย ไหนๆ ก็เป็น iOS Developer มา 2–3 ปีแล้วอะเนอะ เรื่องที่จะมาแชร์วันนี้ก็คือ….. คือ ….. คือออออออออออออ (อะ ลีลาเก่ง) สิ่งที่เรียกว่า Generics ในภาษา Swift นั่นเอง พอดีเรามีโอกาสได้คุยกับ iOS Developer ท่านนึง เขาถามเราว่ารู้จัก Generics เปล่า รู้เปล่า รู้เปล่า (ใส่ทำนองแบบย่อเปล่าๆ 555 จริงๆถามแค่รู้เปล่านะ แต่เราใส่ทำนองเอง) ตอนนั้นเราก็แบบคืออิหยังวะ = . = เขาก็บอกอันที่เป็นวงเล็บสามเหลี่ยมอะ เท่านั้นแหละเราก็ อ๋อออออออออ เคยเห็น แต่ไม่รู้จัก (นึกว่าเราจะรู้อะดิ ไม่รู้จ้า ก่อนจะรู้ เราต้องไม่รู้ก่อนไงทุกคนนนนน) ทำให้เรามาลงแรงลงมือศึกษาละก็พบว่า เฮ้ยยยยย อันนี้มันมีประโยชน์นะเว้ย ทำไมเราไม่เคยได้มีโอกาสรู้จักและใช้มันมาก่อนเนี่ย เรามาเริ่มรู้จักเจ้า Generics นี่กันเลยดีกว่า

ใน Apple doc ได้กล่าวไว้ว่า

Generic code enables you to write flexible, reusable functions and types that can work with any type, subject to requirements that you define. You can write code that avoids duplication and expresses its intent in a clear, abstracted manner.

อะงงเลยดิ งงเพราะ Apple โม้อิหยังวะ เปล่า! งงเพราะอ่านไม่ออก ผ่าม!! อะหยอกๆ คือ Apple เนี่ยเขาบอกว่าเจ้า Generics code นะ มันทำให้เราเขียน function ได้อย่าง ยืดหยุ่น, เรียกใช้ซ้ำได้, และ type ใน function ก็ใช้ type ไหนก็ได้ ทุกอย่างมันแล้วแต่เราจะกำหนดตอนเรียกใช้งานเลย ในโค้ดเรามันก็จะไม่มี function หลายตัวที่ทำงานเหมือนกัน และแต่ละ function ที่เกิดขึ้นจะมีจุดประสงค์ที่ชัดเจน เป็นรูปธรรม

อาจจะอ่านละงงๆ อยู่ แต่เดี๋ยวก่อน!! เพียงคุณโทรมาใน 5 สายแรกจะได้รับรางวัล… ไม่ใช่ละ!!! เอาใหม่ๆ แต่เดี๋ยวก่อน!! ทุกคนมาลองดูตัวอย่างกันก่อน ละจะปิ๊งไอเดียว่ามันดียังไง มันใช้ยังไง ทำไมมันดีอย่างนี้ล่ะซาร่า

Example:

สมมติเราอยากจะสลับค่าระหว่าง a กับ b โดยปกติโค้ดเราก็จะประมาณตามด้านล่างนี้เนอะ

func swapTwoStrings(_ a: String, _ b: String) -> [String]{return [b,a]}
print("Swap : \(swapTwoStrings("One", "Two"))")
Swap : ["Two", "One"]

function ด้านบนก็เป็นการสลับค่า string type 2 ค่า แล้วถ้าเราอยากจะสลับค่า int type เราก็บ้านๆ เลยอะเนอะ สร้าง function มาอีกอันสำหรับรับค่า int ตามด้านล่าง

func swapTwoInt(_ a: Int, _ b: Int) -> [Int]{return [b,a]}
print("Swap : \(swapTwoInt(1, 2))")
Swap : [2, 1]

ถ้าเราสังเกตดูดีๆ 2 function ที่เราเขียนมันทำงานเหมือนกันเลยนี่หว่า แค่ค่าที่รับกับ return คนละ type เอง ละทำไมเราถึงต้องเขียน 2 function เลยเนี่ย ไม่ cool เลยอะนาย เพราะงี้ไงล่ะชาวโลกเจ้า Generics เลยถือกำเนิดขึ้นมา เรามาดูวิธีใช้กัน

func swapTwoValues<T>(_ a: T, _ b: T) -> [T]{return [b,a]}print("Swap : \(swapTwoValues("One", "Two"))")print("Swap : \(swapTwoValues(1, 2))")Swap : ["Two", "One"]Swap : [2, 1]

จาก code ด้านบนทุกคนคงจะเห็นแล้วว่าเรามีชื่อ function แล้วตามมาด้วย placeholder type ชื่อ T ซึ่งอยู่ใน angle brackets (<T>) เจ้า T เนี่ย จริงๆแล้วไม่ได้บอกว่าตัวเองเป็น type อะไรนะ แค่มันบอกว่า a และ b ที่รับเข้ามาคือ type T เหมือนกัน ตอนที่เราจะรู้ว่า type จริงๆ ของ T คืออะไร นั่นคือตอนที่เราเรียกใช้งาน function swapTwoValues ในแต่ละครั้งนั่นเอง

เนี่ยเพียงแค่ function เดียว เราก็สามารถใช้งานได้ทั้ง string และ int แล้ว เนี่ยโคตร cool ไม่ต้องมาเขียน function ซ้ำๆ เพื่อจุดประสงค์เดียวกัน มีเฮียคนนึงกล่าวไว้ว่า

Lets understand generics with the help of good code and bad code.

จริงๆ Generics ของ Swift ไม่ได้มีแค่นี้นะ จะมี

  1. Generic Functions and Generic Types
  2. Protocols with Associated Types
  3. Generic Where Clauses
  4. Generic Subscripts

แต่วันนี้เรามีมาแชร์แค่ข้อ 1 นี่แหละ 555555 หวังว่าบทความเราจะมีประโยชน์กับทุกคน และทุกคนอ่านมันด้วยความสนุกนะ แล้วพบกันใหม่ในบทความหน้า :)

--

--