【问题标题】:Scala equivalent for ActiveSupport's Object.try in RubyScala 等效于 Ruby 中的 ActiveSupport 的 Object.try
【发布时间】:2015-07-20 03:20:53
【问题描述】:

try method 是核心 Ruby 的常见扩展。例如,它在 Rails 中默认可用。 try 仅在对象不是 nil(Ruby 的 null)时才在对象上执行方法或代码块。它的用法分为三种:

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

  2. 如果目前的结果不是nil:
    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 相关:

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 这个问题所关注的主要用例。

【问题讨论】:

  • 理解应该可以完成这项工作。 Scala 中的Try 是一个monad,这意味着flatmap() 是在其上定义的。 flatmap() 在 Try 上的工作方式是将其参数应用于成功路径。 for{ df <- ctx.sql(...); rep <- repartiion( ... ); sat <- saveAsTable(...); }
  • @BobDalgleish 您错过了问题的目的:我正在寻找支持方法链接的答案。看看 Alexey 的回答。

标签: ruby-on-rails ruby scala apache-spark chaining


【解决方案1】:

不在标准库中,但等价于 3 很容易编写(try 是关键字,因此重命名为 ap(apply 的缩写)):

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")

【讨论】:

  • 对我不起作用:null.ap(identity _) // <console>:12: error: value ap is not a member of Null
  • @JörgWMittag 我可以在上面重现您的错误,但是,当我使用 ap 和应该是来自 Spark SQL 的 null 值(使用 Any 值变量)时,我没有收到任何错误.
  • Alexey,有什么办法可以解决@JörgWMittag 发现的问题?
  • 如果你给null一个类型,例如(null: String).ap ... 或 val x: String = null; x.ap ...,它会工作的。但是null 本身有一个特殊的类型Null,而且似乎你不能对它进行任何隐式转换。对我来说,这看起来像是一个编译器错误,我已经在 groups.google.com/forum/#!topic/scala-user/jpVi3_AlF4E 询问过它
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-29
  • 1970-01-01
  • 1970-01-01
  • 2012-01-07
  • 1970-01-01
  • 2022-01-08
相关资源
最近更新 更多