我将在前言中说我是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中工作正常,但就像我说的,我宁愿把它放在一个文件中。有人可以解释我在这里做错了吗?
答案 0 :(得分:3)
有人可以解释我在这里做错了吗?
我相信,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的第二行,直到编译器可以使用struct定义,它不能。
答案 1 :(得分:0)
我从[您的特定编译错误]了解到无法在定义的同一文件中使用结构,这通常意味着您正在外部文件的词法范围内访问或使用该结构。
只需在另一个模块的函数中而不是在外部文件范围(“上下文”)中创建结构实例,然后调用该函数使其运行。
这是我在单个文件中使用名为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