ストアドプロパティに加えて、クラス、構造体および列挙型に、実際には値を保管しないコンピューテッドプロパティを定義することができます。保管する代わりに、他のプロパティの値を間接的に取り出す 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(newCenter) {
            origin.x = newCenter.x - (size.width / 2)
            origin.y = newCenter.y - (size.height / 2)
        }
    }
}
var square = Rect(origin: Point(x: 0.0, y: 0.0),
                  size: Size(width: 10.0, height: 10.0))
let initialSquareCenter = square.center
square.center = Point(x: 15.0, y: 15.0)
print("square.origin is now at (\(square.origin.x), \(square.origin.y))")
// "square.origin is now at (10.0, 10.0)" と出力

この例では、幾何学的図形を扱う 3 つの構造体を定義しています。

  • Point は、(x, y) 座標です。
  • Size は、width と height です。
  • Rect は、長方形の原点とサイズを定義します。

構造体 Rect は、コンピューテッドプロパティ center も提供しています。Rect の現在の中心位置は、常に origin と size で特定され、中心位置を Point 値として保管する必要はありません。 代わりに、ストアドプロパティのように長方形の center を扱えるよう、Rect はコンピューテッド変数 center の getter と setter を定義しています。

前述の例では、Rect の変数 square を生成しています。変数 square は、原点 (0, 0) で初期化され、幅と高さは 10 です。この square は、下の図では青い正方形で表されています。

square 変数の center プロパティは、ドットシンタックス (square.center) でアクセスされ、現在のプロパティ値を取り出すために center の getter が呼び出されます。現在の値を返すことよりも、getter は実際には正方形の中心を表す新しい Point を算出して返します。上で見たように、getter は正確に中心位置の (5, 5) を返しています。

そして、center プロパティに新しい値 (15, 15) が設定され、正方形は上と右に移動し、下の図ではオレンジの正方形で新しい位置に表示されています。center プロパティに設定すると、center の setter が呼び出され、ストアドプロパティ origin の x と y の値を変更し、正方形を新しい位置に移動します。

image: computedProperties_2x

簡略 setter 宣言

コンピューテッドプロパティの setter に、設定される新しい値の名前を定義していない場合、デフォルトの名前 newValue となります。次は構造体 Rect の別バージョンで、この簡略表記を活用しています。

struct AlternativeRect {
    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 = newValue.x - (size.width / 2)
            origin.y = newValue.y - (size.height / 2)
        }
    }
}

読み取り専用のコンピューテッドプロパティ

setter が無く、getter のみのコンピューテッドプロパティは、読み取り専用のコンピューテッドプロパティです。読み取り専用のコンピューテッドプロパティは、常に値を返し、ドットシンタックスでアクセスでき、異なる値を設定できません。

NOTE
コンピューテッドプロパティの値は固定でないため、読み取り専用のコンピューテッドプロパティを含め、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" と出力

この例では、3D の直方体を widthheightdepth プロパティで表す構造体 Cuboid を定義しています。この構造体には、読み取り専用のコンピューテッドプロパティ volume もあり、直方体の現在の容積を算出して返します。特定の volume 値に使われる widthheightdepth の値についてあいまいになるため、volume を設定できるようにするのは意味をなしません。それでもやはり、外部のユーザが現在の算出容積値を知ることができるように、Cuboid に読み取り専用のコンピューテッドプロパティを持たせることは有益です。


Portions of this page are translations based on work created and shared by Apple and used according to terms described in the Creative Commons Attribution 4.0 International License.