LoginSignup
24
23

More than 5 years have passed since last update.

あなたは何個分かる? Swiftのsubscriptの使い方7選

Posted at

1. 普通のsubscriptの使い方

class MyClass {
    var values: [String] = []
    subscript(index: Int) -> String {
        get {
            return values[index]
        }
        set {
            values[index] = newValue
        }
    }
}
print(MyClass()[0])
MyClass()[0] = ""

struct/enumでも同様に使えます。

struct MyStruct {
    subscript(index: Int) -> String {
        get { return "" }
        set {}
    }
}

enum MyEnum {
    subscript(index: Int) -> String {
        get { return "" }
        set {}
    }
}

2. Readonlyなsubscript構文

setを書かなければreadonlyになります。

class MyClass {
    var values: [String] = []
    subscript(index: Int) -> String {
        get {
            return values[index]
        }
    }
}
print(MyClass()[0])
// MyClass()[0] = "" はエラー

プロパティーと同じようにgetだけならgetを省略できます。

class MyClass {
    var values: [String] = []
    subscript(index: Int) -> String {
        return values[index]
    }
}

setのみの構文は許可されていません。

// Subscript declarations must have a getterエラーになる
class MyClass {
    var values: [String] = []
    subscript(index: Int) -> String {
        set {
            values[index] = newValue
        }
    }
}

3. 複数のIndexを使ったsubscript構文

index1ですが複数持つことができます。

class MyClass {
    subscript(index1: Int, index2: Int) -> String {
        get {
            return ""
        }
        set {
        }
    }
}
print(MyClass()[0, 0])
MyClass()[0, 0] = ""

indexの型はInt以外も使えます。

class MyClass {
    subscript(index1: String, index2: String) -> String {
        get {
            return ""
        }
        set {
        }
    }
}
print(MyClass()["0", "0"])
MyClass()["0", "0"] = ""

4. 可変長なIndexを持つsubscript構文

subscriptですがIndexを可変長にする事もできます。

class MyClass {
    subscript(index: Int...) -> String {
        print(index.first)
        return ""
    }
}
print(MyClass()[0, 1, 2])

5. Indexにラベルを付ける

メソッドのようにラベルを付ける事もできます。

class MyClass {
    subscript(row row: Int, section section: Int) -> String {
        return ""
    }
}
print(MyClass()[row: 0, section: 0])

6. Void型を扱うsubscript構文

使いどころは思いつかないのですがVoidを扱う事もできます。
普通のメソッドと違ってVoidを返却してあげる必要があります。

class MyClass {
    subscript(index: Int) -> Void {
        return Void()
    }
    func method() -> Void {
    }
}
print(MyClass()[0])

7. autoclosureを使ったsubscript構文

これも実用性は低いのですがautoclosureと組み合わせる事もできるようです。

class MyClass {
    subscript(@autoclosure index: () -> Int) -> String {
        return ""
    }
}
print(MyClass()[0])

autoclosureというマニアックで少し面白い機能

できないこと

subscriptはメソッドと同じような事ができますが、一部使えない機能があります。

デフォルト引数

class MyClass {
    // Default argument is only permitted for a non-curried function parameter になる
    subscript(index: Int = 0) -> String {
        return ""
    }
}

inout構文

class MyClass {
    subscript(inout index: Int) -> String {
        return ""
    }
}

var int = 0
print(MyClass()[&int]) // '&' can only appear immediately in a call argument listエラーになる
24
23
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
24
23