【问题标题】:Scala: methods in trait can't use methods from companion objectScala:特征中的方法不能使用来自伴随对象的方法
【发布时间】:2020-01-09 10:57:31
【问题描述】:

当我尝试编译以下内容时,我得到: “未找到:值缺点”和“未找到:值空”用于 take 和 drop 方法定义。

不知何故,特征没有“看到”伴随对象?

我正在使用 IntelliJ IDEA,以防万一。

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: _*))
  }
}

【问题讨论】:

  • import StreamRed._ 放在 trait 的顶部可以解决这个问题。
  • 谢谢,我是 Scala 新手。我认为它会“自动”工作,因为它是一个伴生对象,还是仅适用于类+伴生对象,而不是特征?我也尝试将导入放在整个事情的顶部,但没有奏效。

标签: scala companion-object


【解决方案1】:

在访问修饰符不是问题的意义上,同伴可以看到彼此的成员。

class A {
  private def foo: Unit = ()

  A.bar 
}
object A {
  private def bar: Unit = ()

  (new A).foo
}

正好相反

class A {
  private def foo: Unit = ()

  B.bar 
}
object B {
  private def bar: Unit = ()

  (new A).foo
}

(但如果将private 替换为private[this],则前者也不起作用。)

但这并不意味着命名空间是自动导入的。

class A {
  private def foo: Unit = ()

  import A._
  bar
}
object A {
  private def bar: Unit = ()

  val a = new A
  import a._
  foo
}

正好相反

class A {
  private def foo: Unit = ()

  bar
}
object A {
  private def bar: Unit = ()

  foo
}

无论如何方法必须知道它的this

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多