模块
模块是把函数组织到不同命名空间的最好的办法,除了能为函数分组,他还允许我们定义命名函数和私有函数。
defmodule Example do
def greeting(name) do
"Hello #{name}."
end
end
iex> Example.greeting "Sean"
"Hello Sean."
Elixir 也允许嵌套的模块,这让你可以轻松定义多层命名空间:
defmodule Example.Greetings do
def morning(name) do
"Good morning #{name}."
end
def evening(name) do
"Good night #{name}."
end
end
iex> Example.Greetings.morning "Sean"
"Good morning Sean."
模块属性
模块的属性通常被用作常量。
defmodule Example do
@greeting "Hello"
def greeting(name) do
~s(#{@greeting} #{name}.)
end
end
iex>Example.greeting('world')
"Hello world."
需要注意有些属性是保留的,最常用到的三个为:
- moduledoc 当前模块的文档
- doc 函数和宏的文档
- behaviour 使用 OTP 或者用户定义的行为
结构体
结构体是字典的特殊形式,他们的键是预定义的,一般都有默认值。结构体必须定义在某个模块内部,因此也必须通过模块的命名空间来访问。在一个模块里只定义一个结构体是一种常用的手法。
要定义结构体,我们使用 defstruct
关键字,后面跟着关键字列表和默认值。
defmodule Example.User do
defstruct name: "Sean", roles: []
end
# 创建结构体
iex> %Example.User{}
%Example.User{name: "Sean", roles: []}
iex> %Example.User{name: "Steve"}
%Example.User{name: "Steve", roles: []}
iex> %Example.User{name: "Steve", roles: [:admin, :owner]}
%Example.User{name: "Steve", roles: [:admin, :owner]}
我们可以像图一样更新结构体。
iex> steve = %Example.User{name: "Steve", roles: [:admin, :owner]}
%Example.User{name: "Steve", roles: [:admin, :owner]}
iex> sean = %{steve | name: "Sean"}
%Example.User{name: "Sean", roles: [:admin, :owner]}
结构体可以匹配图
iex> %{name: "Sean"} = sean
%Example.User{name: "Sean", roles: [:admin, :owner]}
网友评论