この記事は Xcode6 beta4 を元に記述しています。

Swift の配列は mutable か immutable

Swift では配列を mutable/immutable の区別なく定義することができるようになりました。

1
2
3
var numbers = [1, 2, 3]
numbers[0] = 0
println(numbers)    // [0, 2, 3]

let で定義すると immutablevar で定義すると mutable になり、配列の代入はすべてコピーで行われるようになっています。

Force UnWrapping 型!

で、ハマったのが次のようなコードです。

1
2
var numbers: [Int]! = [1, 2, 3]
numbers[0] = 0    // error: '@lvalue $T7' is not identical to 'Int'

Force Unwrapping 型とでも言うんでしょうかね?変数に必ず値が入ってることを保証するために ! が付いた型です。 この型で定義した配列には、値の追加や変更ができなくなっています。。

これで何が困るかというと、UIKit 使って UIViewController のサブクラスにプロパティを定義する際に 初期化を viewDidLoad で行う時には、! をつけないと initializer が必要になってしまうので、プロパティの定義には ! を付けていました。

そうすると、mutable で扱いたかったプロパティなのに、変更できないという問題にぶち当たったわけです。。どうすんだこれ。。。

コンパイルエラーの例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class MyViewController: UIViewController {

  var numbers: [Int]!

  override func viewDidLoad() {
    super.viewDidLoad()

    self.numbers = [1, 2, 3]
  }


  func myFunc() {
    self.numbers[0] = 0     // コンパイルエラー
  }
}

うまくいく例

対応としては、一旦変数で受けて、変更後に元に戻すっていうので何とかなりますが、コンパイラの方でなんとかならんもんですかね。。

1
2
3
4
5
  func myFunc() {
    var nums: [Int] = self.numbers
    nums[0] = 0
    self.numbers = nums
  }