在创建%MyStruct {}之后实现回调

时间:2017-07-10 12:48:44

标签: elixir

在Elixir中,我希望在创建数据结构时强制执行验证。为了实现它,我想强制调用一个回调函数来获取刚创建的数据结构,并返回该数据结构(如果它是有效的)或错误元组。

实施它的方法是什么?

如果我声明一些类似ValidatedStruct的行为并在struct的模块中实现回调 - 那么在调用代码中返回新结构之前,如何强制在struct初始化时调用它呢?

2 个答案:

答案 0 :(得分:2)

您不能保证结构在Elixir中包含有效值。 Struct只是一个带有__struct__字段的Map,其中包含Atom(通常是模块名称)。您可以使用任何地图,添加__struct__字段,它就会成为该结构。

例如,我在这里构建一个MapSet结构而没有任何其他字段。 iex甚至无法打印结构,因为Inspect的{​​{1}}实现假定在结构内部有一个包含地图的MapSet键:

map

Elixir库通常做的是在模块中添加iex(1)> %{__struct__: MapSet} %Inspect.Error{message: "got FunctionClauseError with message \"no function clause matching in MapSet.to_list/1\" while inspecting \e[39m%{\e[0m\e[33m\e[36m__struct__: \e[0m\e[33m\e[36mMapSet\e[0m\e[33m\e[39m}\e[0m\e[33m"} 函数,该模块接受参数并在有效输入时返回new并在失败时返回{:ok, struct}(或仅{:error, "description"}) 。这不会阻止用户使用:error语法创建结构。您可以通过添加默认为%ModuleName{}的{​​{1}}字段来添加一个简单的安全措施,然后在所有函数中检查该值是否为true。 valid?使用了类似的技术,如果false中出现错误,Ecto.Changeset甚至不会尝试将数据插入数据库。再次,这是微不足道的。

以下是一个例子:

Repo.insert

输出:

Ecto.Changeset

答案 1 :(得分:1)

您可以通过一个名为UIViewController的函数创建结构,并从那里调用验证方法。

例如:(未经测试)

TWs.Range(TFinal).NumberFormat = "#,##0"