2016-10-04 74 views
3

我刚开始学习Elixir,但有一些编程背景和几种OOP语言,主要是Ruby。我发现的例子,我如何定义模块内部结构:如何访问struct定义的模块结构[Elixir]

defmodule Example.User do 
    defstruct name: "Sean", roles: [] 
end 

另外,我发现当我创建结构,我可以设置这个值: steve = %Example.User{name: "Steve", roles: [:admin, :owner]} 并且只需通过调用steve.name

的访问外模块问题是,我怎么能访问模块内部结构数据,让我们说,我想从call_my_name访问功能:

defmodule Example.User do 
    defstruct name: "" 
    def call_my_name do 
    IO.write(???) 
    end 
end 
martin = %Example.User{name: "Martin"} 

就OOP而言,我只是想写一个getter

我该怎么办?什么是良好的/默认的方式来做到这一点?如果我不能,为什么?

回答

3

尽管语法最初看起来可能类似于Ruby,但Elixir不是,而是的OOP语言。你在Elixir没有“方法”。相反,你需要显式调用该函数并传入结构:

defmodule Example.User do 
    defstruct name: "" 

    def call_my_name(%Example.User{name: name}) do 
    IO.write(name) 
    end 
end 

martin = %Example.User{name: "Martin"} 
Example.User.call_my_name(martin) 
+0

感谢您的回复,我真的很感激。我知道这不是OOP,我只是想澄清一些事情。结合数据和相关操作的好/默认方法是什么?我应该只在模块内部定义结构和函数,以便我可以将结构传递给这个函数?是否有任何确切的概念/想法,为什么我无法访问数据? –

+0

@YarTheGreat创建结构和函数以“修改”这些结构的方法是合理的。但不要试图将结构作为对象。我将_modify_放在引号之间,因为在功能语言中,您不会修改数据,您只需在修改后创建原始数据的副本。 –

+0

嘿,你还可以解释这个函数声明,为什么我们可以声明这样的参数:“call_my_name(%Example.User {name:name})”或者当我能够阅读这个表单时给我一个源代码?它提醒我静态样式声明,而我们使用动态语言。这种形式的戒备还是什么?从未见过它。 –

0

只是堆在这里,你不需要用你自己的模块内完整的命名空间,只要你不有另一个用户模块来引用。试试这个:

defstruct Example.User do 
    alias __MODULE__ # <- this is the magic 

    defstruct [:name] 

    def my_fun(%User{} = user) 
    IO.inspect(user) 
    end 
end 

感谢https://dockyard.com/blog/2017/08/15/elixir-tips的提示