Scala:trait 中的方法不能使用来自伴生对象的方法 [英] Scala: methods in trait can't use methods from companion object

查看:42
本文介绍了Scala:trait 中的方法不能使用来自伴生对象的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我尝试编译以下内容时,我得到:未找到:值缺点"和未找到:值空"用于获取和删除方法定义.

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?

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

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

推荐答案

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

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
}

class A {
  private def foo: Unit = ()

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

  (new A).foo
}

(但如果你用 private[this] 替换 private ,前者也不起作用.)

(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
}

class A {
  private def foo: Unit = ()

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

  foo
}

无论如何,一个方法必须知道它的this.

Anyway a method has to know its this.

这篇关于Scala:trait 中的方法不能使用来自伴生对象的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆