Extension เป็นการเพิ่มความสามารถให้ Class, Struct, Enum หรือ Protocol โดยที่เราไม่ต้องมีโค้ดของ type เหล่านั้น ทำให้เราก็สามารถเพิ่มความสามารถที่ต้องการให้กับ ไลบารีภายนอกได้ด้วย
ถ้าเราต้องการเพิ่ม compute property isOn
เราทำได้แบบนี้
Copy extension TapSwitch {
var isOn: Bool {
self == .on
}
}
print ( state.isOn )
บางครั้งเราเพิ่มความสามารถลงบน type standard อย่าง Double เพื่อทำ format หรือทำให้โค้ดเราอ่านง่ายขึ้นแบบนี้
Copy extension Double {
var km: Double { return self * 1_000.0 }
var m: Double { return self }
var cm: Double { return self / 100.0 }
var mm: Double { return self / 1_000.0 }
var ft: Double { return self / 3.28084 }
}
let distance = 45 .km + 5 .cm
หรือเราสามารถทำให้ TapSwitch สามารถ conform protocol ได้แบบนี้
Copy enum TapSwitch {
case on
case off
}
extension TapSwitch : ItemDiscribable {
var description: String {
switch self {
case .on : return "current is on"
case .off : return "current is off"
}
}
}
extension TapSwitch : Togglable {
mutating func toggle () {
switch self {
case .on :
self = .off
case .off :
self = .on
}
}
}
Extension
สามารถเพิ่มความสามารถได้ แต่จะไม่สามารถ override
ได้
รวมทั้งไม่สามารถเก็บค่าไว้ได้ เราไม่สามารถประกาศ ตัวแปรเพิ่มโดยไม่ใช่ compute properties ได้
จากตอนที่เราเขียน Enum เราจะไม่สามารถเขียนให้เป็น raw type และใช้ case argument ไปพร้อม ๆ กันได้
Copy enum PaymentType : String {
case cheque( issuer : String )
case creditCard( number : String )
}
// ใช้ case argument และต้องการเป็น raw type String
// โปรแกรมจะไม่สามารถรันได้
เราสามารถนำ extension มาเพิ่มความสามารถให้กับ enum ที่เป็น case argument ทำให้สามารถเป็น raw type ได้ แบบนี้
Copy enum PaymentType {
case cheque( issuer : String )
case creditCard( number : String )
var description: String {
switch self {
case let . cheque ( issuer ) : return "Cheque issued by \(issuer) "
case let . creditCard ( number ) : return "Credit card number \(number) "
}
}
}
extension PaymentType : RawRepresentable {
typealias RawValue = String
init? ( rawValue : RawValue ) {
switch rawValue {
case "Cheque" : self = . cheque ( issuer : "" )
case "CreditCard" : self = . creditCard ( number : "" )
default: return nil
}
}
var rawValue: String {
return description
}
}
เราเพิ่ม extension ให้ enum conform RawRepresentable
จากนั้นเราก็ implement protocol requirement ใน extension ก็จะทำให้เราสามารถใช้งานได้