Scala 2.12告诉我Stack已被弃用,如何完全替换它(以及为什么我没有在IntelliJ中看到正确的警告)

时间:2017-05-09 10:00:43

标签: scala intellij-idea

我设置了一个Scala项目并添加了http://www.scalatest.org/

中的这个代码段
import collection.mutable.Stack
import org.scalatest._

class ExampleSpec extends FlatSpec with Matchers {

  "A Stack" should "pop values in last-in-first-out order" in {
    val stack = new Stack[Int]
    stack.push(1)
    stack.push(2)
    stack.pop() should be (2)
    stack.pop() should be (1)
  }

  it should "throw NoSuchElementException if an empty stack is popped" in {
    val emptyStack = new Stack[Int]
    a [NoSuchElementException] should be thrownBy {
      emptyStack.pop()
    } 
  }
}

和IntelliJ(IDEA 2017.1.2)向我显示new Stack[Int]的使用警告:

enter image description here

搜索警告向我展示了这个问题: https://issues.scala-lang.org/browse/SI-9068

但我仍然有这些问题:

  1. 我得到一个分为两个区域的弹出窗口。这是否意味着有两个警告,每个警告有两行。什么是真实的信息?对于第二个区域,我看到参考必须加前缀正在建设中

  2. 为什么我没有看到正确的弃用警告,就像在此处添加的那样:https://github.com/scala/scala/pull/5260/files#diff-1ab096eae7e5571b6410a123567aac0aR57

  3. 在github / API文档上,他们说:Use a List assigned to a var instead但我无法用Stack替换List,因为.push()不适用于var那个班。或者我应该完全切换到List API?使用vallist.add(2)分配列表的区别是什么? 即使分配了val,我也无法通过scala> val stack = new Stack[Int] <console>:14: warning: class Stack in package mutable is deprecated (since 2.12.0): Stack is an inelegant and potentially poorly-performing wrapper around List. Use a List assigned to a var instead. val stack = new Stack[Int] ^ 添加项目吗?

  4. 我通过Homebrew安装了Scala 2.12.2。我不确定IntelliJ是否使用自己的版本,因为我需要通过IntelliJ下载它,但无论如何它是相同的版本,所以我的设置如下: enter image description here

    BTW:在终端/ Scala REPL中我得到了这个输出

    comments

    所以适当的弃用警告似乎在那里有用。

3 个答案:

答案 0 :(得分:5)

已弃用的消息

通常,当有不推荐使用的功能时,您只会看到您看到的一般回复。要获取详细消息,您应该使用-deprecation进行编译。要更改此使用设置 - >构建,执行,部署 - &gt;编译器 - &gt; scala编译器并检查相关选项(在您的情况下弃用警告,但其余大多数可能是一个好主意)

参考必须带有前缀警告

这是一个完全不相关的警告。使用可变类时,scala样式是使用mutable作为前缀。即使用这个:

import collection.mutable    
val a = new mutable.Stack[Int]

而不是

import collection.mutable.Stack    
val a = new Stack[Int]

这是因为scala中的默认思维模式通常应该是使用不可变集合,除非你有充分的理由不这样做。

如果这让您感到困扰,您可以随时关闭此检查。

该怎么做而不是堆栈

删除堆栈的原因是它只是一个包装列表。 Push只是添加了一个新的头部,而pop则只是添加了尾部。

这意味着如果你有:

val a = new mutable.Stack
a.push(XXX)
a.pop(XXX)

您可以将其替换为:

var a = new List
a = XXX +: a
a = a.tail

请注意,一般情况下,您可以在此处使用不可变列表。

修改

为了确保它更容易理解,在var a = new List中创建的List应替换为实际的list列表。

标准方法是使用标准的scala创建方法,例如:

var a = List[Int]()  
var a: List[Int] = Nil 

但如果需要更多功能,也可以根据需要选择其他具体列表。

答案 1 :(得分:0)

ListBuffer是很好的替代方法,因为它提供了恒定的时间前置和删除。 mutable.List是另一种选择。有关详细信息,请参见https://stackoverflow.com/a/5753935/839733

答案 2 :(得分:0)

  

与为列表分配var或val有什么区别?   即使分配了清单,我也无法通过list.add(2)添加物件   val?

您可以为val分配一个可变的ListBuffer(它们不会使可变列表),或为var分配一个常规的不可变列表。这取决于您,但是使用不可变数据结构更具功能性。我认为这是您的问题的一部分,@ abhijit-sarkar正在解决。

  <Capabilities>
    <uap:Capability Name="removableStorage" />
    <DeviceCapability Name="microphone" />
  </Capabilities>

实施流行音乐留给读者练习。