Scala 不考虑方法参数的默认值

Scala 不考虑方法参数的默认值,scala,methods,default-value,Scala,Methods,Default Value,我已经在“Empty”caseobject和“Top”case类中为参数“currentStack”提供了默认值,但是如果我在调用push方法时调用该参数,我会得到以下消息 "error: not enough arguments for method push: (newTop : A, currentStack: Main.Stack[A])Main.Stack[A]. Unspecified value parameter currentStack.

我已经在“Empty”caseobject和“Top”case类中为参数“currentStack”提供了默认值,但是如果我在调用push方法时调用该参数,我会得到以下消息

"error: not enough arguments for method push: (newTop
: A, currentStack: Main.Stack[A])Main.Stack[A].
Unspecified value parameter currentStack.
                    currentBracket == '{') isBracketingValid(rest, bracketStack.push(currentBracket))".
我尝试过构造一个空堆栈和一个已经填充的堆栈,并对它们调用push方法,它可以添加一个元素。当我试图通过进一步的推送调用添加另一个元素时,我得到了上面的错误消息

lazy val s1 = Empty

println(s1.push(1)) // <- works

//println(s1.push(1).push(2)) <- doesn't work

lazy val s2 = Top(3, Top(4, Empty))

println(s2.push(1)) // <- works

//println(s2.push(1).push(2)) <- doesn't work
编辑

在Luis提示使用“this”之后重写了堆栈定义,因此不,它不会导致上述问题,因为没有传入堆栈,但我仍然对理解原因感兴趣

sealed trait Stack[+A] {
    def push[A] (newTop: A): Top[A] = ???

    def pop: (Option[A], Stack[A]) = ???
}

case object Empty extends Stack[Nothing] {
    override def push[A] (newTop: A): Top[A] = Top(newTop, this)

    override def pop: (Option[Nothing], Stack[Nothing]) = (None, Empty)
}

case class Top[A](val top: A, val rest: Stack[A]) extends Stack[A] {
    override def push[A] (newTop: A): Top[A] = Top(newTop, this.asInstanceOf[Stack[A]])

    override def pop: (Option[A], Stack[A]) = (Some(top), rest)
}
编辑2

由于Luis的洞察力,重构了堆栈定义,不使用“asInstanceof”,而是使用较低的类型界限来实现目标。还检查了为什么案例分类通常应该是最终的

sealed trait Stack[+A] {
    def push[B >: A] (newTop: B): Top[B] = ???

    def pop: (Option[A], Stack[A]) = ???
}

case object Empty extends Stack[Nothing] {
    override def push[A] (newTop: A): Top[A] = Top(newTop, this)

    override def pop: (Option[Nothing], Stack[Nothing]) = (None, Empty)
}

final case class Top[+A] (val top: A, val rest: Stack[A]) extends Stack[A] {
    override def push[B >: A] (newTop: B): Top[B] = Top(newTop, this)

    override def pop: (Option[A], Stack[A]) = (Some(top), rest)
}

所以,总结一下。问题是,即使在您的两个子类中,您已经覆盖了
push
方法,使其具有默认值。
trait上的方法签名没有此类默认值。而且,由于这是您正在调用的,编译器发出了正确的错误。
您可以进行模式匹配,以了解您使用的是
Stack
的哪种特定情况,这样编译器就可以找到具有默认值的签名。但是,由于默认值始终是一个
堆栈,其形状与this相同,并且由于您真正需要的是只使用this(因为作为一个不可变的集合,您可以进行结构共享),因此最好只重写该方法

下面是您的
堆栈的实现,它更加简洁和简单(IMHO)


为什么要将
堆栈
传递给
堆栈
方法?构造一个新堆栈,从而确保调用该方法的堆栈保持不变。我仍然无法获取它。您总是想要
这个
,然后返回一个新的,它共享这个。因为堆栈是不可变的,所以这不会是问题。这就像一个普通的列表。Thx对于使用“this”关键字的提示,代码现在要简单得多,如果像这样重写,问题当然会消失,但我仍然想了解原因。你不应该使用
来代替
(如果你正在学习,你应该假设它不存在)。您可以这样重写
覆盖def push[B>:A](newTop:B):Stack[B]=Top(newTop,this)
(此外,您还应该在A中标记
Top
类协变。-
最终案例类Top[+A]…
)-现在的问题是,即使您的两个覆盖都有默认值,trait本身的方法也没有默认值,这就是您正在调用的方法。再次感谢您的回答和额外的指导。pop方法的最终版本中有一个小错误,顶部必须在某个()类中。@Mahmoud Right,快速复制和粘贴,抱歉。不客气。
sealed trait Stack[+A] {
    def push[B >: A] (newTop: B): Top[B] = ???

    def pop: (Option[A], Stack[A]) = ???
}

case object Empty extends Stack[Nothing] {
    override def push[A] (newTop: A): Top[A] = Top(newTop, this)

    override def pop: (Option[Nothing], Stack[Nothing]) = (None, Empty)
}

final case class Top[+A] (val top: A, val rest: Stack[A]) extends Stack[A] {
    override def push[B >: A] (newTop: B): Top[B] = Top(newTop, this)

    override def pop: (Option[A], Stack[A]) = (Some(top), rest)
}
sealed trait Stack[+A] {
  final def push[B >: A](newTop: B): Stack[B] =
    Top(newTop, this)

  final def pop: (Option[A], Stack[A]) = this match {
    case Top(top, rest) => (Some(top), rest)
    case Empty          => (None, Empty)
  }
}

final case class Top[+A](top: A, rest: Stack[A]) extends Stack[A]
case object Empty extends Stack[Nothing]