1

コンストラクターの引数をチェックし、引数セットが有効でない場合 (値が予想される制約に適合しない場合) に 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

私はこれまでに述べた答えが好きではありません。問題は、オブジェクトを作成するにはパラメータが有効でなければならないということです。他の解決策はオブジェクトの作成を中止しますが、私の意見では、本当に必要なのは中止ではなく、オブジェクトの作成前のいくつかのチェックです。これを実現するには、工場が必要です。

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 に答える
2

ミュータブルな状態は悪い考えですが、それが必要で 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 に答える