簡體   English   中英

相當於javascript運算符|| 在斯卡拉

[英]equivalent to the javascript operator || in scala

在javascript中,我們可以執行以下操作:

value = f1() || f2() || f3();

這將調用f1,如果結果不為null,則將其賦值給value。 只有當結果為null時,它才會調用f2,並且如果它不為null,則將其賦值給value。 ...

這里給出了一種在scala中實現這一點的方法: 如何使這個first-not-null-result函數更加優雅/簡潔? 創建一個getFirstNNWithOption函數,調用每個函數直到非null:

value = getFirstNNWithOption(List(f1 _, f2 _, f3 _))

但是,這不如javascript ||那么好 運營商,更靈活。 例如:

value = f1() || f2(3) || f3(44, 'ddd') || value4;

有沒有辦法在scala中實現這一點?

由於您正在使用函數返回Option

最好的解決方案是使用鏈接選項,就像這里解釋選項的鏈接一樣

所以你會這樣做

f1().orElse(f2()).orElse(f3()).orElse(Some(4))

我使用推薦的Option而不是null
例如:

class OptionPimp[T](o: Option[T]) {
  def ||(opt: => Option[T]) = o orElse opt
  def ||(t: => T) = o getOrElse t
}
implicit def optionPimp[T](o: Option[T]) = new OptionPimp(o)

def f1(): Option[Int] = None
def f2(): Option[Int] = None
def f3(): Option[Int] = Some(3)

val value1 = f1() || f2() || f3() || 4 // yields 3
val value2 = f1() || f2()         || 4 // yields 4

如果您將此函數與可能返回null的函數一起使用,您還可以定義一個空合並運算符:

class NullOption[A <: AnyRef](a: A) {
  def |?|[B >: A](b: => B) = if (a ne null) a else b
}
implicit def null_handling[A <: AnyRef](a: A) = new NullOption(a)

它的工作原理就像Javascript一樣。 (我使用|?|以避免將其誤認為布爾邏輯或者,但如果您願意,可以使用|| 。)這樣可以更好地工作 - 幾乎像Option一樣 - 如果您添加條件映射(此處命名為? - 選擇你最喜歡的單詞或符號):

class NullOption[A <: AnyRef](a: A) {
  def |?|[B >: A](b: => B) = if (a ne null) a else b
  def ?[C >: Null](f: A => C): C = if (a ne null) f(a) else null
}
implicit def null_handling[A <: AnyRef](a: A) = new NullOption(a)

那么你也能

scala> val s: String = null
s: String = null

scala> val t: String = "foo"
t: String = foo

scala> s?(_.toUpperCase) |?| t |?| { println("I am not executed"); "bar" }
res4: java.lang.String = "foo"

當然,你的類型系統不會幫助你記住你需要處理那些沒有數據的情況,但它可以使空處理稍微更愉快(至少只要沒有原語;使用原語,返回null-or-primitive實際上沒有意義)。

我和Andy幾乎一樣,除了我使用運算符表示法,並使用正確的默認方法:

value = f1 orElse f2(3) orElse f3(44, 'ddd') getOrElse value4

使用新的scala 2.10,您可以使用隱式類來更新@PeterSchmitz答案,因此您無需定義隱式轉換函數。

implicit class OptionPimp[T](o: Option[T]) {
  def ||(opt: => Option[T]) = o orElse opt
  def ||(t: => T) = o getOrElse t
}

雷克斯克爾的回答是一樣的:

implicit class NullOption[A <: AnyRef](a: A) {
  def |?|[B >: A](b: => B) = if (a ne null) a else b
  def ?[C >: Null](f: A => C): C = if (a ne null) f(a) else null
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM