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."
你的任務是建立一個密碼檢查器。 密碼檢查器會驗證使用者提出的密碼,確保它符合控管該資源存取權的組織所定義的一組要求。
這道練習的密碼要求如下:
你的解法必須使用Result來封裝成功或失敗的狀態。
成功時,Result必須以字串呈現通過驗證的密碼。
失敗時,Result必須指出違反了哪一條規則。
在這道練習裡,密碼檢查器會很陽春,只會指出單一條規則被違反的情況。 之後的練習會探討更貼近現實的密碼檢查器,它能夠同時指出多條被違反的規則。
checkPassword函式checkPassword函式會依據上述規則檢查指定的密碼。失敗時,它會將其中一個PasswordRule值封裝進結果值中,藉此指出違反了哪一條規則。
checkPassword "abcdefghij5#"
// => Error MissingUppercaseLetter
getStatusMessage函式會回傳一個字串,內容是讓人看得懂的訊息,說明checkPassword回傳的結果代表什麼意思。
getStatusMessage (Error MissingDigit)
// => "Error: does not have at least one digit"