我之前使用过类型(type),但不知道什么是不透明类型(opaque type),我也看到它被提到过。暴露不透明类型是否比类型别名更好?
我之前使用过类型(type),但不知道什么是不透明类型(opaque type),我也看到它被提到过。暴露不透明类型是否比类型别名更好?
首先让我们看一下类型别名:
类型别名是完全透明的。这意味着任何导入它的其他模块都可以完全访问它的内部结构。假设我们有一个“User”模块,公开了一个“User”类型:
module User exposing User
type alias User =
{ userName : String
, age : Int
}
引入User
的任何人都可以操纵数据,例如newUser = { oldUser | age = 25 }
。或者执行someUser = User "Bill" 27
。当您控制它们存在的上下文时,这些操作是可以接受的。
然而,如果User
是库的一部分,那么对User
类型的每个更改对使用该库的人来说都是一个破坏性的变化。例如,如果添加了email
字段到User
,那么构造函数示例(someUser = User "Bill" 27
)将会产生编译器错误。
即使在项目代码库内部,类型别名也可能向其他模块提供过多信息,导致难以维护和演进的代码。也许User
在某些时候发生了巨大变化,并具有完全新的属性集。这将要求更改代码操纵User
的任何地方。
不透明类型很有价值,因为它们避免了这些问题。这里是一个User
的不透明版本:
module User exposing User
type User =
User
{ userName : String
, age : Int
}
使用此版本,其他模块无法直接访问或操作数据。通常,这意味着您将创建并公开一些getter和函数:
initUser : String -> Int -> User
userName : User -> String
age : User -> String
setAge : Int -> User -> User
这样做更加繁琐,但有以下好处:
User
函数,并且不需要知道类型中包含了哪些数据大部分解释来自@wintvelt: elmlang.slack.com