繁体   English   中英

Scala相当于Ruby中ActiveSupport的Object.try

[英]Scala equivalent for ActiveSupport's Object.try in Ruby

try方法是Ruby核心的通用扩展。 例如,默认情况下在Rails中可用。 仅当对象不为nil (Ruby的null )时,才try执行方法或代码块。 它的用法有以下三种:

  1. 在非nil对象上调用方法并返回结果:
    customer_or_nil.try(:save)

  2. 如果到目前为止的结果不是nil则在表达式中链接任意代码块:
    obj.try { |non_nil_obj| do_something(non_nil_obj) } obj.try { |non_nil_obj| do_something(non_nil_obj) }

  3. (2)的扩展名不是用于可选处理,而是用于延续链式表达式的一种方式,其中步骤n + 1中的方法需要一个必须根据步骤n的结果来计算的自变量:
    data.analyze.try { |result| result.compress(optimal_settings(result)) }.save

我对等效于(3)的Scala或另一个Scala惯用语特别感兴趣,该惯用语将允许例如与Apache Spark的DataFrame相关的DataFrame

val df = ctx.sql("select * from my_table")
df.
  repartition(max(1, df.rdd.partitions.size / 4)).
  saveAsTable("repartitioned_table")

重构为以下内容(使用Ruby语法)

ctx.
  sql("select * from my_table").
  try { |df| df.repartition(max(1, df.rdd.partitions.size / 4)) }.
  saveAsTable("repartitioned_table")

重构的目的是通过维护单个方法链来提高可读性,并通过将df紧密限定在绝对需要它的链中的步骤上,从而减少范围污染。

注意:对于使用Option进行可选处理的优缺点的讨论,我特别不感兴趣,因为这不是try此问题的主要用例。

不在标准库中,但是易于编写等效于3( try是一个关键字,因此重命名为apapply缩写)):

implicit class TryOp[A](x: A) {
  def ap[B](f: A => B): B = f(x)
}

ctx.
  sql("select * from my_table").
  ap { df => df.repartition(max(1, df.rdd.partitions.size / 4)) }.
  saveAsTable("repartitioned_table")

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM