😊

【翻訳】5 Swift Features Every Beginner Must Know

2023/07/26に公開

初級開発者として働くということは、ただ基本的な知識を持って仕事をし、先輩のサポートを待つということではありません。スキルアップの余地は常にあります。

学んで、学んで、学びましょう。

Swift は便利な機能をたくさん備えた強力な言語の一つです。この記事では、 Swift の5つの便利な機能について説明し、 iOS 開発における私たちのスキルがレベルアップすることを願います。

1. Extension

Swift では、 UIViewController 、 UIView 、 String 、 Date 、 Int などの既存のクラスに、Extension を通してより多くの関数を追加することができます。また、クラスの別のプロパティにアクセスしたい場合にも便利です。

この例では、 Date クラス に isToday() と isYesterday() という新しい関数を追加します。

extension Date {
    func isToday() -> Bool {
        let calendar = Calendar.current
        return calendar.isDateInToday(self) // self refer to current Date class
    }
    
    func isYesterday() -> Bool {
        let calendar = Calendar.current
        return calendar.isDateInYesterday(self) // self refer to current Date class
    }
}
// usage is the same as common date functions
let date = Date()
print(date.isToday()) // true
print(date.isYesterday()) // false

さて、 UIViewController に新しい関数を追加します。 UIViewContoller をポップバックするシンプルな関数です。

extension UIViewController {
    func pop() {
        self.navigationController?.popViewController(animated: true)
    }
}

class DemoViewController: UIViewController {
    // ...
    // ...
    
    func didClickBackButton() {
        self.pop()
    }
}

あらゆる UIViewController クラスで広く使えます。それってすごいことですか?

2. Enum

単なる一般的な Enumeration ではありません。 Swift では、Enum は、 Int 、 String 、 Double などの定義された型を持つことができます。例えば、私たちのバックエンド API が値を表現するために整数を必要とする場合、より自己説明可能なコードにするために Int 型 を持つ Enum を使用することができます(これはとてもクールに見えます)。

enum LoginType: Int {
    case google = 1
    case facebook = 4
    case apple = 5
    case email = 6
    case anonymous = 0
}
// example usage: enum function as parameter
func authenticate(loginType: LoginType) {
    // do API request process 
}

authenticate(loginType: .apple)

Xcode では、ドット(.)で値を入力し始めると、ドロップダウン・オプションでうまく表示されます。

Enum のもう一つの便利な機能は、 Associated Value です。これについてはこちら(https://docs.swift.org/swift-book/documentation/the-swift-programming-language/enumerations/)でよく説明されています。これはパラメータを持つ Enum です。本当か?そう、選択されたオプションに渡す変数を定義できます。

enum Vehicle {
    case car(modelId: String, maxSpeed: Double)
    case truck(modelId: String, maxWeightCapacity: Double)
    case motorcycle(modelId: String, maxSpeed: Double)
}

func insertData(vehicle: Vehicle) {
    // process data
}

// call the function, and pass the enum value
insertData(vehicle: .car(modelId: "A12001", maxSpeed: 240))

// in variable definition
let selectedCar = Vehicle.truck(modelId: "TowTrucker", maxWeightCapacity: 2500)

3. Map

Map は、配列(または任意のコレクション型)を別の要素に変換するために、全ての言語で使用される一般的な関数です。以下はその例です。

例1

Int の配列を「2の乗算」で新しい配列に変換します。

通常私たちがやることは(古い方法ですが)、配列のループを作り、掛け算をしてから新しい配列に追加することです。この2つの方法の違いを見てみましょう(同じ結果が得られることを確認するために、プレイグラウンドに貼り付けてみよう)。

// old way
let array = [1, 2, 3, 4, 5]

// do multiply with two (i * 2)
var newArray = [Int]()
for i in array {
    let result = i * 2
    newArray.append(result)
}

// get the result
print(newArray)

// Our good practice 😆
let newArray2 = array.map { $0 * 2 }
print(newArray2)

なんと、たった1行のコードで同じことができます!

説明しましょう。

つまり、 map() 関数 は、配列内の全ての要素をクロージャ{ ... }で指定された意図した結果に変換し、その結果を newArray2 に返すということです。この $0 は、変換する配列の現在のオブジェクトであることに注意してください。これは第1引数でも構いません。詳細については、こちら(https://stackoverflow.com/questions/36144322/what-does-0-and-1-mean-in-swift-closures/36144362#36144362)を参照してください。

これは、クロージャを持つ swift 関数 の一般的な構文です。

variable.functionName { // conditions or intended operation }

例2

オブジェクトの配列を別の要素に変換します。例えば、学生のオブジェクトの配列があり、そのスコアだけを取得する必要があるとします。

struct Student {
    let id: String
    let name: String
    var score = 0
}

let studentA = Student(id: "1001", name: "John", score: 48)
let studentB = Student(id: "1002", name: "Carlos", score: 63)
let studentC = Student(id: "1003", name: "Foo", score: 80)

let students = [studentA, studentB, studentC]
// old way
var allScores = [Int]()
for student in students {
    allScores.append(student.score)
}
// our better way
let allScore = students.map { $0.score }
// wow again!

これで map() がどのように機能するか理解できたでしょう。次の似たような関数に移りましょう。

4. filter

map() をすでに理解しているなら、これは簡単でしょう。 map() とよく似ていますが、クロージャの中で与えられた条件に基づいてマッチする要素を探したり返したりするのが filter() です。

例えば、50点以上の学生をフィルタリングしようとします。

// find student with score > 50
// old way
var passedStudent = [Student]()
for student in students {
    if student.score > 50 {
        passedStudent.append(student)
    }
}
print(passedStudent)
// our brilliant way
let passed = students.filter { $0.score > 50 }

5. computed Property(読み取り専用)

computed Property と関数をいつ使うかについては、これまでにも何度か議論されてきました。私たちが知っておく必要があるのは、 computed Property は単純な操作や計算をするときに使うということだけです。それだけです。この記事では、"get"値(読み取り専用)として使用する方法に焦点を当てます。つまり、値は基本的に他のプロパティに依存します。

下の例を見てください。幅と高さを持つ Rectangle の構造体です。次に、さらにいくつかの computed Property を追加します。やってみましょう!

struct Rectangle {
    var width = 0.0
    var height = 0.0
    
    // computed properties
    var perimeter: Double {
        return width * 2 + height * 2
    }
    
    var wide: Double {
        return width * height
    }
}

// usage example
let box = Rectangle(width: 30, height: 40)
print(box.perimeter) // 140.0
print(box.wide) // 1200.0

素晴らしい、これで私たちは iOS プロジェクトで頻繁に使用する Swift の5つの素晴らしい機能を全てカバーしました。あなたのコードを実装し、改善してみましょう。

次は何をする?

flatMap() 、 compactMap() 、 count(where:) など、 Swift で提供されている関数をもっと調べてみてください。

読んでくれてありがとう。フィードバックは大歓迎です。

"学ぶこと、それが私たちのスキルを成長させる方法です"

参考記事

https://docs.swift.org/swift-book/LanguageGuide/CollectionTypes.html

https://docs.swift.org/swift-book/LanguageGuide/Enumerations.html

【翻訳元の記事】

5 Swift Features Every Beginner Must Know
https://medium.com/codex/5-swift-features-every-beginner-must-know-9bb101d051b8

Discussion