如何从Vector [T]推断参数T

时间:2017-11-26 22:15:33

标签: scala generics

我有一个简单的函数,它根据过滤函数从Vector [T]获得第一个匹配T.

def first[T](vector: Vector[T], func: T => Boolean, fallback: T): T = {
  for (value <- vector) if (func(value)) return value
  fallback
}

我称之为

first(people, _.name == "Bob", "")

我的编译器抱怨:

Type mismatch, expected: NotInferredT => Boolean, actual: Nothing => Any

如何让编译器正确推断T,以便_.name不会抛出错误?

4 个答案:

答案 0 :(得分:2)

首先,我为你重构了你的函数,我很确定它能完成你想要的东西 - 而且,正如已经指出的那样,你在示例中明确键入的返回值不是' T'(即它是一个字符串,而不是一个人。)

另外,我非常确定你可以添加第二个参数列表来修复你的问题,因为在调用站点的参数列表之外没有任何内容可以指示T可能是什么(也是,可重用性!)。 在这个回购中查看更多信息: https://github.com/ljwagerfield/scala-type-inference

  case class Person(name: String)

  def first[T](vector: Vector[T])(func: T => Boolean, fallback: T): T = vector.find(func).getOrElse(fallback)

  val people = Vector(Person("Bob"))

  //Note: Passing "people" in first, compiler now knows what "T" is!
  val test1 = first(people)(p => p.name == "Bob", Person(""))
  val test2 = first(people)(p => p.name == "Alice", Person("Not Bob"))"

  println(test1) // "Person(Bob)"
  println(test2) // "Person(Not Bob)

答案 1 :(得分:1)

这里的重点是类型推断将参数列表视为一个整体。 使用first(v: Vector[T])(f: T => Boolean, fallback: T),编译器可以从上一个参数列表(T)推断ffallback的类型Vector[T]。 与first(v: Vector[T], f: T => Boolean, fallback: T)编译器不能,因为它还没有T的信息。

答案 2 :(得分:1)

您必须以某种方式提供类型信息,以便编译器可以决定您的T实际是什么。

这样做的一种方法是在答案中按照@Raudbjorn的建议更改方法签名。

但是如果你想保持方法签名相同,那么你必须在func中使用模式匹配,

case class Person(name: String)

val people = List(Person("NotBob"), Person("Bob"))

val defaultPerson = Person("Default Person")

val result = first(
  people,
  {
    // if it is a Person then compare p.name
    case p: Person => p.name == "Bob"
    // if it is not a person... then just return false
    case _ => false
  },
  // You can not provide a String here. You have to provide a Person
  defaultPerson
)

答案 3 :(得分:0)

我可能不知道函数的所有语法糖,但你可以尝试声明像'(e:T) => e.name == "Bob"'这样的函数,其中T是人的类型。

first(people, (e:T) => e.name == "Bob", fallback)

'后备'也必须属于T型!在你的例子中,你有一个字符串,我假设你的'人'不是函数的字符串。