这是我发现自己写的一个成语。
def chooseName(nameFinder: NameFinder) = {
if(nameFinder.getReliableName.isEmpty) nameFinder.getReliableName
else nameFinder.secondBestChoice
}
为了避免在getReliableName()
上调用nameFinder
两次,我添加了使我的方法看起来不那么优雅的代码。
def chooseName(nameFinder: NameFinder) = {
val reliableName = nameFinder.getReliableName()
val secondBestChoice = nameFinder.getSecondBestChoice()
if(reliableName.isEmpty) reliableName
else secondBestChoice
}
这感觉很脏,因为我使用vals
创建了一个不必要的状态量,除了防止重复的方法调用之外没有任何理由。斯卡拉告诉我,每当我感到肮脏时,几乎总会有更好的方法。
有更优雅的方式来写这个吗?
Here's two Strings, return whichever isn't empty while favoring the first
答案 0 :(得分:3)
当然,没有必要随时拨打getSecondBestChoice
。就个人而言,我发现在改变之后代码没有任何优雅 - 它清楚它的作用,没有可变的状态。其他答案似乎过于复杂,只是为了避免使用val
def chooseName(nameFinder: NameFinder) = {
val reliableName = nameFinder.getReliableName()
if(reliableName.isEmpty) reliableName
else nameFinder.getSecondBestChoice()
}
如果你真的想避免使用val,那么这是另一个变体(如果有两个以上的替代方案,则说得很好)
List(nameFinder.getReliableName(), nameFinder.getSecondBestChoice()).find(_.nonEmpty).get
(或getOrElse(lastResort)
,如果列表中的所有内容也可能为空)
答案 1 :(得分:2)
这是使用Option
的方法。它并不是那么漂亮,但一切都只召唤一次。这假设您希望结果为String
,并且不关心第二个字符串是否为空。
Some(nameFinder.getReliableName)
.filter(_.nonEmpty)
.getOrElse(nameFinder.secondBestChoice)
答案 2 :(得分:2)
Option(namefinder.getReliableName) // transforms a potential null into None
.filter(_.trim.nonEmpty) // "" is None, but also " "
.getOrElse(nameFinder.secondBestChoice)
或者更好的是,如果您可以修改getReliableName
以返回Option[String]
:
def chooseName(nameFinder: NameFinder): String =
namefinder.getReliableName getOrElse nameFinder.secondBestChoice
最后,如果secondBestChoice
也可能失败(假设它返回Option[String]
):
def chooseName(nameFinder: NameFinder): Option[String] =
namefinder.getReliableName orElse nameFinder.secondBestChoice
答案 3 :(得分:2)
如果您需要不止一次:
scala> implicit class `nonempty or else`(val s: String) extends AnyVal {
| def nonEmptyOrElse(other: => String) = if (s.isEmpty) other else s }
defined class nonempty
scala> "abc" nonEmptyOrElse "def"
res2: String = abc
scala> "" nonEmptyOrElse "def"
res3: String = def
答案 4 :(得分:0)
使用以下模式匹配可以提供更整洁的scalish代码,
def chooseName(nameFinder: NameFinder) = {
nameFinder.getReliableName match {
case r if r.isEmpty => r
case _ => nameFinder.secondBestChoice
}
}