Swift study - Methods


Swift - Methods


メソッドは、特定のタイプに関連付けられた関数です.クラス、構造体、および列挙型は、特定の動作および所与のタイプのインスタンスとともに動作する機能性をカプセル化したすべてのインスタンスメソッドを指定することができる.クラス、構造体、および列挙型は、タイプに関連付けられたタイプメソッドを指定することもできます.タイプメソッドはObjective-Cのクラスメソッドに似ています.
sweetでは,構造体と列挙型定義手法の事実はC,Objective−Cと大きく異なる.Objective-Cのクラスはメソッドを定義できる唯一のタイプです.swiftでは、クラス、構造体、または列挙タイプを指定し、カスタムタイプにメソッドを指定する柔軟性があります.

インスタンスメソッド(Instance Methods)


インスタンスメソッドは、特定のクラス、構造体、または列挙インスタンスに属する関数です.インスタンスの機能をサポートします.機能は、インスタンス・プロシージャを変更およびアクセスする方法またはインスタンスの目的に関連する機能を提供します.インスタンスメソッドでは、関数構文と同じ構文が使用されます.
属するタイプのカッコ内にインスタンスメソッドを作成します.インスタンス・メソッドは、このタイプの他のすべてのインスタンス・プログラムおよびメソッドに暗黙的なアクセス権を有します.インスタンスメソッドは、このタイプに属する特定のインスタンスでのみ呼び出されます.既存のインスタンスがなければ、独立して呼び出すことはできません.
class Counter {
    var count = 0
    func increment() {
        count += 1
    }
    func increment(by amount: Int) {
        count += amount
    }
    func reset() {
        count = 0
    }
}
カウンタクラスは、3つのインスタンスメソッドを定義します.
  • increment()カウンタを1つ増やします.
  • increment(by: Int)カウンタに特定の数値でインクリメントされます.
  • reset()カウンタを0にリセットします.
  • countで変数を作成し、現在の数値の値を追跡します.ポイント構文呼び出しを使用します.
    let counter = Counter()
    // the initial counter value is 0
    counter.increment()
    // the counter's value is now 1
    counter.increment(by: 5)
    // the counter's value is now 6
    counter.reset()
    // the counter's value is now 0
    関数パラメータには、パラメータラベルと名前を付けることができます.メソッドパラメータと同じです.これは、メソッドがタイプに関連付けられた関数であるためです.

    The self Property


    タイプのすべてのインスタンスには、selfという明示的なプロシージャがあります.これは、インスタンス自体と同じです.selfpropertyを使用して、現在のインスタンスを自己インスタンスメソッド内で参照します.
    func increment() {
        self.count += 1
    }
    実際、コードではself頻繁に記述する必要はありません.明確に作成されていない場合は、sweepは、メソッド内部の既知のpropertyまたはメソッド名を使用するたびに、現在のインスタンスのpropertyまたはメソッドを参照すると仮定します.この仮定は,カウンタ内部で3つの例示的な方法countを用いたことを実証した.
    このルールの典型的な例外の1つは、パラメータ名がインスタンスメソッドでインスタンスプロパティ名と同じ場合に発生します.この場合、パラメータ名を取得してからpropertyをより限られた方法で参照する必要があります.属性selfを使用して、パラメータ名とプログラム名を区別します.
    struct Point {
        var x = 0.0, y = 0.0
        func isToTheRightOf(x: Double) -> Bool {
            return self.x > x
        }
    }
    let somePoint = Point(x: 4.0, y: 5.0)
    if somePoint.isToTheRightOf(x: 1.0) {
        print("This point is to the right of the line where x == 1.0")
    }
    // true ! 
    // Prints "This point is to the right of the line where x == 1.0"
    self接頭辞がない場合、swiftはxの2つの使用法をパラメータとして使用します.

    Within Instanceメソッドから値タイプを変更(インスタンスメソッドで値タイプを変更)


    値のタイプは、構造体と列挙型です.デフォルトでは、値タイプのプロパティはインスタンスメソッド内では変更できません.
    特定のメソッド内で構造体または列挙型のpropertyを変更する必要がある場合は、そのメソッドの動作を変更できます.次に、メソッド内でPropertyを変更し、変更はメソッドの終了時に元の構造体に書き込まれます.メソッドはまた、暗黙的に新しいインスタンスをselfPropertyに割り当てることができ、メソッドが終了すると、新しいインスタンスが既存のインスタンスに置き換えられる.mutating上記の操作は、キーワードを使用して行うことができる.
    struct Point {
        var x = 0.0, y = 0.0
        mutating func moveBy(x deltaX: Double, y deltaY: Double) {
            x += deltaX
            y += deltaY
        }
    }
    var somePoint = Point(x: 1.0, y: 1.0)
    somePoint.moveBy(x: 2.0, y: 3.0)
    print("The point is now at (\(somePoint.x), \(somePoint.y))")
    // Prints "The point is now at (3.0, 4.0)"
    
    // let으로 정의하면 에러가 발생한다.
    let fixedPoint = Point(x: 3.0, y: 3.0)
    fixedPoint.moveBy(x: 2.0, y: 3.0)
    // this will report an error
    上のmoveByは、実際の値を返すのではなく、呼び出し時に実際の値を変更します.
    構造体タイプ定数は、上記の方法を呼び出すことはできません.このプロパティは、変数属性が「」であっても変更できないためです.

    Self Within aマルチステーションメソッドへの割当て(変更メソッド内で自動割当て)


    変更方法は、selfpropertyをすべての新しいインスタンスに暗黙的に割り当てることができる.次のように記述できます.
    struct Point {
        var x = 0.0, y = 0.0
        mutating func moveBy(x deltaX: Double, y deltaY: Double) {
            self = Point(x: x + deltaX, y: y + deltaY)
        }
    }
    上記の方法では、新しいx値とy値に設定された構造体が作成されます.このメソッドの結果は、前のメソッドを呼び出した結果と同じです.
    列挙型の変更方法は、他の暗黙的selfパラメータが同じ列挙型の場合に使用することができる.
    enum TriStateSwitch {
        case off, low, high
        mutating func next() {
            switch self {
            case .off:
                self = .low
            case .low:
                self = .high
            case .high:
                self = .off
            }
        }
    }
    var ovenLight = TriStateSwitch.low
    ovenLight.next()
    // ovenLight is now equal to .high
    ovenLight.next()
    // ovenLight is now equal to .off
    3つの異なる例で状態を表す.

    タイプメソッド(タイプメソッド)


    上記のインスタンスメソッドは、特定のタイプのインスタンスで呼び出されるメソッドです.タイプが自分で呼び出す方法を定義することもできます.この方法はタイプメソッドと呼ばれます.staticキーワードは、関数の前に記述することによって表される.クラスはキーワードclassで置き換えることができ、サブクラスはこの方法の親クラスの実装を上書きすることができる.
    NOTE
    Objective-Cでは、クラスのタイプレベルメソッドしか定義できません.swiftでは、すべてのクラス、構造体、および列挙型で定義できます.各タイプのメソッドは、サポートされるタイプとして明確に指定されています.
    タイプメソッドは、インスタンスメソッドなどのポイント構文として呼び出されます.ただし、タイプインスタンスでは呼び出せないタイプメソッドは、タイプから呼び出すことができます.
    class SomeClass {
        class func someTypeMethod() {
            // type method implementation goes here
        }
    }
    SomeClass.someTypeMethod()
    タイプメソッドでは、暗黙的selfpropertyは、タイプ自体を表し、そのタイプのインスタンスではありません.これは、selfを使用してタイプおよびタイプメソッドパラメータを明確にし、インスタンスおよびインスタンスメソッドパラメータを明確にすることに相当する.
    より一般的には、タイプメソッド本明細書で使用される未規定のメソッドおよびproperty名は、他のタイプレベルのメソッドおよびpropertyを参照する.タイプメソッドは、タイプ名の前にタイプ名を付けることなく、他のタイプメソッドを呼び出すことができます.同様に、構造体および列挙型のタイプメソッドは、名前のないタイプpropertyの名前を使用して、タイプpropertyにアクセスすることができる.
    ゲームレベルとフェーズの構造体の例を追跡します.1つのデバイスは、複数のプレーヤーの情報を含んでもよい.
    struct LevelTracker {
        static var highestUnlockedLevel = 1
        var currentLevel = 1
    
        static func unlock(_ level: Int) {
            if level > highestUnlockedLevel { highestUnlockedLevel = level }
        }
    
        static func isUnlocked(_ level: Int) -> Bool {
            return level <= highestUnlockedLevel
        }
    
        @discardableResult // 결과를 사용하지 않고 호출될때 경고를 무시한다.
        mutating func advance(to level: Int) -> Bool {
            if LevelTracker.isUnlocked(level) {
                currentLevel = level
                return true
            } else {
                return false
            }
        }
    }
    この構造は、すべてのプレイヤーがロックを解除する最高レベルを追跡します.この値は、highestUnlockedLevelというタイプのpropertyに格納されます.
    上記の値に示すように、2種類の関数も定義されています.最初の関数は、新しいレベルが解放されるたびに値を更新します.2番目の関数は、特定のステップが解決された場合trueを返します.
    さらにこのタイプのプログラムとタイプメソッドを加えて、各プレイヤーのゲームの進捗状況を追跡します.currentLevelと呼ばれるインスタンスプロセスを使用して、プレイヤーの現在の進捗状況を追跡します.currentLevelPropertyの管理を支援するために、advance(to:)と呼ばれるインスタンスメソッドを定義します.このメソッドは、現在のステップを更新する前に、新しいレベルが無効になっているかどうかを決定します.上記のメソッドは、現在のステップで実際に設定できるかどうかを示すブール値を返します.
    class Player {
        var tracker = LevelTracker()
        let playerName: String
        func complete(level: Int) {
            LevelTracker.unlock(level + 1)
            tracker.advance(to: level + 1)
        }
        init(name: String) {
            playerName = name
        }
    }
    プレイヤークラスは、プレイヤーの進捗状況を追跡するためにレベルtrackerの新しいインスタンスを作成します.complete(level:)メソッドは、ユーザが特定のステップを完了したときに呼び出される.この方法では、すべてのプレイヤーの次のステップを解放し、プレイヤーの進捗状況を更新して次のステップに進みます.
    var player = Player(name: "Argyrios")
    player.complete(level: 1)
    print("highest unlocked level is now \(LevelTracker.highestUnlockedLevel)")
    // Prints "highest unlocked level is now 2"
    2番目のプレイヤーを作成し、まだリリースされていないレベルに移動しようとすると、この試みは失敗します.
    player = Player(name: "Beto")
    if player.tracker.advance(to: 6) {
        print("player is now on level 6")
    } else {
        print("level 6 hasn't yet been unlocked")
    }
    // Prints "level 6 hasn't yet been unlocked"