我有一个 traitPerson和一个继承自这个 trait 的 case 类,我希望如果我有一个函数,除了一个来自Personto的函数Future[Person],我会把它 func from MaletoFuture[Male]传递给那个函数。像这样:
trait Person {
val name: String
val age: Int
}
case class Male (override val name: String, override val age: Int, height: Double) extends Person
val male1 = Male(name = "John", age = 30, height = 1.80)
def something(person: Person => Future[Person]): Unit = {
println(s"person is $person")
}
def maleToFutureMale (male: Male) = Future.successful(male)
something(maleToFutureMale)
Run Code Online (Sandbox Code Playgroud)
但得到编译错误:
这与 case 类或特征无关,它与函数子类型有关。
Scala 拒绝这样的代码,因为虽然 aMale是 a Person,但 aMale => Future[Male]不是 a Person => Future[Person]。
要了解原因,请考虑以下类型
case class Female(val name, val age) extends Person
Run Code Online (Sandbox Code Playgroud)
以及您something方法的以下增量
def something(personToFuture: Person => Future[Person]): Unit = {
val future = personToFuture(Female("Lisa", 53))
}
Run Code Online (Sandbox Code Playgroud)
上面的代码是完全正确的。我们可以传递 a FemaletopersonToFuture因为 aFemale是 a Person。
如果该语言允许我们传递maleToFutureMaleto something,那么它将允许我们将 a 传递Female给期望 a 的函数Male。
所有这些并不是说函数类型是不变的,您传递给的参数something必须具有 type Person => Future[Person]。函数类型确实有子类型关系。
一般来说,给定一个函数类型 ,F具有较少特定参数类型和更特定返回类型的函数类型是 的子类型F。
例如,以下是完全有效的
val anyToFutureOfMale: Any => Future[Male] = _ => Future.successful(Male("Robert", 39, 1.8))
something(anyToFutureOfMale)
Run Code Online (Sandbox Code Playgroud)
以上是有效的,因为 anAny => Male是 a Person => Person。由于 aPerson是 an Any,将 a 传递Person给期望 an 的函数是完美的Any,同样,作为a ,从返回 a 的函数接收 aMale也是Person完美Male的Person。
| 归档时间: |
|
| 查看次数: |
111 次 |
| 最近记录: |