知識のアップデート
ある程度学習した言語であれば、特に調べなくてもやりたいことが実装できたりします。
そのコードは問題なく動き、ある程度綺麗に書けていると思ったら、満足して、次の実装に移ったりします。
もちろんそれでもいいんですが、改めてリファレンスを見ると、こんな書き方があったのかと思わされます。
今回は筆者の知識レベルでありますが、個人的にこんな書き方もできるのかと思った実装方法をまとめます。
参考にするも良いいですし、皆さんの知識のアップデートのきっかけになればなと思います。
参考にしたサイトは下記です
https://www.swiftlangjp.com/
The Swift Programming Languageの日本語版
本記事
上記サイトの言語ガイド(LANGUAGE GUIDE)を上から見てきます。
本記事は「基本(The Basics)」〜「エラー処理(Error Handling)」までの内容で、気づきをまとめたものです。
やってくぞ〜!
基本演算子(Basic Operators)
片側範囲演算子(One-Sided Ranges)
ループ処理で使うことはあったが、配列の添え字としても使える。
また ...5
とかはPartialRangeThrough型でcontainsなどの関数も使用可能。
let names = ["Anna", "Alex", "Brian", "Jack"]
for name in names[2...] { print(name) } // Brian, Jack
for name in names[..<2] { print(name) } // Anna, Alex
(...5).contains(8) // false
コレクション型(Collection Types)
配列リテラルを使ったセットの作成(Creating a Set with an Array Literal)
Setの配列で型推論を用いて、イニシャライザを書くことができる。
var favoriteGenres: Set<String> = ["Rock", "Classical", "Hip hop"]
var favoriteGenres: Set = ["Rock", "Classical", "Hip hop"] // こうも書くことができる
上の行の書き方で書いてたけど、Setを型推論で書けるのは知らなかった。
型推論が強力だから、言われてみたら確かにそうというのはある。結局どっち書くかは好み分かれそう。
基本的なセットの操作(Fundamental Set Operations)
複数のSetの配列で両方に一致している要素のみの配列を作りたい場合とか、片方だけマッチしている配列とかを取り出す関数が用意されている。
(リファレンスのベン図がメソッドの挙動のイメージをしやすくて、わかりやすい)
let oddDigits: Set = [1, 3, 5, 7, 9]
let evenDigits: Set = [0, 2, 4, 6, 8]
let singleDigitPrimeNumbers: Set = [2, 3, 5, 7]
oddDigits.union(evenDigits).sorted() // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
oddDigits.intersection(evenDigits).sorted() // []
oddDigits.subtracting(singleDigitPrimeNumbers).sorted() // [1, 9]
oddDigits.symmetricDifference(singleDigitPrimeNumbers).sorted() // [1, 2, 9]
自前でループしたり、filter関数とかでなんとかしようと思ったりもするけど、もうすでに用意されている関数が使えるパターン。
こういう場面が個人的にあるあるなので、なんとかしたい。
辞書へのアクセスと変更(Accessing and Modifying a Dictionary)
辞書型の要素の値の更新時に、updateValue(_:forKey:)メソッドを使うことで、更新前の値が戻り値として取得できる。
var airports = ["YYZ": "Toronto Pearson", "DUB": "Dublin"]
if let oldValue = airports.updateValue("Dublin Airport", forKey: "DUB") {
print("DUB キーに対する更新前のバリューは \(oldValue) でした。")
}
// removeも同様
if let removedValue = airports.removeValue(forKey: "DUB") {
print("削除された空港の名前は \(removedValue) です。")
} else {
print("airports 辞書には DUB キーに対する値がありません。")
}
メソッド名だけみると update
で戻り値が更新前なのは「ん?」って思った。実装時はちゃんとドキュメントも見ようの教訓。
クロージャ(Closures)
演算子メソッド(Operator Methods)
Comparableに準拠した要素のソートはsorted関数にオペレーターを渡すだけでできる。
let students: Set = ["Kofi", "Abena", "Peter", "Kweku", "Akosua"]
print(students.sorted()) // Prints "["Abena", "Akosua", "Kofi", "Kweku", "Peter"]"
print(students.sorted(by: >)) // Prints "["Peter", "Kweku", "Kofi", "Akosua", "Abena"]"
エラー処理(Error Handling)
do catchを使ったエラー処理(Handling Errors Using Do-Catch)
catch句で各エラーを一つ一つ拾うやり方もあるが、一気にまとめてもとれる。
enum VendingMachineError: Error {
case invalidSelection
case insufficientFunds(coinsNeeded: Int)
}
func nourish(with item: String) throws {
do {
try vendingMachine.vend(itemNamed: item)
} catch is VendingMachineError {
print("自動販売機から買うことができませんでした。")
}
}
上記の場合は、他のエラーは呼び出し元に戻されるため、メソッドの責務に応じて、その責務の範囲内で対処したいエラーとかはこういう記述方の方が良い時もありそう。