Reason
  • Docs
  • Try
  • API
  • Community
  • Blog
  • Languages icon中文
    • 日本語
    • English
    • Deutsch
    • Español
    • Français
    • 한국어
    • Português (Brasil)
    • Русский
    • Українська
    • 繁體中文
    • 帮助翻译
  • GitHub

›Advanced Features

Intro

  • What & Why

Setup

  • Installation
  • Editor Plugins

Language Basics

  • Overview
  • Let Bindings
  • Primitives
  • Basic Structures
  • Types
  • Records
  • Variants
  • Options and nullability
  • Functions
  • Recursion
  • Destructuring
  • Pattern Matching
  • Mutable Bindings
  • Loops
  • Modules

Advanced Features

  • JSX
  • External
  • Exception
  • Object

JavaScript

  • Interop
  • Syntax Cheatsheet
  • Pipe First
  • Promise
  • Libraries
  • Converting from JS

Extra

  • Frequently Asked Questions
  • Extra Goodies
Translate

Exception

异常只是一种特殊类型的变体, 在 异常 的情况下 "抛出" (请不要滥用!)

用法

let getItem = (theList) =>
  if (callSomeFunctionThatThrows()) {
    /* 在这里返回找到的值 */
  } else {
    raise(Not_found)
  };

let result =
  try (getItem([1, 2, 3])) {
  | Not_found => 0 /* getitem 异常情况下的默认值 */
  };

注意上述只是为了展示;实际上,你应该直接从 getItem 返回 option(int) 而避免和 try 一起使用。

在从一个函数获得返回值的 同时,也可以直接匹配异常:

switch (List.find((i) => i === theItem, myItems)) {
| item => print_endline(item)
| exception Not_found => print_endline("No such item found!")
};

你也可以像创建 variant 一样创建异常(异常也必須是字母大写)。

exception InputClosed(string);
...
raise(InputClosed("the stream has closed!"));

提示 & 技巧

一般使用 variant 时,几乎 不需要 用到异常。 例如,在集合中找不到 item 时,试着返回 option(item)(这个例子返回None),而不是抛出异常。

设计决策

上述提示看似和 OCaml 标准库的行为有所相悖;模块中著名的函数如 List 和 String ,看上去过于频繁使用异常了。 这些部分是历史沉淀的结果,部分则出于对性能的考虑。 原生 OCaml/Reason 是非常有效率;抛出异常被设计的很轻量,比分配和返回值还要轻量,例如 option。 很遗憾这和 JavaScript 没什么关系。

较新的标准库通常返回 option,而非抛出异常。 例如,List.find 返回和 option 类似的 List.find_opt,而不会抛出异常。

异常实际上也就是变体(variant)。 事实上,它们都属于同一个变体类型,叫做 exn。 这是 可扩展变体,表示你可以加入新的构造器,例如上述的 InputClosed。 exception Foo 只是个語法糖,方便加入构造函数到 exn。

← ExternalObject →
  • 用法
  • 提示 & 技巧
  • 设计决策