【在主画面加入捷径】
       
【选择语系】
繁中 简中

Perl 6 程序设计教学:例外 (Exceptions) 处理

【赞助商连结】

    在实际情境中运行的程序,即使程序本身没有臭虫 (bug),仍然要面对许多可能的错误 (error) 或例外 (exception)。例如,想要将某个字串转成数字,但字串本身不是合法的数字;想要读取某个外部文件,却权限不足;想要解析某个 XML 文件,但该 XML 文件内有错误的格式。我们不能天真地认定程序不会发生错误,而要详细考虑可能发生的错误,撰写相关的程序代码。

    抛出例外事件

    die 是 Perl 5 留下来的语法,后面接一个字串,可以抛出例外事件,见下例:

    1 + 2 == 3 or die "Wrong logic";
    

    有类型的例外事件

    Perl 6 增加有类型的例外事件,主要是为了增加错误讯息的可读性,如下例:

    die X::IO::DoesNotExist.new(:path("foo/bar"), :trying("zombie copy"))
    

    想要使用内建的例外物件,可见官网有关 Exception 类的说明,此处不逐一列出。

    接收例外事件

    使用 CATCH 区块可以接住例外事件,可搭配 when,对于不同类型的例外以不同方式处理,如下例:

    die X::IO::DoesNotExist.new(:path("foo/bar"), :trying("zombie copy"));
     
    CATCH {
        when X::IO { say "some kind of IO exception was caught!"; }
        default { say "Something wrong"; }
    }
    

    进入 CATCH 区块后,会跳出程序,不会再执行后续的程序代码,如下例:

    die "Something happens";
     
    CATCH {
        default { .say; }
    }
    
    say "This won't happen";
    

    加上 .resume 后,可从例外中回复,如下例:

    die "Something happens";
     
    CATCH {
        default { 
            .say;
            .resume;
        }
    }
    
    say "This will happen as well";
    

    try

    try 区块可将可能会发生例外的程序代码包住,引发错误后仍可继续执进程序,如下例:

    try {
        die "Something happens";
     
        CATCH {
            default { .say; }
        }
    }
    
    say "This will happen as well";
    

    throw

    throw 由 Exception 物件调用,作用类似于 die。见下例:

    X::AdHoc.new(:payload<foo>).throw;
    "OHAI".say;
    
    CATCH {
        when X::AdHoc { .resume }
    }
    
    "OBAI".say;
    

    自订 Exception 类

    除了使用内建的 exceptions 外,使用者也可自订自己的 Exception 类,建立 Exception 类时至少要建立一个回传字串的 message 方法。以下例子摘自 Perl 6 官网:

    class X::YourApp::SomeError is Exception {
        method message() {
            "A YourApp-Specific error occurred: out of coffee!";
        }
    }
    
    【赞助商连结】