我正在尝试编译以下代码:
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();
}
斯卡拉有什么不同之处,它不会允许这种行为?
答案 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[_]]
,正如其他答案所说的那样。