在Elixir中,我希望在创建数据结构时强制执行验证。为了实现它,我想强制调用一个回调函数来获取刚创建的数据结构,并返回该数据结构(如果它是有效的)或错误元组。
实施它的方法是什么?
如果我声明一些类似ValidatedStruct的行为并在struct的模块中实现回调 - 那么在调用代码中返回新结构之前,如何强制在struct初始化时调用它呢?
答案 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"