【问题标题】:Scala - using parametrized type inside parametrized typeScala - 在参数化类型中使用参数化类型
【发布时间】:2016-06-01 06:46:25
【问题描述】:

我正在尝试编译以下代码:

case class Settings(settingsList:List[Setting])
abstract class Setting[T](name:String, value:T)

但编译器抱怨:

Error:(9, 54) class Setting takes type parameters
case class Settings(settingsList:List[Setting])
                                                     ^

但等效的 Java 代码编译成功:

public class Settings {
    List<Setting> settingsList;
}

abstract class Setting<T> {
    abstract T getValue();
    abstract String getName();
}

scala 有什么不同,它不允许这样的行为?

【问题讨论】:

    标签: java scala


    【解决方案1】:

    你只需要一个通配符类型:

    case class Settings(settingsList:List[Setting[_]])
    abstract class Setting[T](name:String, value:T)
    

    这相当于你的 Java 代码。

    【讨论】:

      【解决方案2】:

      Java 已使用版本 5 进行了通用化,AFAIK 为了向后兼容,您可以省略类型参数。此外,Java 具有使用点差异,这通常会使这些东西输入起来非常烦人,这与 Scala 中的使用点差异相反。如果不进行更改,您可以在 Scala 中使用存在类型 List[Setting[_]],但使用正确的变体可能更好:

      case class Settings(settingsList: List[Setting[Any]])
      
      abstract class Setting[+A](name: String, value: A)
      

      【讨论】:

      • 处理差异不一定是最好的主意。根据设置的实现细节,协方差可能没有意义,并且会限制设计。通配符似乎是要走的路。
      • @UlysseMizrahi 这不是“搞砸”。我建议总是在有意义的地方用方差注释类型。这就是基于子类型的系统的工作方式,Scala 更喜欢不可变的数据结构,所以这很有意义。正如我所指出的,如果这是不可能的,您可以使用存在(通配符)类型。
      • “这就是基于子类型的系统的工作方式”——这根本不是真的,虽然协方差确实与不变性有关,但强制协方差意味着无法在方法参数中使用类型(其中即使在不可变结构中也可能是可取的)。此外,差异在字体设计方面具有实际意义。我们是否希望 Setting[List[Int]] 成为 Setting[Iterable[Int]] ?从设计的角度来看,这可能没有意义。
      • ""这就是基于子类型的系统的工作方式" - 这根本不是真的"。咳咳。对,是真的。避免考虑 Scala 中的差异是错误的。正确注释您的类型几乎总是有用的。它有助于设计和推理。
      【解决方案3】:

      等效的 Java 代码编译成功

      Setting 没有类型参数是原始类型。根据Java documentation

      仅允许使用原始类型作为对遗留代码兼容性的让步。强烈反对在将泛型引入 Java 编程语言之后编写的代码中使用原始类型。 Java 编程语言的未来版本可能会禁止使用原始类型。

      用Java写这个的正确方法是

      List<Setting<?>> settingsList;
      

      正如其他答案所说,Scala 等价物是 List[Setting[_]]

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-02-19
        • 1970-01-01
        • 1970-01-01
        • 2021-04-20
        • 2012-02-09
        • 2011-10-05
        • 2018-09-24
        • 2016-11-06
        相关资源
        最近更新 更多