r) protocol Enough not implemented for "string"
iex:3: Enough.impl_for!/1
iex:4: Enough.enough?/1
上面的 string 类型没有实现协议,所以不能使用。 我们在实际使用中也不会对没种类型都实现协议,为了避免出现异常,可以设置协议对所有类型的默认实现
defprotocol Enough do
@fallback_to_any true
def enough?(data)
end
defimpl Enough, for: Any do
def enough?(_), do: false
end
这样以后,如下使用就不会报错了
iex> Enough.enough?("string")
false
异常处理
自定义异常
自定义异常使用 defexception/1 函数,
iex> h(defexception)
The most common way to raise an exception is via raise/2:
┃ defmodule MyAppError do
┃ defexception [:message]
┃ end
┃
┃ value = [:hello]
┃
┃ raise MyAppError,
┃ message: "did not get what was expected, got: #{inspect value}"
In many cases it is more convenient to pass the expected value to raise/2 and
generate the message in the exception/1 callback:
┃ defmodule MyAppError do
┃ defexception [:message]
┃
┃ def exception(value) do
┃ msg = "did not get what was expected, got: #{inspect value}"
┃ %MyAppError{message: msg}
┃ end
┃ end
┃
┃ raise MyAppError, value
The example above shows the preferred strategy for customizing exception
messages.
异常的使用
elixir 虽然提供了 try/catch/rescue/after 的结构,但是尽量不要使用这种结构,使用这种异常处理方式,会影响现有程序的处理流程。 elixir 的很多函数都会返回错误信号,通过信号来处理错误是推荐的方式(类似golang的错误处理),比如如下示例:
iex> case File.read "hello" do
...> {:ok, body} -> IO.puts "got ok"
...> {:error, body} -> IO.puts "got error"
...> end
列表速构
速构的意思也就是从一个列表方便的生成另一个列表。
生成器
iex> l = for n <- [1, 2, 4], do: n*n
[1, 4, 16]
iex> l
[1, 4, 16]
过滤器
iex> require Integer
iex> for n <- 1..4, Integer.is_odd(n), do: n*n
[1, 9]
二进制转化为元组
iex> pixels = <<213, 45, 132, 64, 76, 32, 76, 0, 0, 234, 32, 15>>
<<213, 45, 132, 64, 76, 32, 76, 0, 0, 234, 32, 15>>
iex> for <<r::8, g::8, b::8 <- pixels>>, do: {r, g, b}
[{213, 45, 132}, {64, 76, 32}, {76, 0, 0}, {234, 32, 15}]
- into
删除空格
iex> for <<c <- " hello world ">>, c != ?\s, into: "", do: <<c>>
"helloworld"
sigils(魔法印)
sigils 也就是对已有的变量或者常量做一些标记,使之变为其他的东西。 sigils 的目的就是提高 elixir 语言的扩展性。
正则表达式中的使用
iex> regex = ~r/foo|bar/
~r/foo|bar/
iex> "foo" =~ regex
true
iex> "bat" =~ regex
false
表示字符串,字符以及列表的示例
iex> ~s(this is a string with "quotes")
"this is a string with \"quotes\""
iex> ~c(this is a string with "quotes")
'this is a string with "quotes"'
iex> ~w(foo bar bat)
["foo", "bar", "bat"]
~w 还可以加入其他的修饰符(比如:c, s, a 分别代表字符列表,字符串,原子)
iex> ~w(foo bar bat)a
[:foo, :bar, :bat]
自定义 sigils
iex> defmodule MySigils do
...> def sigil_i(string, []), do: string <> "add_sigil"
...> end
iex> import MySigils
iex> ~i("123")
|