LoginSignup
11
1

More than 5 years have passed since last update.

[Swift] EnumのAssociated Valueの定義を変更したらデグレった話

Last updated at Posted at 2018-12-10

はじめに

非常に便利なEnumのAssociatedValueですが、定義を変更する際には注意が必要です。
誰かが同じ過ちを繰り返さないよう、私が実際に起こしたデグレを紹介します。

変更前

例えば、以下のようなEnumがあったとします。

enum Hoge {
    case foo(value: Int)
    case bar(value: Int)
}

このEnumを、こんな感じで使っていたとすると、

let hoge = Hoge.bar(value: 10)
if case .bar(let value) = hoge {
    self.label.text = "Value = \(value)"
}

画面には以下のように表示されます。
修正前.png

変更後

ここで、barに対して何かしらの定義を追加したくなりました。

enum Hoge {
    case foo(value: Int)
    case bar(value: Int, value2: Int)
}

定義が追加されたことで、変数hogeを定義している箇所では、Missing argument for parameter 'value2' in callというコンパイルエラーが発生する為、以下のように変更を行います。

let hoge = Hoge.bar(value: 10, value2: 20)

しかし、実際にhogeが使われている箇所では、コンパイルエラーは発生しません。
Enumの変更前に記述したまま(以下の内容)でも何も怒られないのです。

if case .bar(let value) = hoge {
    self.label.text = "Value = \(value)"
}

実際に上記の状態で動かしてみると、画面には以下のように表示されます。
修正後.png
そうです。
case .bar(let value)valueには、(value: Int, value2: Int)のタプルが代入されてしまったのです。

まとめ

EnumのAssociatedValueの定義を変更した場合、それを使っている箇所ではエラーにならない為、注意が必要という内容でした。
※定義を減らす場合には、使っている箇所でもエラーになります。
例えば、bar(value: Int, value2: Int)からbar(value: Int)へ変更した場合、Tuple pattern has the wrong length for tuple type '(value: Int)'というエラーになります。

この件は『プログラムの修正を行う場合は、影響範囲を調査し、全ての箇所で動作を確認する。』という基本を改めて思い出させてくれる出来事でした。

11
1
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
11
1