Swift構文のまとめ-属性、メソッド、下付き

10585 ワード

1.属性
プロパティは、値を特定のクラス、構造、または列挙に関連付けます.属性は、インスタンスの一部として定数または変数を格納し、属性計算(格納ではない)の値を計算します.計算プロパティは、クラス、構造体、および列挙に使用できます.記憶プロパティは、クラスおよび構造体にのみ使用できます.
ストレージ属性と計算属性は、通常、特定のタイプのインスタンスに関連付けられます.ただし、属性はタイプ自体に直接作用することもできます.この属性をタイプ属性と呼びます.
1.1ストレージ属性
簡単に言えば、1つのストレージ属性は、特定のクラスまたは構造体インスタンスに格納される定数または変数です.ストレージ属性は、変数ストレージ属性(キーワードvarで定義)でも定数ストレージ属性(キーワードletで定義)でもよい.
1.1.1定数構造体の記憶属性
構造体のインスタンスを作成して定数に値を割り当てると、そのインスタンスのプロパティは変更できません.変数として宣言されたプロパティがあっても、変更できません.
let rangeOfFourItems = FixedLengthRange(firstValue: 0, length: 4)
//  0,1,2,3
rangeOfFourItems.firstValue = 6
//   firstValue  , 

1.1.2遅延ストレージ属性
遅延ストレージ属性とは、最初に呼び出されたときにその初期値が計算される属性です.プロパティ宣言の前にlazyを使用して、遅延ストレージプロパティを表示します.
1.インスタンス構築が完了してから、属性の初期値が得られる可能性があるため、遅延記憶属性を変数として宣言する必要があります(varキーワードを使用します).定数属性は、構築プロセスが完了する前に初期値が必要であるため、遅延属性として宣言できません.
  • lazyとマークされた属性が初期化されていないときに同時に複数のスレッドにアクセスされる場合、その属性が一度だけ初期化されることは保証されません.

  • 1.1.3ストレージ属性とインスタンス変数
    Swiftの属性には対応するインスタンス変数がなく,属性のバックエンドストレージにも直接アクセスできない.これにより、異なるシーンでのアクセス方法の問題を回避し、プロパティの定義を文に簡略化できます.アトリビュートのすべての情報(名前、タイプ、メモリ管理フィーチャーを含む)は、ユニークな場所(タイプ定義)で定義されます.
    1.2計算属性
    クラス、構造体、列挙は、ストレージ属性に加えて計算属性を定義できます.計算プロパティは、値を直接格納するのではなく、getterとオプションのsetterを提供して、他のプロパティまたは変数の値を間接的に取得および設定します.
    struct Point {
        var x = 0.0, y = 0.0
    }
    struct Size {
        var width = 0.0, height = 0.0
    }
    struct Rect {
        var origin = Point()
        var size = Size()
        var center: Point {
            get {
                let centerX = origin.x + (size.width / 2)
                let centerY = origin.y + (size.height / 2)
                return Point(x: centerX, y: centerY)
            }
            set {
                origin.x = newCenter.x - (size.width / 2)
                origin.y = newCenter.y - (size.height / 2)
            }
        }
    }
    

    1.2.1読取り専用計算属性
    getterにsetterがない計算属性だけが読み取り専用計算属性です.読み取り専用計算プロパティは、ポイント演算子でアクセスできる値を常に返しますが、新しい値を設定することはできません.
    注意varキーを使用して、値が固定されていないため、読み取り専用計算プロパティを含む計算プロパティを定義する必要があります.letキーワードは定数属性を宣言するためにのみ使用され、初期化後に変更できない値を表します.
    読み取り専用計算プロパティの宣言では、getキーとカッコを削除できます.
    struct Cuboid {
    var width = 0.0, height = 0.0, depth = 0.0
    var volume: Double {
        return width * height * depth
    }
    }
    let fourByFiveByTwo = Cuboid(width: 4.0, height: 5.0, depth: 2.0)
    print("the volume of fourByFiveByTwo is \(fourByFiveByTwo.volume)")
    //   "the volume of fourByFiveByTwo is 40.0"
    

    1.3属性オブザーバ
    アトリビュートオブザーバは、アトリビュート値の変化を監視し、応答します.アトリビュート値が設定されるたびにアトリビュートオブザーバが呼び出されます.新しい値と現在の値が同じ場合でも例外ではありません.
    属性には、•willSetが新しい値が設定される前に呼び出される•didSetが新しい値が設定された直後に呼び出される1つまたはすべてのオブジェクトを追加できます.
    class StepCounter {
    var totalSteps: Int = 0 {
    willSet(newTotalSteps) {
    print("About to set totalSteps to \(newTotalSteps)")
    }
    didSet {
    if totalSteps > oldValue {
    print("Added \(totalSteps - oldValue) steps")
    }
    }
    }
    }
    let stepCounter = StepCounter()
    stepCounter.totalSteps = 200
    // About to set totalSteps to 200
    // Added 200 steps
    stepCounter.totalSteps = 360
    // About to set totalSteps to 360
    // Added 160 steps
    stepCounter.totalSteps = 896
    // About to set totalSteps to 896
    // Added 536 steps
    

    1.4グローバル変数とローカル変数
    グローバル変数は、関数、メソッド、閉パッケージ、または任意のタイプ以外で定義された変数です.ローカル変数は、関数、メソッド、または閉パッケージの内部で定義された変数です.
    注意<1>グローバルの定数または変数は、遅延記憶属性(ページ0)と同様に遅延計算されます.異なる点は、グローバルの定数または変数にlazy修飾子をマークする必要がないことです.<2>ローカル範囲の定数または変数は、計算を遅延しません.
    1.5タイプ属性
    タイプ自体のプロパティを定義できます.このタイプのインスタンスがいくつ作成されても、これらのプロパティは唯一です.この属性がタイプ属性です.
    タイプ属性は、すべてのインスタンスが使用できる定数(C言語の静的定数のような)や、すべてのインスタンスがアクセスできる変数(C言語の静的変数のような)など、すべてのインスタンスが共有するデータを定義するために使用されます.
    注意<1>インスタンスのストレージ属性とは異なり、タイプ自体にコンストラクタがないため、初期化中にコンストラクタを使用してタイプ属性に値を割り当てることはできません.<2>ストレージタイプのプロパティは、最初にアクセスしたときにのみ初期化される遅延初期化です.複数のスレッドに同時にアクセスされても、lazy修飾子を使用する必要がなく、一度だけ初期化されることを保証します.
    1.5.1型属性構文
    Swiftでは、タイププロパティはタイプ定義の一部としてタイプの最外層のカッコ内に書かれているため、その役割範囲もタイプがサポートする範囲内にあります.キーワードstaticを使用してタイププロパティを定義します.
    struct SomeStructure {
        static var storedTypeProperty = "Some value."
        static var computedTypeProperty: Int {
            return 1
        }
    }
    enum SomeEnumeration {
        static var storedTypeProperty = "Some value."
        static var computedTypeProperty: Int {
            return 6
        }
    }
    class SomeClass {
    static var storedTypeProperty = "Some value."
    static var computedTypeProperty: Int {
        return 27
    }
    class var overrideableComputedTypeProperty: Int {
        return 107
    }
    }
    

    1.5.2タイプ属性の値の取得と設定
    インスタンス属性と同様に、タイプ属性もポイント演算子でアクセスします.ただし、タイププロパティは、インスタンスではなくタイプ自体でアクセスします.
    print(SomeStructure.storedTypeProperty)
    //   "Some value."
    SomeStructure.storedTypeProperty = "Another value."
    print(SomeStructure.storedTypeProperty)
    //   "Another value.”
    print(SomeEnumeration.computedTypeProperty)
    //   "6"
    print(SomeClass.computedTypeProperty)
    //   "27"
    

    2.0インスタンスメソッド(Instance Methods)
    インスタンス・メソッドは、特定のクラス、構造体、または列挙タイプのインスタンスに属するメソッドです.インスタンス・メソッドは、インスタンスのプロパティにアクセスおよび変更する方法またはインスタンスの目的に関連する機能を提供し、インスタンスの機能をサポートします.
    インスタンスメソッドは、その属するタイプの前後のカッコの間に書きます.インスタンス・メソッドは、その属するタイプの他のすべてのインスタンス・メソッドおよびプロパティに暗黙的にアクセスできます.インスタンスメソッドは、その属するクラスの特定のインスタンスによってのみ呼び出されます.インスタンスメソッドは、既存のインスタンスから離れて呼び出されません.
    class Counter {
        var count = 0
        func increment() {
            count += 1
        }
        func increment(by amount: Int) {
            count += amount
        }
        func reset() {
            count = 0
        }
    }
    

    2.1 self属性
    タイプの各インスタンスにはselfという暗黙的な属性があり、selfはインスタンス自体に完全に等しい.この隠しselfプロパティを使用して、インスタンスのインスタンスメソッドで現在のインスタンスを参照できます.
    func increment() {
        self.count += 1
    }
    

    関数内にクラス変数と同じ名前の変数が存在する場合、パラメータ名は優先権を有し、属性を参照する際により厳密な方法を使用する必要があります.この場合、selfプロパティを使用してパラメータ名とプロパティ名を区別できます.
    //self  x  x  :
    struct Point {
        var x = 0.0, y = 0.0
        func isToTheRightOfX(x: Double) -> Bool {
            return self.x > x
        }
    }
    let somePoint = Point(x: 4.0, y: 5.0)
    if somePoint.isToTheRightOfX(1.0) {
        print("This point is to the right of the line where x == 1.0")
    }
    //   "This point is to the right of the line where x == 1.0"
    

    2.2インスタンスメソッドでの値タイプの変更
    構造体と列挙は値タイプです.デフォルトでは、値タイプのプロパティはインスタンスメソッドで変更できません.
    しかし、特定の方法で構造体または列挙の属性を変更する必要がある場合は、この方法のために可変(mutating)動作を選択し、その方法の内部から属性を変更することができます.このメソッドの変更は、メソッドの実行が終了すると元の構造に戻ります.メソッドは、メソッドの終了時に既存のインスタンスを置き換える、隠されたselfプロパティに新しいインスタンスを与えることもできます.
    可変メソッドを使用するには、メソッドのfuncキーワードの前にキーワードmutatingを配置します.
    struct Point {
        var x = 0.0, y = 0.0
        mutating func moveByX(deltaX: Double, y deltaY: Double) {
            x += deltaX
            y += deltaY
        }
    }
    var somePoint = Point(x: 1.0, y: 1.0)
    somePoint.moveByX(2.0, y: 3.0)
    print("The point is now at (\(somePoint.x), \(somePoint.y))")
    //   "The point is now at (3.0, 4.0)"
    

    2.3可変メソッドでselfに値を割り当てる
    可変メソッドは、隠し属性selfに新しいインスタンスを割り当てることができます.
    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)
        }
    }
    

    列挙の可変メソッドは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   .High
    ovenLight.next()
    // ovenLight   .Off
    

    2.4タイプメソッド
    インスタンスメソッドは、あるタイプのインスタンスによって呼び出されるメソッドです.タイプ自体で呼び出されるメソッドを定義することもできます.このメソッドをタイプメソッドと呼びます.メソッドのfuncキーワードの前にキーワードstaticを付けてタイプメソッドを指定します.クラスはまた、キーワードclassを使用して、サブクラスが親クラスを書き換える方法を実装することもできます.
    Objective-Cでは、Objective-Cのクラスタイプ(classes)のタイプメソッド(type-level methods)しか定義できません.Swiftでは、すべてのクラス、構造体、列挙のタイプメソッドを定義できます.各タイプのメソッドは、サポートされているタイプによって明示的に含まれます.
    タイプメソッドは、インスタンスメソッドと同様にポイント構文で呼び出されます.ただし、インスタンスで呼び出すのではなく、タイプでこのメソッドを呼び出します.
    class SomeClass {
        class func someTypeMethod() {
            //  
        }
    }
    SomeClass.someTypeMethod()
    

    3.下付き
    下のラベルは、クラス、構造体、列挙で定義できます.これは、コレクション、リスト、またはシーケンスの要素にアクセスするショートカットです.対応するアクセスメソッドを呼び出すことなく、下付きインデックスを使用して値を設定および取得できます.
    3.1下書き構文
    下の記号を使用すると、インスタンス名の後ろのカッコに1つ以上のインデックス値を入力することで、インスタンスにアクセスできます.構文は、インスタンスメソッド構文と計算型属性構文の混合に似ています.インスタンスの定義方法と同様に、subscriptキーワードを使用して、1つ以上の入力パラメータと戻りタイプを指定するように定義します.インスタンスメソッドとは異なり、下付き文字は読み書きまたは読み取り専用に設定できます.この動作はgetterとsetterによって実現され、計算型属性に似ています.
    struct TimesTable {
        let multiplier: Int
        subscript(index: Int) -> Int {
            return multiplier * index
        }
    }
    let threeTimesTable = TimesTable(multiplier: 3)
    print("six times three is \(threeTimesTable[6])")
    //   "six times three is 18"
    

    例えば、上述したthreeTimesTable[6].この文は、3の乗算テーブルの6番目の要素をクエリーし、3の6倍の18を返します.
    なお、TimesTableの例は一定の数学式に基づいており、threeTimesTable[someIndex]を付与する操作は適切ではないため、下付き文字は読み取り専用と定義されている.
    3.2下書きの使い方
    下付き文字の正確な意味は、シーンを使用することによって異なります.下付き文字は、通常、アクセス・セット、リスト、またはシーケンスの要素のショートカットとして使用されます.
    3.3下付きオプション
    下の記号は任意の数のパラメータを受け入れることができ、これらのパラメータは任意のタイプであってもよい.下付き文字の戻り値は、任意のタイプであってもよい.下付き文字は変数パラメータと可変パラメータを使用できますが、入出力パラメータは使用できません.パラメータにデフォルト値を設定することはできません.
    1つのクラスまたは構造体は、自身の必要に応じて複数のダウンスケール実装を提供することができ、ダウンスケールを使用すると、パラメータの数とタイプによって区別され、適切なダウンスケールが自動的に一致します.これがダウンスケールの再ロードです.
    struct Matrix {
        let rows: Int, columns: Int
        var grid: [Double]
        init(rows: Int, columns: Int) {
            self.rows = rows
            self.columns = columns
            grid = Array(count: rows * columns, repeatedValue: 0.0)
        }
        func indexIsValidForRow(row: Int, column: Int) -> Bool {
            return row >= 0 && row < rows && column >= 0 && column < columns
        }
        subscript(row: Int, column: Int) -> Double {
            get {
                assert(indexIsValidForRow(row, column: column), "Index out of range")
                return grid[(row * columns) + column]
            }
            set {
                assert(indexIsValidForRow(row, column: column), "Index out of range")
                grid[(row * columns) + column] = newValue
            }
        }
    }
    

    適切なrowとcolumnの数を入力することで、新しいMatrixインスタンスを構築します.
    var matrix = Matrix(rows: 2, columns: 2)
    

    rowとcolumnの値を下付き文字に入力してマトリクスの値を設定し、下付き文字の入力はカンマで区切られます.
    matrix[0, 1] = 1.5
    matrix[1, 0] = 3.2
    

    上の2つの文は、下付きのsetterを呼び出して、マトリクスの右上隅位置(すなわちrowが0、columnが1の位置)の値を1.5に設定し、マトリクスの左下隅位置(すなわちrowが1、columnが0の位置)の値を3.2に設定します.