Scala - 在参数化类型中使用参数化类型

时间:2016-05-31 17:23:38

标签: java scala

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

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();
}

斯卡拉有什么不同之处,它不会允许这种行为?

3 个答案:

答案 0 :(得分:3)

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

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

这相当于您的Java代码。

答案 1 :(得分:1)

Java已经通过版本5生成,而AFAIK为了向后兼容,您可以省略类型参数。 Java也有使用站点差异,这通常会使这些事情非常烦人,而不是Scala中的使用站点差异。如果没有更改,您可以在Scala中使用存在类型List[Setting[_]],但更好的方法是使用正确的方差:

case class Settings(settingsList: List[Setting[Any]])

abstract class Setting[+A](name: String, value: A)

答案 2 :(得分:0)

  

等效的Java代码成功编译

没有类型参数的

Setting是原始类型。根据{{​​3}},

  
    

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

  

在Java中编写它的正确方法是

List<Setting<?>> settingsList;

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