2016-05-31 4 views
1

をパラメータ化タイプを使用して:スカラ - 私は次のコードをコンパイルしようとしているパラメータ化型の内側に

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コードがsucesfullyコンパイル:

public class Settings { 
    List<Setting> settingsList; 
} 

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

このような動作を許さないスケーラについてはどういう違いがありますか?

答えて

1

Javaはバージョン5で、AFAIKは下位互換性のために型パラメータを省略できます。また、Javaにはuse-site varianceがあり、Scalaのuse-site varianceとは対照的に、通常、これらのものは非常に迷惑になります。変更がなければ、あなたはScalaでは実存タイプList[Setting[_]]を使用することができ、おそらくより良いが、右分散を使用することです:

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

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

分散の混乱は、必ずしも最良のアイディアではありません。設定の実装の詳細によっては、共分散が意味をなさない場合があり、設計が制限されます。ワイルドカードは行く方法のようです。 –

+0

@UlysseMizrahiそれは「混乱」ではありません。私はそれが理にかなっている分散を持つ型に常に注釈を付けることをお勧めします。これがサブタイプベースのシステムの仕組みです。Scalaは不変のデータ構造を好むので、これはかなり意味があります。これが不可能な場合は、私が指摘したように、実在の(ワイルドカード)タイプを使用することができます。 –

+0

"これはサブタイプベースのシステムの仕組みです" - これは単純に真実ではなく、共分散は実際には不変性に関連していますが、共分散はメソッドパラメータの型を使用できないことを意味します(不変構造)。さらに、分散は型設計の点で実際の意味を有する。 Setting [List [Int]]をSetting [Iterable [Int]]にしますか?デザインの観点からは意味をなさないかもしれません。 –

3

あなただけのワイルドカード型を必要とする:

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

これは、Javaコードと同等です。

0

同等のJavaコードは、タイプパラメータなしsucesfully

Settingをコンパイルし、生タイプです。

Java documentationによれば、生型の使用は、従来のコードの互換性に譲歩として許容されます。ジェネリック性がJavaプログラミング言語に導入された後に作成されたコードでは、生の型を使用することはお勧めしません。 Javaプログラミング言語の将来のバージョンでは、生の型の使用を禁止する可能性があります。

Javaでこれを書くための正しい方法は

List<Setting<?>> settingsList; 

とScalaのと同等である他の回答が言うように、List[Setting[_]]です。

関連する問題