榆树中的不透明类型是什么?为什么它有价值?

Nat*_*han 13 elm

我之前使用过类型,但不知道opaque类型是什么.我也看过它.暴露opaque类型而不是类型别名更好吗?

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