gpt4 book ai didi

scala - 方法返回类型协方差

转载 作者:行者123 更新时间:2023-12-04 19:54:34 26 4
gpt4 key购买 nike

如何定义该方法返回 List[+AnyRef]?我试过:

def a[T <: AnyRef](): List[T] = List[AnyRef]() 

但由于某种原因它没有编译。

编辑:根据 Wong 的说法,我应该使用

def a[T <: AnyRef](): List[T] = List[T]()

但是有什么方法能够返回 AnyRef 的任何子类型,例如

def a[T <: AnyRef](): List[T] = if (value) List[T]() else List[Option[String]]()

这里的 Option[String] 是 Anyref 的后代,但是编译器不接受它

所以主要问题是我是否可以声明具有协变返回类型的方法,例如 List[+AnyRef]

最佳答案

让我们进行一些观察,并试验几种让编译器决定您的返回类型的方法:

1) 注意语句 if (value) List[T]() else List[Option[String]]()返回 2 种不同的特定类型,但 if语句必须从其 then 和 else 子句返回相同类型。因此,当此语句返回一个值时,编译器将需要为这 2 个子句推断出最一般的类型,以引入一致的约束。

2) 注意类型变量 T取决于您调用 a() 时传入的确切类型,例如 a[scala.io.Source]() .在你给出的方法声明中 T上限 T <: AnyRef ,这意味着编译器必须找到最通用的类​​型,它是 AnyRef 和 Option[String] 的子类型的任何类型的联合。

3) 注意编译器通过删除返回类型声明推断出的返回类型。即 def a[T <: AnyRef]() = if (true) List[T]() else List[Option[T]]() .编译器给出了 a()返回类型 List[AnyRef] .这是有道理的,因为这是任何东西之间最通用类型的唯一可能性 T那是 AnyRef 的子类型和 Option[of that anything T] .

4) 现在尝试 def a[T <: AnyRef]() = if (true) List[T]() else List[Option[String]]() .推断的返回类型现在是 List[java.lang.Object] .原因是 String Scala 2.8 中的类实际上是 java.lang.String ,所以根据我的最佳猜测,现在最通用的类​​型必须转义 scala.*层次结构并最终出现在 java.lang.Object 中出于未知原因。

5) 自 AnyRef实际上只是 java.lang.Object 的别名, 你可以做 def a[T <: AnyRef](): List[AnyRef] = if (true) List[T]() else List[Option[String]]()强制返回类型 List[AnyRef] .

如果你只想返回 AnyRef 的任何子类型,你基本上必须这样做:

def a(): List[AnyRef] = ...

基本上返回父类(super class),你必须转换返回的 List[AnyRef]使用 .asInstanceOf[T] .或者:

def a[T <: AnyRef](): List[T] = List[T]()

会给你一个特定的类型 T,但是你不能在 if 中返回 2 种不同的类型。像您的示例中的语句,其中一个可能更具体,另一个可能更具体,并期望它在您调用该方法时始终返回您提供的更具体的类型。因为编译器无法保证 if 中的类型仅通过类型检查,语句将始终为 List[T]。我说得更清楚了吗?

关于scala - 方法返回类型协方差,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4941675/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com