轨道
/
F#
F#
/
练习
/
密码检查器
密码检查器

密码检查器

学习练习

简介

Result 类型让函数可以返回一个值,同时表明以下几件事:

  • 操作是成功还是失败
  • 成功时,操作得到的结果值
  • 失败时,这次失败的原因

用法

Result 类型是一种泛型类型,包含两种底层类型:

  • 操作成功时结果值的类型
  • 失败时错误的类型

Result 类型也是一种[可辨识联合][discriminated-union],可能有以下几种情况:

  • Ok <value>,表示成功的结果
  • Error <reason>,表示失败

下面的函数演示了如何创建一个 Result 值:

let validateName (name: string) : Result<string, string> = 
    match name with
    | null -> Error "Name not found."
    | "" -> Error "Name is empty."
    | _ -> Ok name

在这个例子中,Ok 的值是一个字符串(给定的名字),Error 的值也是一个字符串(错误原因,以人类可读的形式给出)。

读取 Result 值的内容

考虑下面的类型定义和函数签名:

type FileOpenError = 
| NotFound
| AccessDenied
| FileLocked

let openFile (filename: string) : Result<int, FileOpenError> =

调用 openFile 函数的代码可以用模式匹配来处理成功和失败的情况,如下例所示:

match openFile(filename) with
| Ok handle -> doSomethingWithFile(handle)
| Error NotFound -> printfn $"Error: file {filename} was not found."
| Error AccessDenied -> printfn $"Error: you do not have permission to open the file {filename}."
| Error FileLocked -> printfn $"Error: file {filename} is already in use."

说明

你的任务是创建一个密码检查器。 密码检查器会验证用户提出的密码,确保它满足一组由控制该资源访问权限的组织所定义的要求。

在本练习中,密码的要求如下:

  • 必须包含 12 个或更多字符
  • 必须至少包含一个大写字母
  • 必须至少包含一个小写字母
  • 必须至少包含一个数字
  • 必须至少包含一个符号,该符号来自集合 !@#$%^&*

你的解答必须使用Result来封装成功或失败的状态。 对于成功的情况,Result必须以字符串的形式给出通过验证的密码。 对于失败的情况,Result必须给出失败时被违反的那条规则。

Note

在本练习中,密码检查器会非常简化,它只会在有一条规则被违反时给出提示。 后续的练习会探讨一个更贴近现实的密码检查器,它可以同时指出多条被违反的规则。

1. 实现checkPassword函数

checkPassword函数会根据上述规则检查给定的密码。检查失败时,它会把某个PasswordRule值封装在结果值中,以此来指出被违反的规则。

checkPassword "abcdefghij5#"
// => Error MissingUppercaseLetter

2. 实现``getStatusMessage`函数

getStatusMessage函数会返回一个字符串,其中包含一条人类可读的消息,说明checkPassword所返回结果的含义。

getStatusMessage (Error MissingDigit)
// => "Error: does not have at least one digit"
通过 GitHub 编辑 链接将在新窗口或新标签页中打开
F# Exercism

准备好开始 密码检查器 了吗?

注册 Exercism,借助 18 个概念148 个练习 和真人导师指导,学习并掌握 F#,全部免费。