try
method是核心Ruby的常见扩展。例如,它在Rails中默认可用。仅当try
不是nil
(Ruby' s null
)时,nil
才会在对象上执行方法或代码块。它的用法有三种:
在非customer_or_nil.try(:save)
对象上调用方法并返回结果:
nil
。
如果到目前为止的结果不是obj.try { |non_nil_obj| do_something(non_nil_obj) }
,则在表达式中链接任意代码块:
data.analyze.try { |result| result.compress(optimal_settings(result)) }.save
。
(2)的扩展名不是用于可选处理,而是用作继续链接表达式的一种方法,其中步骤n + 1中的方法需要一个必须根据步骤n的结果计算的参数:登记/>
val df = ctx.sql("select * from my_table")
df.
repartition(max(1, df.rdd.partitions.size / 4)).
saveAsTable("repartitioned_table")
我特别感兴趣的是(3)的Scala等价物或替代的Scala惯用法,例如,这个代码与Apache Spark的DataFrame
相关:
ctx.
sql("select * from my_table").
try { |df| df.repartition(max(1, df.rdd.partitions.size / 4)) }.
saveAsTable("repartitioned_table")
重构为类似以下内容(使用Ruby语法)
df
重构的目标是通过维护单个方法链来提高可读性,并通过将Option
严格限制在绝对需要的链中的步骤来减少范围污染。
注意:我对讨论使用try
进行可选处理的利弊特别不感兴趣,因为这不是artistArray = [];
while (artistUrls[i] != null) {
getArtists(artistArray, artistUrls[i]);
i++;
}
doSomethingWithArtistArray(artistArray);
doAnotherThingWithArray(artistsArray);
这个问题的主要用例关心。
答案 0 :(得分: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")