我是scala的新手。我有一节课:
abstract class List[T] {
def isEmpty: Boolean
def head: T
def tail: List[T]
def nth[T](elem : T, index: Int) : Int =
if (this.isEmpty) throw new IndexOutOfBoundsException("Element not found")
else if (head.equals(elem)) return index
else tail.nth(elem, index+1)
}
无论实现如何,方法nth
都可以使用或不使用Type参数[T]进行编写,即在定义中没有Type参数[T]
的方法声明将生成同样的结果:
def nth(elem : T, index: Int) : Int =
if (this.isEmpty) throw new IndexOutOfBoundsException("Element not found")
else if (head.equals(elem)) return index
else tail.nth(elem, index+1)
根据我的理解,没有使用带有方法定义的类型参数。如果是这样,为什么这个功能被添加到语言中?有人能用一个有用的例子解释这个功能背后的动机吗?在这种情况下进行了什么样的编译时检查?
更新:链接列表的其余实现:
class NilList[T] extends List[T]{
def isEmpty:Boolean = true
def head : Nothing = throw new NoSuchElementException("Nil node")
def tail : Nothing = throw new NoSuchElementException("Nil node")
}
class ConsList[T] (val head: T, val tail: List[T]) extends List[T]{
def isEmpty: Boolean = false
}
答案 0 :(得分:2)
请考虑以下事项。
abstract class X[A] {
def m1[A](arg: A) // warning: A defined in method shadows A defined in class
def m2[B](arg: B) // B can be unrelated to A
def m3[C <: A](arg: C) // C must be subtype of A
def m4[D >: A](arg: D) // D must be supertype of A
}
如您所见,方法类型参数可用于多种用途。
答案 1 :(得分:1)
根据我的理解,没有使用类型参数 方法定义。
只有在阴影类级别类型参数时,才允许在方法上使用类型参数。隐藏类型参数通常是程序员错误的结果,编译器能够捕获并警告您实际上正在隐藏现有类型参数。
除此之外,还有很多用例需要泛型类型参数,而不是类。假设您对类型T
有一个现有的,不变的约束,并且您希望类型V
具有T
作为其上限,但也可以对派生进行操作类。你会这样做:
class Foo[T] {
def playWithDerived[V <: T](param: V) = Unit {
// Do stuff.
}
}
还有许多其他情况,这会有所帮助。
答案 2 :(得分:1)
l.nth("foo", 0)
上的 List[Int]
将使用以下List
进行编译:
abstract class List[T] {
def isEmpty: Boolean
def head: T
def tail: List[T]
def nth[T](elem : T, index: Int) : Int =
if (this.isEmpty) throw new IndexOutOfBoundsException("Element not found")
else if (head.equals(elem)) return index
else tail.nth(elem, index+1)
}
但如果我们定义List
如下所示,它会产生编译时错误:
abstract class List[T] {
def isEmpty: Boolean
def head: T
def tail: List[T]
def nth(elem : T, index: Int) : Int =
if (this.isEmpty) throw new IndexOutOfBoundsException("Element not found")
else if (head.equals(elem)) return index
else tail.nth(elem, index+1)
}
后者是编写此代码的正确方法,为什么要在nth
上调用List[T]
,其元素类型与T
完全不同?
我很好奇如何使用这个抽象类来实现终止列表。看起来不像是(重新)实现链表的更好方法之一。
还要考虑T
:abstract class List[+T]
的协方差。