scala - 在 Scala 中使用基于类型的过滤器时如何获得正确的返回类型

标签 scala filter type-inference scala-collections

以下不编译。我需要先投这个人吗?

 object People {
  def all = List(
    new Person("Jack", 33),
    new Person("John", 31) with Authority,
    new Person("Jill", 21),
    new Person("Mark", 43)
  )
}

class Person(val name: String, val age: Int) 

trait Authority {
  def giveOrder {
    println("do your work!")
  }
}

object Runner {
  def main(args:List[String]) {
    val boss = People.all.find { _.isInstanceOf [Authority] }.get
    boss.giveOrder // This line doesnt compile
  }
}

最佳答案

您认为以某种方式应该有一种机制可以让您避免强制转换,这是正确的。这样的 Actor 阵容将是丑陋和多余的,因为它无论如何已经出现在过滤器中。 find然而,它根本不关心它得到的谓词的形状;它只是应用它并返回 Option[A]如果 A是集合元素的静态类型。

您需要的是collect功能:

val boss = People.all.collect { case boss: Authority => boss }.head
collect创建一个新集合。如果你想避免这种情况(如果你真的只对第一个元素感兴趣,它是 Authority ),以防潜在老板列表很长,你可能想切换到 view懒惰地评估它:
val boss = People.all.view.collect { case boss: Authority => boss }.head

最后,除非您绝对确定您的列表中总是至少有一个老板,否则您应该真正测试搜索是否成功,例如像这样:
val bossOpt = People.all.view.collect { case boss: Authority => boss }.headOption
bossOpt.foreach(_.giveOrder) // happens only if a boss was found

编辑:最后,如果你使用 Scala 2.9,你绝对应该使用 collectFirstKevin Wright's answer 中所述.

关于scala - 在 Scala 中使用基于类型的过滤器时如何获得正确的返回类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5933660/

相关文章:

scala - == 用于 Scala 中的 case 类和 "non-case"类

scala - PlayFramework + ScalaTest + ScalaCheck

scala - 无法解析 Scala 中流的符号 #::error

ios - 如何过滤 JSON 数据然后枚举过滤后的数据?

javascript - jQuery 过滤器帮助

dataframe - 使用多个值过滤数据框

c++ - "Materializing"用于 C++ 类型推断的已知类型的对象

scala - 理解时类型不匹配 : getting "Product with Serializable"

javascript - TypeScript:有什么技术可以中断递归条件类型推断吗?

c# - 为什么我无法实例化从匿名对象推断类型的泛型类?