第 2 部分 · 高级特性
异常与契约
异常与契约
使用异常处理运行时错误,用契约系统保障接口的正确使用。
异常处理
#lang racket ;; 抛出异常 (define (divide a b) (if (= b 0) (error 'divide "division by zero") (/ a b))) ;; 捕获异常 (with-handlers ([exn:fail? (lambda (e) (displayln (exn-message e)) 0)]) (divide 10 0)) ; 打印错误信息,返回 0
自定义异常
(struct exn:fail:user exn:fail (username)) (define (login name password) (unless (valid? name password) (raise (exn:fail:user "Invalid credentials" (current-continuation-marks) name))))
契约系统
契约为模块接口添加运行时检查:
#lang racket (provide (contract-out [interest-rate (-> number? number?)])) (define (interest-rate amount) (cond [(< amount 1000) 0.02] [(< amount 10000) 0.03] [else 0.04]))
常用契约
(-> number? number? number?) ; 两数返回一数 (-> string? (listof string?) boolean?) ; 字符串 + 字符串列表 → 布尔 (-> any/c integer?) ; 任意输入 → 整数 (->/c [positive?]) ; 返回值为正数
小结
异常处理运行时错误,契约在模块边界强制执行类型约束。两者结合让你的程序更加健壮。