1

我想检查构造函数参数并拒绝构造 throwing IllegalArgumentException,以防参数集无效(值不符合预期的约束)。在修改对象时设置相同的参数集时,同样的检查应该起作用。如何在 Scala 中编写代码?

  scala> class Rectangle (var Length:Double, var Width:Double){
   | if (Length <0)
   | throw new IllegalArgumentException("The Length must be Non-negative")
   | if (Width <0)
   | throw new IllegalArgumentException("The Width must be Non-negative")
   | def setLength(l:Double) = Length = l
   | }
  defined class Rectangle

  scala> var R = new Rectangle (-9, -9)
  java.lang.IllegalArgumentException: The Length must be Non-negative
at Rectangle.<init>(<console>:9)

  scala> var R = new Rectangle (0, -9)
  java.lang.IllegalArgumentException: The Width must be Non-negative
at Rectangle.<init>(<console>:11)



   scala> var R = new Rectangle(9, 9)
   R: Rectangle = Rectangle@1590164


   scala> R.Length
   res7: Double = 9.0

   scala> R.Width
   res8: Double = 9.0

   scala> R.setLength(18)

   scala> R.Length
   res10: Double = 18.0

   scala> R.setLength(-9)
   // R.setLength should not the set the Length to -9.   **************************
   scala> R.Length
   res12: Double = -9.0
4

4 回答 4

2

您需要一个属性设置器/获取器方法。

class Rectangle(private var l: Int, private var w: Int) {
  require(l > 0, "Invalid length: " + l + " <0 ")
  require(w > 0, "Invalid width: " + w + " <0 ")
  def length = l
  def width = w
  def length_=(len: Int) { require(len > 0, "Invalid length: " + len + " < 0"); l = len }
  def width_=(wid: Int) { require(wid > 0, "Invalid width: " + wid + " < 0"); w = wid }
  override def toString = length + ", " + width
}
于 2012-06-02T10:27:33.740 回答
2

它必须是可变的吗?

case class Rectangle(length:Double, width:Double) {
  if (length < 0)
    throw new IllegalArgumentException("The Length must be Non-negative")
  if (width < 0)
    throw new IllegalArgumentException("The Width must be Non-negative")
  def setLength(l: Double) = copy(length=l)
}
于 2012-06-02T10:27:35.143 回答
2

可变状态是个坏主意,但如果您确实需要它并且不想要两点验证,您可以使用Prince John Wesley的稍微修改的解决方案:

class Rectangle(l: Int, w: Int) {

  private[this] var _length: Int = _
  private[this] var _width: Int = _
  def length: Int = _length
  def width: Int = _width
  def length_=(len: Int) { require(len > 0, "Invalid length: " + len + " < 0"); _length = len }
  def width_=(wid: Int) { require(wid > 0, "Invalid width: " + wid + " < 0"); _width = wid }

  length = l
  width = w

  override def toString = length + ", " + width
}
于 2012-06-02T19:48:59.453 回答
2

我不喜欢到目前为止提到的答案。您的问题是参数必须有效才能创建对象。其他解决方案中止对象创建,但在我看来,您真正想要的不是中止,而是在创建对象之前进行一些检查。要实现这一点,您需要工厂:

object Rectangle {
  def apply(length:Double, width:Double): Rectangle = {
    require(length >= 0, "The Length must be Non-negative")
    require(width >= 0, "The Width must be Non-negative")
    new Rectangle(length, width)
  }
}
class Rectangle private(val length:Double, val width:Double) {
  def length_=(l: Double) = Rectangle(l, width)
}

这里唯一的问题是,当我们想要定义自己的 apply-Method(与类构造函数具有相同的方法签名)时,我们不允许创建案例类。

于 2012-06-02T22:03:52.627 回答