学习路径
/
Elm
Elm
/
教学大纲
/
不透明类型
不透

不透明类型 属于 Elm

2 个练习

关于 不透明类型

简介

不透明类型是 Elm 中的一种封装技术。 有人也称之为信息隐藏,或隐藏实现细节。 它们还常被用来强制执行验证,采用解析而非验证模式。 例如,你可以有一个EmailAddress不透明类型,它只能包含有效的电子邮件地址(与之相对,String可以包含任何内容)。

创建不透明类型

自定义类型有一个或多个变体,编译器会根据变体的名称,自动生成一个函数来创建每个变体。 这是创建自定义类型的唯一方式。 编译器也允许对这些变体进行解构。

type Maybe a
    = Nothing --> Variant implies a 'Nothing' function, with type 'Maybe a', and destructuring of 'Nothing'
    | Just a  --> Variant implies a 'Just' function, with type 'a -> Maybe a', and destructuring of 'Just _'

默认情况下,所有这些都只属于文件/模块内部,我们使用exposing关键字来选择要导出什么。 Maybe模块暴露了Maybe类型(这样其他模块就能使用已有的Maybe值),也暴露了Nothing和Just这两个变体(这样其他模块就能创建和解构Maybe值)。 它使用以下语法来做到这一点。 Maybe(..)这部分告诉 Elm 暴露所有变体,以及自定义类型本身的定义。

module Maybe exposing
  ( Maybe(..)
  -- ...
  )

要创建不透明类型,你只需选择不导出变体。 若要为Maybe类型做到这一点,你可以使用以下语法:

module Maybe exposing
  ( Maybe
  -- ...
  )

这样做时,你几乎总是需要提供另一种创建和获取变体的方式,即暴露自定义函数。 这些自定义函数让你在创建和获取变体时应用一些逻辑。 这隐藏了模块的内部实现细节,也意味着只要暴露的函数保持不变,你可以随意修改实现细节。 它还让你在创建和使用该类型时能够维护不变量。

解析而非验证

不透明类型最常见的用途大概就是强制执行验证,采用解析而非验证模式。 在这种模式下,你暴露一个函数,它接收一个结构化程度或类型安全性低于你期望的输入,比如String,然后把它解析成结构更强的类型,比如EmailAddress,要么返回该类型,要么返回一个错误(通常是Maybe或Result)。

例如,在下面的代码中,外部模块只能通过parseEmailAddress函数创建EmailAddress类型,因此当你使用EmailAddress类型时,你就能确定它是有效的。

module EmailAddress exposing ( EmailAddress, parseEmailAddress, getEmailAddress )

-- The `EmailAddress` custom type has one variant, also called `EmailAddress`
-- When a custom type has one variant, it is idiomatic to use the same name for both.
type EmailAddress = 
  EmailAddress String

-- create an EmailAddress variant
parseEmailAddress: String -> Maybe EmailAddress
parseEmailAddress candidateEmailAddress =   
  if isValidEmailAddress candidateEmailAddress then
    Just (EmailAddress candidateEmailAddress)
  else
    Nothing

-- get an EmailAddress variant
getEmailAddress: EmailAddress -> String
getEmailAddress ( EmailAddress  emailAdress ) =
  emailAdress

isValidEmailAddress: String -> bool
-- ... 
通过 GitHub 编辑 该链接会在新窗口或标签页中打开

学习 不透明类型

练习已锁定

再解锁 1 个练习即可练习 不透明类型