LoginSignup
3
1

More than 5 years have passed since last update.

Elixirの静的型チェックの確認 - リテラル型

Posted at

結論。
Elixirの静的型チェックで、文字列を指定してすることはできない。
長さぐらいは可能。
同様のことをしたいならatomを使う。
ちゃんと確認してないが、Erlangでも同じだろう。

具体的に

便宜上Flowと比較する。

Flowで以下のような型をElixirで表現するにはどうするか。

// @flow
function sample(hoge_or_goro: "hoge" | "goro") {}

sample("hoge")    // Ok
sample("hogehoge") // Error
sample("goro")    // Ok

関数sampleは "hoge""goro"という値しか受け取らないようにしたい。

Elixirでは以下のようにするのが良さそう

defmodule Sample do
  @spec sample(:hoge | :goro) :: nil
  def sample(hoge_or_goro), do: nil

  def test(:hoge), do: nil  # Ok
  def test2(:hogehoge), do: nil # Error
  def test3(:goro), do: nil # Ok
  def test4(:mogu), do: nil # Error
end

bitstringを使う場合はせいぜい長さを指定するぐらいはできる

defmodule Sample do
  @spec sample(<<_::32>) :: nil
  def sample(hoge_or_goro), do: nil

  def test("hoge"), do: nil  # Ok
  def test2("hogehoge"), do: nil # Error
  def test3("goro"), do: nil # Ok
  def test4("mogu"), do: nil # Ok (Errorにしたい)
end

@spec sample(<<"hoge"::32>> :: nilみたいにかきたいがコンパイルできない。

数値リテラル

数値は可能。
まずは、Flowの場合の例

// @flow
function sample(one_or_three: 1 | 3) {}

sample(1) // Ok
sample(2) // Error
sample(3) // Ok
sample(1+2) // Error (Okにしたくはある)
defmodule Sample do
  @spec sample(1 | 3) :: nil
  def sample(one_or_three), do: nil

  def test(), do: hoge(1)  # Ok
  def test2(), do: hoge(2) # Error
  def test3(), do: hoge(3) # Ok
  def test4(), do: hoge(1+2) # Ok (やったぜ)
end

参考

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