有什么机制可以实现结构重用:定义一个结构,其中包含另一个结构的所有字段以及它自己的一些结构.
我有这些看起来像这样的结构
defmodule VideoView do
defstruct name: nil, description: nil, video_link: nil, ...
end
defmodule ImagesView do
defstruct name: nil, description: nil, images: [], ...
end
defmodule Model3DView do
defstruct name: nil, description: nil, model: nil, ...
end
Run Code Online (Sandbox Code Playgroud)
其中有7个.在我的UML它们都继承了View它有name和description.我希望他们所有人分享这些共同的领域,特别是如果我决定添加或删除一个公共领域,这可能是当前方法的真正痛苦.
Pat*_*ity 10
正如其他人所建议的那样,你应该再考虑一下你是否真的从重新使用结构中获得了那么多.
如果仍然需要它来减少大量复制,可以使用模块属性来初始存储struct选项.然后你可以重复使用它们defstruct并通过一个函数将它们暴露给其他模块:
defmodule View do
@common_fields [name: nil, description: nil]
def common_fields, do: @common_fields
defstruct @common_fields
end
Run Code Online (Sandbox Code Playgroud)
如果您不打算单独使用View,可以直接将公共字段放在函数中:
defmodule View do
def common_fields do
[name: nil, description: nil]
end
end
Run Code Online (Sandbox Code Playgroud)
然后,您可以使用其他结构中的公共字段,如下所示:
defmodule VideoView do
defstruct View.common_fields ++ [video_link: nil, ...]
end
defmodule ImagesView do
defstruct View.common_fields ++ [images: [], ...]
end
defmodule Model3DView do
defstruct View.common_fields ++ [model: nil, ...]
end
Run Code Online (Sandbox Code Playgroud)
据我所知,没有直接的方法可以做到 1。如果你对宏的了解足够多,你可能可以找到一个。Elixir 中的结构体实际上是一个零参数的函数__struct__/0,它返回一个带有默认值的映射。
您可以将另一个模块的函数导入到您的模块中,并且如果其他模块中的函数定义为可重写,则可以使用您自己的定义来重写其他模块中定义的函数。
use OtherModule
Run Code Online (Sandbox Code Playgroud)
但你不能导出这些函数,只能导出模块中定义的函数。
如果你想要继承 Elixir 不是你想要使用的语言。Elixir 不关注继承,而是关注函数的组合和数据的转换。从面向对象的世界带来大量包袱只会减慢你的速度。
在这种情况下,如果您需要来自另一个模块的数据结构,您应该考虑组合而不是继承。一种方法是
defstruct other_module: struct(Other_Module), foo: nil , bar: 1
Run Code Online (Sandbox Code Playgroud)
在大多数情况下,Elixir 是一种基于表达式的语言,您几乎总是可以为运行时函数调用交换数据值,反之亦然。