【问题标题】:Scala constructor overloading parameter is not taking effectScala构造函数重载参数不生效
【发布时间】:2019-09-12 18:38:03
【问题描述】:

我试图了解我实现构造函数重载的方式有什么问题。我想在具有同名成员的类中添加一个接受参数count 的构造函数。

我们的想法是根据默认构造函数参数之一计算 count,除非它通过重载构造函数传递。我稍后会显示代码。

为了说服自己这可行,我构建了一个快速简单的测试:

import org.scalatest.FunSuite

class ConstructorOverloadTest extends FunSuite {

  test("Overload parameter shadows class member") {
    val actual = new TestME(200).length

    200 === actual
    1 !==  actual
  }

  class TestME(name:String) {
    val length = name.length

    def this(length:Int) = {
      this("*")
    }
  }
}

测试按预期通过。这让我明白了重载构造函数参数length阴影/替换了类成员length

但是当我在另一个类中做同样的事情时,类成员不会被隐藏/替换。

class MyClass(input1: Array[Float], input2: Array[Byte], input3: Array[Float]) {

  val count = input2.length

  val index = doSomething()

  def this(count: Int) = {
    this(Array(), Array(), Array())
  }


  def printCount() = {
    if (this.count == 0)
      println("ZERO")
    else
      println("OTHER")
  }
}

当我如下使用这个类时

val myInstance = new MyClass(200)
myInstance.printCount()

我希望它将OTHER 打印到屏幕上。相反,它打印ZERO

为什么?

【问题讨论】:

    标签: scala unit-testing constructor scalatest constructor-overloading


    【解决方案1】:

    您的测试似乎有问题。 new TestME(200).length 返回1,说明构造函数参数实际上并没有覆盖length

    class TestME(name:String) {
      val length = name.length
    
      def this(length:Int) = {
        this("*")
      }
    }
    
    println(new TestME(200).length)
    
    1
    

    每个summerbulb的cmets:

    1. 测试的断言应该被包裹在assert:

      // Closer to correct...
      assert(200 === actual)
      assert(1 !==  actual)
      
    2. 实际值和预期值应按此顺序传递:

      // Correct!
      assert(actual === 200)
      assert(actual !== 1)
      

    【讨论】:

    • 谢谢。测试确实是不正确的。应该是assert(200 === actual),然后测试失败。 |感觉很笨|
    • @summerbulb 啊,有道理。不要出汗,额外的眼睛总是有帮助的!
    • 如果更准确一点,实际和预期的顺序相反:assert(actual === 200)
    猜你喜欢
    • 1970-01-01
    • 2013-09-08
    • 2021-09-14
    • 1970-01-01
    • 2013-03-16
    • 2012-11-30
    • 2011-01-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多