はじめに
Extensionの基礎的な扱い方をまとめました。
Extensionとは?
Extensionキーワードを使うことで既存の型に方を構成する要素(プロパティやメソッドやイニシャライザ)を追加する事ができます。
具体例を見ていきましょう。
メソッドでの利用
以下のようにすることで、plusOne
メソッドをIntに追加できます。
self
はこのメソッドの呼び出し元(今回は5)を表しています。(詳細は後述します)
extension Int {
func plusOne() -> Int {
return self + 1
}
}
print(5.plusOne()) // 6
プロパティでの利用
extensionはストアドプロパティは追加できませんが、コンピューテッドプロパティを追加する事ができます。
extension Int {
var minus10: Int {
return self - 10
}
}
print(100.minus10) // 90
イニシャライザでの利用
イニシャライザを追加してみます。
enum BloodType {
case A
case B
case O
case AB
var title: String {
return "あなたの血液型は"
}
var message: String {
switch self {
case .A: return "Aです"
case .B: return "Bです"
case .O: return "Oです"
case .AB: return "ABです"
}
}
}
extension UIAlertController {
convenience init(blood: BloodType) {
self.init(title: blood.title,
message: blood.message,
preferredStyle: .alert)
}
}
let blood = BloodType.AB
let alert = UIAlertController(blood: blood)
プロトコルでの利用
プロトコルをエクステンションすることもできます。
protocol Book {
var name: String { get }
var price: Int { get }
}
extension Book {
func printName() {
print(name)
}
func printPrice() {
print(price)
}
func printSelf() {
print(self)
}
func printMyType() {
print(type(of: self))
}
}
struct MyBook: Book {
var name: String
var price: Int
}
let myBook = MyBook(name: "マイブック", price: 1000)
myBook.printPrice() // 1000
myBook.printSelf() // MyBook(name: "マイブック", price: 1000)
myBook.printMyType() // MyBook
これでBook
プロトコルを採用した型はextension Book
内のメソッドを扱う事ができます。
制約の追加
プロトコルエクステンションは型による制約をつけることができ、この条件を満たすもののみプロトコルエクステンションを有効にできます。
extension Collection where Element == Int {
var total: Int {
return self.reduce(0) { $0 + $1 }
}
}
let intArray = [1, 2, 3, 4, 5]
print(intArray.total) // 15
let stringArray = ["a", "b", "c"]
print(stringArray.total) // error
条件はCollection
の要素Element
がInt
であると言う意味です。ですので、intArray
の要素はInt
なのでtotal
プロパティを扱う事ができますが、stringArray
は要素がString
なのでtotal
プロパティにアクセスしようとするとエラーになります。
おわりに
エクステンションの基礎的な使い方を紹介しました。以上です。