✏️

演算子をランダムで与えたい場合にEnumを利用する

2022/06/05に公開

と言っても直接演算子を渡せるわけではありません。 あくまで演算子を限定する目的でenumを利用し、その上でランダムに与えるのにInt型のようなプリミティブな値で無理に作るようなことはしないためにはどうするかという記事です。(もっとも直接演算子を渡せるような書き方もあるのかもしれません)

参考にさせていただいたのは次の記事です。
https://qiita.com/noppefoxwolf/items/d216479dcc66431d7136
ただし、以前のSwiftのバージョンであった頃の記述であるため、現在は書き方が異なります。

変更でどのように変わったかに関しては、次の記事が参考になります。
https://dev.classmethod.jp/articles/wwdc18-random-number-generator/


2022.6.9 追記

(もっとも直接演算子を渡せるような書き方もあるのかもしれません)

ありました、クロージャを利用することで演算子を直接渡せることを思い出しました。
https://zenn.dev/toaster/articles/45c4403846f707


演算子をランダムで渡すことについて

本題の演算子をランダムで渡すことについて考えてみます。とりあえず、無理くり渡せるようにと考えると素直に次のようなコードは思いつきそうです。

enum Operation: Int {
    case plus = 0
    case minus
}

let operation = Operation.init(rawValue:(Int.random(in: 0...1)))

ただ、これはenumに列挙するケースの数が増えたら対応できなくなることに加えて、たいがい始まりは0ではありますが根本的には開発者がそのように理解しているから書けるのだという前提があります。私はこういうの書きがちなのですが、結構無理くり感があります。

CaseIterableプロトコルとコレクション型のメソッドとして与えられるrandomeElement()を利用することで、無理のないランダムな与え方を実現できます。

enum Operation: CaseIterable {
    case plus
    case minus
    
    static var random: Self {
        let randomeCase = Self.allCases.randomElement()
        return randomeCase!
    }
}

let operation = Operation.random

CaseIterableに準拠することで、配列であるプロパティのallCaseを利用することができます。そして、配列はコレクション型であることから要素をランダムで返してくれるrandomElement()が使えます。このようにすると要素が増えたとしても書き換えることなく、対応が可能となります。

Discussion