☝️

RustでInt(1)とAdd { id: 1 }の使い分け

2022/05/09に公開

Rustでenumを作り、あるVariantがただ1つの値を中身に持ちたい時、2つの選択肢がある。

  1. Int(1)のようにtuple variantとする
  2. Add { name: "ryo" }のようにstruct variantとする

これまでは自分は何も考えず常に1を選んでいたのだが、2を選ぶべき時が結構あることに気づいた。
それはvariantの名前と中身に保つ値の意味が等しくない時だ。つまり次のように使い分ける。

  • variant nameがそのまま中身の意味を示しているなら、tuple variantを使う
  • variant nameとは別の意味の値が中に入るのであれば、struct variantを使う

こうするべき強い理由を説明する。
Str("a")のようなtuple variantは実質Str { 0: "a" }と解釈できる。0は0番目という意味なので、0番目ということしか説明せず、内容についてはなにも語らない。
これは変数名がある言語で意味のある値に対してabxといった意味のない変数名を使うのに等しく、リーダブルなコードではない。

これまで自分が常に1を選んでしまっていたのは、自分が仕様に詳しいため、variant名が与えられた時にその中身が簡単にイメージできてしまっていたからだ。人は簡単にイメージできてしまうところには、コメントを書くなどの分かりやすく書く意識が薄れてしまう。

ちなみにInt { value: 0 }Int { int: 0 }は冗長でありこれはこれで混乱を生むためリーダブルでない。

また、今回はenumで説明したが、structを定義するNewTypeパターンの時にもこの話が通用するはずである。

Rust API Guidelinesにはないっぽい?Gitterで投げてみることにする。

Discussion