Nat*_*han 17
让我们首先看一下类型别名来回答这个问题:
类型别名是完全透明的.这意味着导入它的任何其他模块都可以完全访问其内部工作.假设我们有一个User
暴露User
类型的模块:
module User exposing User
type alias User =
{ userName : String
, age : Int
}
Run Code Online (Sandbox Code Playgroud)
任何导入User
都可以操纵数据,例如newUser = { oldUser | age = 25 }
.或者做someUser = User "Bill" 27
.当您控制它们存在的上下文时,这些操作很好.
但是,如果User
是库的一部分,则对该User
类型的每次更改都是对使用该库的人的重大更改.例如,如果email
添加了一个字段User
,那么构造函数example(someUser = User "Bill" 27
)将给出编译器错误.
即使在项目代码库内部,类型别名也可以向其他模块提供过多信息,从而导致代码难以维护和发展.也许User
在某些时候会发生巨大的变化,并且拥有一套全新的属性.这需要在代码操作User
的任何地方进行更改.
不透明类型很有价值,因为它们避免了这些问题.这是一个不透明的版本User
:
module User exposing User
type User =
User
{ userName : String
, age : Int
}
Run Code Online (Sandbox Code Playgroud)
使用此版本,其他模块无法直接访问或操作数据.通常,这意味着您将制作并公开一些getter和函数:
initUser : String -> Int -> User
userName : User -> String
age : User -> String
setAge : Int -> User -> User
Run Code Online (Sandbox Code Playgroud)
这是更多的工作,但它有优势:
User
功能,不需要知道类型中的数据大部分解释来自@wintvelt:elmlang.slack.com