Reputation: 999
I don't think there's any difference, or reason to prefer one over the other, but wanted to check...
def length(l: List[Any])
def length[T](l: List[T])
Upvotes: 1
Views: 106
Reputation: 3608
If you just want the length of any List
, there is no difference for you.
But if you want operatations with the elements of that list, there is.
val l = List(1, 2, 3, 4)
def secondElementAny(l: List[Any]) = l.tail.head
def secondElementGen[A](l : List[A]) = l.tail.head
Giving those two functions and the list, we will expect to get the 2
from the List
.
val secondAny = secondElementAny(l)
val secondGen = secondElementGen(l)
If we would print the values to the console, we could spot no diference, but if we try to cast them to Float
for example, we will get an error. secondAny.toFloat
will tell us, that secondAny is type of Any
and that we cannot use the function toFloat
on Any
.
In contrast secondGen.toFloat
will give us a Float
value.
The reason for that is, that the compiler aproximates the full signatures as follows.
def secondElementAny(l: List[Any]): Any = l.tail.head
def secondElementGen[A](l: List[A]): A = l.tail.head
As you can see the return type of the first function is Any
, so we will always get an Any
whereas the return type of the second function depends on the type of the List
. We will get an element of that type. This is typesafe.
Upvotes: 2
Reputation: 9225
There is a difference:
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
Upvotes: 0
Reputation: 297265
You could also write it like this:
def length(l: List[_])
Now, with regards to your question, List[Any]
will, indeed accept any List
, but if you had tried Set[Any]
, it would not work! For instance, try passing a Set[Int]
to it:
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
is co-variant, which makes that possible, but not every parameterized class is covariant. Either your parameterized version or the version above will work, though.
I can't think of any reason to prefer one over the other, but I'd rather not parameterize something when it is not needed. If nothing else, it will have a slight positive impact on compilation speed.
Upvotes: 6