1

違いや、どちらかを好む理由はないと思いますが、確認したかったのです...

def length(l: List[Any])
def length[T](l: List[T])
4

3 に答える 3

6

次のように書くこともできます。

def length(l: List[_])

さて、あなたの質問に関してList[Any]は、確かに任意Listの を受け入れますが、 を試した場合、うまくいきSet[Any]ません! たとえば、 a を渡してみてくださいSet[Int]:

scala> def length(s: Set[Any]) = s.size
length: (s: Set[Any])Int

scala> val set = Set(1, 2, 3)
set: scala.collection.immutable.Set[Int] = Set(1, 2, 3)

scala> length(set)
<console>:10: error: type mismatch;
 found   : scala.collection.immutable.Set[Int]
 required: Set[Any]
Note: Int <: Any, but trait Set is invariant in type A.
You may wish to investigate a wildcard type such as `_ <: Any`. (SLS 3.2.10)
              length(set)
                     ^

List共変であるため、それが可能になりますが、すべてのパラメーター化されたクラスが共変であるとは限りません。ただし、パラメータ化されたバージョンまたは上記のバージョンのいずれかが機能します。

どちらかを優先する理由は思いつきませんが、必要のないものをパラメーター化したくないのです。他に何もないとしても、コンパイル速度にわずかなプラスの影響があります。

于 2013-08-13T02:16:00.650 に答える
2

任意の長さだけが必要な場合Listは、違いはありません。
しかし、そのリストの要素を操作したい場合は、あります。

val l = List(1, 2, 3, 4)
def secondElementAny(l: List[Any]) = l.tail.head
def secondElementGen[A](l : List[A]) = l.tail.head

これら 2 つの関数とリストを指定すると、2からが得られることが期待されますList

val secondAny = secondElementAny(l)
val secondGen = secondElementGen(l)

値をコンソールに出力しても違いを見つけることはできませんがFloat、たとえば値をキャストしようとすると、エラーが発生します。secondAny.toFloatsecondAny は の型であり、関数onAnyは使用できないことがわかります。 対照的に、私たちに値を与えます。toFloatAny
secondGen.toFloatFloat

その理由は、コンパイラが次のように完全な署名を近似するためです。

def secondElementAny(l: List[Any]): Any = l.tail.head
def secondElementGen[A](l: List[A]): A = l.tail.head

ご覧のとおり、最初の関数の戻り値の型はAnyであるため、常に を取得しますAnyが、2 番目の関数の戻り値の型は の型に依存しListます。そのタイプの要素を取得します。これはタイプセーフです。

于 2013-08-13T06:53:10.060 に答える
0

違いがあります:

def head_1(l: List[Any]) = {
  l.head
}

def head_2[T](l: List[T]) = {
  l.head
}

// Doesn't compile, head_1 returns Any
// head_1(List(1,2,3)) > 1

head_2(List(1,2,3)) > 1                   //> res0: Boolean = false
于 2013-08-13T02:26:52.473 に答える