如何指示具有void结果的函数的失败

时间:2015-09-07 07:18:15

标签: scala

我在scala中有一个没有返回值的函数(所以unit)。此功能有时会失败(如果用户提供的参数无效)。如果我在java上,我只会抛出异常。但是对于scala(尽管可能是同样的事情),建议不要使用异常。

我完全知道如何使用OptionTry,但只有在您有效返回时才会有意义。

例如,考虑一个(虚构的)addPrintJob(printJob: printJob): Unit命令,它将打印作业添加到打印机。作业定义现在可能无效,应通知用户。

我看到以下两种选择:

  1. 无论如何使用例外
  2. 从方法中返回一些内容(例如"打印作业标识符")然后返回该类型的Option / Either / Try。但这意味着仅为了处理错误而添加返回值。
  3. 这里的最佳做法是什么?

3 个答案:

答案 0 :(得分:4)

你对FP太深了:-) 您想知道方法是否成功 - 返回布尔值!

答案 1 :(得分:3)

根据这个Throwing exceptions in Scala, what is the "official rule"不建议在scala中抛出异常,因为它会破坏控制流。在我看来,只有在出现重大错误并且正常流不应该继续时,才应该在scala中抛出异常。

对于所有其他情况,通常最好返回已执行操作的状态/结果。 scala OptionEither就是出于此目的。 imho一个不返回任何值的函数是一种不好的做法。

对于addPrintJob的给定示例,我将返回一个作业标识符(如评论中@marstran所建议的),如果这不可能是addPrintJob的状态。

答案 2 :(得分:0)

问题是,通常当您必须为特定方法建模时,这与成功或失败(正确或错误)或(0或1-单位退出代码明智)或(0或1-true或true)无关。明智的做法是错误的插值),但是关于返回状态信息和msg,因此我使用的最简单的技术(每当代码审查naysayers / dickheads / besserwissers不在时)就是

<div class="entry-content">
    <?php
    if (is_singular()) :
        the_post_thumbnail();
        the_content(sprintf(wp_kses(/* translators: %s: Name of current post. Only visible to screen readers */
            __('Continue reading<span class="screen-reader-text"> "%s"</span>', 'hideout'), array(
                'span' => array(
                    'class' => array(),
                ),
            )), get_the_title()));

        wp_link_pages(array(
            'before' => '<div class="page-links">' . esc_html__('Pages:', 'hideout'),
            'after'  => '</div>',
        ));
    else :
        echo '<div class="s-img-ho">';
        the_post_thumbnail();
        echo '<div class="cat-ho"><span class="cat-span">';
        the_category();
        echo '</span></div>';
        echo '<div class="cat-bar">ffff</div></div>';
        ?>
    <?php endif; ?>
</div><!-- .entry-content -->

最后总是返回一个元组

val msg = "unknown error has occurred during ..."
val ret = 1 // defined in the beginning of the method, means "unknown error"
.... // action 
ret = 0 // when you finally succeeded to implement FULLY what THIS method was supposed to to
msg = "" // you could say something like ok , but usually end-users are not interested in your ok msgs , they want the stuff to work ...

或者如果您也有数据(比如说spark数据框)

return ( ret , msg ) 

使用回报更为明显,尽管不是必需的(对于纯粹主义者而言)... 现在,由于ret只是一个愚蠢的int,您可以快速将更复杂的状态代码转换为更复杂的Enums,对象或其他东西,但要点是,您不应在开始时就将多余的复杂性引入代码中,让它有机生长...

当然,呼叫者会打来

return ( ret , msg , Some(df))

因此,异常将意味着真正的错误情况,并且您将避免混乱的尝试捕捉丛林... 我知道这个答案会被否决,因为大学里的人太多了,但是光鲜的履历却写出了精采的算法和东西,最终都变成了意大利面条式的代码,我们都讨厌,而不是尽可能简单但不是更简单,当然可以解决问题。

但是,如果您只需要ok / nok控制流和链接,这里有一些更详细的ok,nok示例,它确实引发了异常,当然,您必须将其捕获在更高的级别上,这可以产生火花:

 ( ret , msg , mayBeDf ) = myFancyFunc(someparam, etc)

免责声明:我的同事为我提供了精美的函数语法...