楼梯书中的一个例子:
package ky.example
object Example {
abstract class MyList[+T] {
def isEmpty: Boolean
def head: T
def tail: MyList[T]
def length: Int = if(isEmpty) 0 else 1 + tail.length
def drop(n: Int): MyList[T] = {
if(isEmpty) MyNil
else tail.drop(n - 1)
}
def map[U](func: T => U): MyList[U] = {
if(isEmpty) MyNil
// else new ::(func(head), tail.map(func))
else func(head) :: tail.map(func) // cannot resolve symbol ::
}
}
case object MyNil extends MyList[Nothing] {
override def isEmpty: Boolean = true
override def tail: MyList[Nothing] = throw new NoSuchElementException("tail of MyNil")
override def head: Nothing = throw new NoSuchElementException("head of MyNil")
}
final case class ::[T](val head: T, val tail: MyList[T]) extends MyList[T] {
override def isEmpty: Boolean = false
}
object :: {
def apply[T](h: T, t: MyList[T]) = {
new ::(h, t)
}
}
}
编译器说它无法解析符号::
。如果我使用前缀版本而不是中缀版本(该行被注释掉),则没有错误。
我该如何解决这个问题?
答案 0 :(得分:3)
中缀表示法不适用于伴随对象的apply
方法。要使用中缀表示法,您必须在::
类中为MyList
提供方法定义。如果添加到MyList
:
def ::[U >: T](h: U): MyList[U] = {
new ::(h, this)
}
MyList
的结果定义如下:
abstract class MyList[+T] {
def isEmpty: Boolean
def head: T
def tail: MyList[T]
def length: Int = if(isEmpty) 0 else 1 + tail.length
def drop(n: Int): MyList[T] = {
if(isEmpty) MyNil
else tail.drop(n - 1)
}
def map[U](func: T => U): MyList[U] = {
if(isEmpty) MyNil
else func(head) :: tail.map(func)
}
def ::[U >: T](h: U): MyList[U] = {
new ::(h, this)
}
}
case object MyNil extends MyList[Nothing] {
override def isEmpty: Boolean = true
override def tail: MyList[Nothing] = throw new NoSuchElementException("tail of MyNil")
override def head: Nothing = throw new NoSuchElementException("head of MyNil")
}
final case class ::[T](val head: T, val tail: MyList[T]) extends MyList[T] {
override def isEmpty: Boolean = false
}