Types 具有类型和值限制以及默认值的Erlang记录

Types 具有类型和值限制以及默认值的Erlang记录,types,erlang,default-value,records,restrictions,Types,Erlang,Default Value,Records,Restrictions,我试图写一份代表银行账户的记录: -record(account, { name :: atom(), type :: atom(), balance = 0 :: integer() }). 我还想限制余额始终为=0。我该怎么做?类似于balance=0::0 | pos_integer()的东西可能会起作用 edit不确定它是否存在,但非负整数()会更好: balance = 0 :: non_neg_in

我试图写一份代表银行账户的记录:

-record(account, {  name :: atom(),
                    type :: atom(),
                    balance = 0 :: integer()  }).

我还想限制余额始终为
=0
。我该怎么做?

类似于
balance=0::0 | pos_integer()
的东西可能会起作用

edit不确定它是否存在,但
非负整数()
会更好:

balance = 0 :: non_neg_integer()

正如其他人所指出的,类型规范仅仅是分析工具(如和)的输入。如果需要强制执行不变量
余额>=0
,则应封装帐户类型,仅可由遵守该不变量的函数访问:

-module(account).

-record(account, { name :: atom(),
                   type :: atom(),
                   balance = 0 :: non_neg_integer() }).

%% Declares a type whose structure should not be visible externally.
-opaque account() :: #account{}.
%% Exports the type, making it available to other modules as 'account:account()'.
-export_type([account/0]).

%% Account constructor. Used by other modules to create accounts.
-spec new(atom(), atom(), non_neg_integer()) -> account().
new(Name, Type, InitialBalance) ->
    A = #account{name=Name, type=Type},
    set_balance(A, InitialBalance).

%% Safe setter - checks the balance invariant
-spec set_balance(account(), non_neg_integer()) -> account().
set_balance(Account, Balance) when is_integer(Balance) andalso Balance >= 0 ->
    Account#account{balance=Balance};
set_balance(_, _) -> error(badarg). % Bad balance
<>注意到,这类似于一个类,在面向对象语言中,如java或C++。通过限制对“受信任”构造函数和访问器的访问,不变量得以强制执行


此解决方案不提供防止恶意修改
余额
字段的保护。另一个模块中的代码完全有可能忽略“不透明”类型规范并替换记录中的余额字段(因为)。

我也不知道存在这种情况。非常感谢!请注意,正如Robert Virding所说,这只是供读者、文档或工具使用的信息。它不会阻止平衡为负或其他任何东西(如原子)。如果它在代码中很重要,则在使用它和/或修改平衡之前,您必须使用类似于is_integer(B)和B>=0的保护。谢谢@Pascal,我一定会使用这些保护。:)请注意,虽然可以将类型声明为非负整数,但在运行时不会强制执行任何操作,它实际上只是一个注释。您可以将“平衡”字段设置为您选择的任何值和任何类型。@rviding如何在运行时强制执行此行为(没有函数保护)?或者这种伪静态类型在Erlang中根本不存在吗?你不能!Erlang过于动态,因此该语言中不存在静态类型,编译器也不使用此信息。它仅用于文档和类型检查工具透析器。感谢您的示例和警告!