首先,我要说我是Elixir世界(以及一般的函数式编程(的新手。我目前正在学习字典类型,并遇到了结构。我根据我的书中的说明定义了这个:
defmodule Subscriber do
defstruct name: "", paid: false, over_18: true
end
在那之后,这本书在本章的其余部分都在 iex 中工作,但我想把我的放在一个文件中。我尝试创建此结构的实例(所有值都设置为默认值(,如下所示:
sub = %Subscriber{}
这游戏我是一个编译错误:
CompileError: cannot access struct Subscriber, the struct was not yet defined or the struct is being accessed in the same context that defines it
它在 iex 中工作正常,但就像我说的,我宁愿把它放在文件中。有人可以解释我在这里做错了什么吗?
有人可以解释我在这里做错了什么吗?
我相信,iex
已经解释了问题所在,我会毫不犹豫地重复一遍:">结构是在定义它的同一上下文中访问的"。
它在IEX中工作正常
是的,因为iex
是一个 REPL,它会编译每个语句
。Elixir是一种编译语言。一般情况下的编译单元是一个文件。在 REPL 中,它是一个完整的语句。除非代码被编译,否则无法直接访问它(但延迟调用仍然可用(。
这将起作用:
defmodule A, do: defstruct foo: :bar
defmodule B, do: def b, do: IO.inspect %A{}
B.b
这也将起作用:
defmodule A, do: defstruct foo: :bar
IO.inspect struct(A)
但是显式调用%A
要求编译器知道如何处理以下 AST(请参阅第 2 行(:
quote do: %A{}
#⇒ {:%, [],
# [{:__aliases__, [alias: false], [:A]},
# {:%{}, [], []}]}
虽然A
只是一个原子(是的,它是一个普通的原子,(
is_atom(A)
#⇒ true
它可以很容易地注入到任何 AST 并成功编译。必须展开上述 AST 的第二行,在结构定义可供编译器使用之前,它不能展开。
我了解到[您的特定编译错误]无法在定义的同一文件中使用结构,这通常意味着您正在从外部文件的词法范围访问或使用结构。
只需在另一个模块的函数中创建结构实例,而不是在外部文件范围("context"(中创建结构实例,然后调用该函数使其运行。
这是我在这个文件中使用名为Product
的结构的简单示例:
defmodule Product do
defstruct [:name, :sku, :upc ]
end
defmodule Main do
def hello do
hh = %Product{name: 'dog'}
IO.puts "Hello, #{hh.name}"
end
end
Main.hello