问题
When I try to compile the following I get: "not found: value cons" and "not found: value empty" for the take and drop method definitions.
Somehow the trait doesn't "see" the companion object?
I'm using IntelliJ IDEA, in case that matters.
import scala.annotation.tailrec
object Run extends App {
sealed trait StreamRed[+A] {
def headOption: Option[A] = this match {
case Empty => None
case Cons(h,t) => Some(h())
}
def toList: List[A] = {
@tailrec
def toListRec(stream: StreamRed[A], accumulated: List[A]): List[A] = this match {
case Cons(h,t) => toListRec(t(), h()::accumulated)
case _ => accumulated
}
toListRec(this, List()).reverse
}
def take(n: Int): StreamRed[A] = this match {
case Cons(h, t) if n > 1 => cons(h(), t().take(n - 1))
case Cons(h, _) if n == 1 => cons(h(), empty)
case _ => empty
}
@tailrec
def drop(n: Int): StreamRed[A] = this match {
case Cons(_,t) if n > 0 => t().drop(n-1)
case _ => empty
}
}
case object Empty extends StreamRed[Nothing]
case class Cons[+A](h: () => A, t: () => StreamRed[A]) extends StreamRed[A]
object StreamRed {
def cons[A](hd: => A, tl: => StreamRed[A]): StreamRed[A] = {
lazy val head = hd
lazy val tail = tl
Cons(() => head, () => tail)
}
def empty[A]: StreamRed[A] = Empty
def apply[A](as: A*): StreamRed[A] =
if (as.isEmpty) empty else cons(as.head, apply(as.tail: _*))
}
}
回答1:
Companions can see each other's members in the sense that access modifiers are not a problem.
class A {
private def foo: Unit = ()
A.bar
}
object A {
private def bar: Unit = ()
(new A).foo
}
is ok on contrary to
class A {
private def foo: Unit = ()
B.bar
}
object B {
private def bar: Unit = ()
(new A).foo
}
(But if you replace private
with private[this]
the former won't work either.)
But this doesn't mean that namespaces are imported automatically.
class A {
private def foo: Unit = ()
import A._
bar
}
object A {
private def bar: Unit = ()
val a = new A
import a._
foo
}
is ok on contrary to
class A {
private def foo: Unit = ()
bar
}
object A {
private def bar: Unit = ()
foo
}
Anyway a method has to know its this
.
来源:https://stackoverflow.com/questions/59662424/scala-methods-in-trait-cant-use-methods-from-companion-object