Erlang 如何为单字母ASCII字符串(值0-127)键入规范?
同样地,如何为“单个”UTF8字符指定typespec 在类型定义中,我可以使用泛型“any string”或“any utf8 string” 有什么方法可以将typespec转换成这样的位模式吗?仅基于二进制的事实。即使你们可以定义这样的规格,我也不相信透析器足够复杂,可以在这样的匹配中发现故障。您只需要在运行时使用保护和模式匹配来实现此类行为,如:Erlang 如何为单字母ASCII字符串(值0-127)键入规范?,erlang,elixir,dialyzer,Erlang,Elixir,Dialyzer,同样地,如何为“单个”UTF8字符指定typespec 在类型定义中,我可以使用泛型“any string”或“any utf8 string” 有什么方法可以将typespec转换成这样的位模式吗?仅基于二进制的事实。即使你们可以定义这样的规格,我也不相信透析器足够复杂,可以在这样的匹配中发现故障。您只需要在运行时使用保护和模式匹配来实现此类行为,如: def unicode?(<<0::size(1), a::size(7)>>), do: true def unic
def unicode?(<<0::size(1), a::size(7)>>), do: true
def unicode?(<<6::3, _::5, 2::2, _::6>>), do: true
def unicode?(<<14::4, _::4, 2::2, _::6, 2::2, _::6>>), do: true
def unicode?(<<30::5, _::3, 2::2, _::6, 2::2, _::6, 2::2, _::6>>), do: true
def unicode?(str) when is_binary(str), do: false
我要在这个问题上加上Erlang标签(还有透析器标签),因为我认为这更多的是透析器的问题,而不是长生不老药的问题。我认为这是不可能的。我最好的猜测是指定一个范围
0..127::8
,但我认为它不会起作用。根据我在透析器文档中看到的情况,似乎char()
类型规范最接近您想要的,但仍然允许0..255(而不仅仅是0..127范围)。@OnorioCatenacci。我真的很想匹配一个“单个”UTF8码点,它可以从8位到32位,有特定的位模式,所以char()不行。好的,我们可能还需要更多的上下文来确定为什么一个简单的验证函数,可以使用模式匹配,我们知道它是有效的,不能满足您的目的。如何才能类型规格这一个utf8字符有助于类型检查你正在执行?据我所知,Erlang和Elixir编译器不会观察到类型不匹配(除了您提供的编译错误之外),因此我假设类型检查用于您自己的内部检查。
@type tile :: <<0::1, _::7>>
@type tile :: <<0::1, _::7>> |
<<6::3, _::5, 2::2, _::6>> |
<<14::4, _::4, 2::2, _::6, 2::2, _::6>> |
<<30::5, _::3, 2::2, _::6, 2::2, _::6, 2::2, _::6>>
<<14::4, _::4, 2::2, _::6, 2::2, _::6>> = "○"
== Compilation error in file lib/board.ex ==
** (ArgumentError) argument error
(elixir) lib/kernel/typespec.ex:1000: Kernel.Typespec.typespec/3
(elixir) lib/kernel/typespec.ex:1127: anonymous fn/4 in Kernel.Typespec.typespec/3
(elixir) lib/enum.ex:1899: Enum."-reduce/3-lists^foldl/2-0-"/3
(elixir) lib/kernel/typespec.ex:1127: Kernel.Typespec.typespec/3
(elixir) lib/kernel/typespec.ex:828: anonymous fn/4 in Kernel.Typespec.typespec/3
(elixir) lib/enum.ex:1899: Enum."-reduce/3-lists^foldl/2-0-"/3
(elixir) lib/kernel/typespec.ex:828: Kernel.Typespec.typespec/3
(elixir) lib/kernel/typespec.ex:470: Kernel.Typespec.translate_type/3
def unicode?(<<0::size(1), a::size(7)>>), do: true
def unicode?(<<6::3, _::5, 2::2, _::6>>), do: true
def unicode?(<<14::4, _::4, 2::2, _::6, 2::2, _::6>>), do: true
def unicode?(<<30::5, _::3, 2::2, _::6, 2::2, _::6, 2::2, _::6>>), do: true
def unicode?(str) when is_binary(str), do: false
defguardp is_valid_utf_part(code) when code in 0b10000000..0b10111111
defguard is_unicode(<<ascii>>) when ascii in 0b0000000..0b01111111
defguard is_unicode(<<first, second>>)
when first in 0b11000000..0b11011111
and is_valid_utf_part(second)
defguard is_unicode(<<first, second, third>>)
when first in 0b11100000..0b11101111
and is_valid_utf_part(second)
and is_valid_utf_part(third)
defguard is_unicode(<<first, second, third, fourth>>)
when first in 0b11110000..0b11110111
and is_valid_utf_part(second)
and is_valid_utf_part(third)
and is_valid_utf_part(fourth)