当前位置: 首页>>代码示例 >>用法及示例精选 >>正文


Elixir Record.defrecord用法及代码示例


Elixir语言中 Record.defrecord 相关用法介绍如下。

用法:

defrecord(name, tag \\ nil, kv)
(宏)

定义一组宏以在记录上创建、访问和模式匹配。

生成的宏的名称将是name(它必须是一个原子)。 tag 也是一个原子,用作记录的"tag"(即记录元组的第一个元素);默认情况下(如果 nil ),它与 name 相同。 kv 是新记录的name: default_value 字段的关键字列表。

生成以下宏:

  • name/0 使用所有字段的默认值创建新记录
  • name/1 使用给定字段和值创建新记录,获取记录中给定字段的从零开始的索引或将给定记录转换为关键字列表
  • name/2 使用给定字段和值更新现有记录或访问给定记录中的给定字段

所有这些宏都是公共宏(由 defmacro 定义)。

有关如何使用这些宏的示例,请参阅"Examples" 部分。

例子

defmodule User do
  require Record
  Record.defrecord(:user, name: "meg", age: "25")
end

在上面的示例中,将定义一组名为 user 但具有不同参数的宏来操作基础记录。

# Import the module to make the user macros locally available
import User

# To create records
record = user()        #=> {:user, "meg", 25}
record = user(age: 26) #=> {:user, "meg", 26}

# To get a field from the record
user(record, :name) #=> "meg"

# To update the record
user(record, age: 26) #=> {:user, "meg", 26}

# To get the zero-based index of the field in record tuple
# (index 0 is occupied by the record "tag")
user(:name) #=> 1

# Convert a record to a keyword list
user(record) #=> [name: "meg", age: 26]

生成的宏也可用于对记录进行模式匹配并在匹配期间绑定变量:

record = user() #=> {:user, "meg", 25}

user(name: name) = record
name #=> "meg"

默认情况下,Elixir 使用记录名称作为元组的第一个元素("tag")。但是,在定义记录时可以指定不同的标记,如下例所示,其中我们使用 Customer 作为 defrecord/3 的第二个参数:

defmodule User do
  require Record
  Record.defrecord(:user, Customer, name: nil)
end

require User
User.user() #=> {Customer, nil}

在值中使用匿名函数定义提取的记录

如果记录在默认值中定义了匿名函数,则会引发 ArgumentError 。在从使用匿名函数作为默认值的 Erlang 库中提取记录后定义记录时,可能会无意中发生这种情况。

Record.defrecord(:my_rec, Record.extract(...))
** (ArgumentError) invalid value for record field fun_field,
    cannot escape #Function<12.90072148/2 in :erl_eval.expr/5>.

要解决此错误,请使用您自己的 &M.f;/a 函数重新定义该字段,如下所示:

defmodule MyRec do
  require Record
  Record.defrecord(:my_rec, Record.extract(...) |> Keyword.merge(fun_field: &__MODULE__.foo/2))
  def foo(bar, baz), do: IO.inspect({bar, baz})
end

相关用法


注:本文由纯净天空筛选整理自elixir-lang.org大神的英文原创作品 Record.defrecord(name, tag \\ nil, kv)。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。