我有一个简单的函数,它根据过滤函数从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
不会抛出错误?
答案 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
)推断f
和fallback
的类型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型!在你的例子中,你有一个字符串,我假设你的'人'不是函数的字符串。