2
  def random[T](array: Array[(T, Double)]): T = {
    var total: Double = 0
    array.foreach(x => total += x._2)

    if (total > 1)
      throw new IllegalArgumentException("The total ratio shouldn't greater than 1.")

    val ratio = rand.nextDouble()
    var min: Double = 0
    var max: Double = 0

    var theOne:T = null // error here !!!

    array.foreach {
      x =>
        max += x._2
        if (ratio > min && ratio <= max)
          theOne = x._1

        min += x._2
    }

    theOne
  }

この問題を回避するにはどうすればよいですか?

4

3 に答える 3

2

オプションタイプを使用できます:

  def random[T](array: Array[(T, Double)]): Option[T] = {
var total: Double = 0
array.foreach(x => total += x._2)

if (total > 1)
  throw new IllegalArgumentException("The total ratio shouldn't greater than 1.")

val ratio = rand.nextDouble()
var min: Double = 0
var max: Double = 0

var theOne:Option[T] = None

array.foreach {
  x =>
    max += x._2
    if (ratio > min && ratio <= max)
      theOne = Some(x._1)

    min += ratio
}

theOne
}

マッチ式

def show[T](x: Option[T]) = x match {
 case Some(s) => s
 case None => null
}

val res = random...
show(res)
于 2012-08-30T10:47:21.097 に答える
1

ここでの問題は、null が型 T の有効な値であることを保証していないことです。Scala の型階層は次のように始まります。

どれでも

AnyVal extends Any // null は不可

AnyRef extends Any // null の可能性あり

型 T を何らかの方法で制約していないため、T が anyval (Int や Double など) のサブクラスではないという保証はなく、したがって null を割り当てることはできません。簡単な解決策は、 null を _ に置き換えることです...

class Container[T] {
    var t: T = _
}

これにより、Scala コンパイラは _ を T の適切なデフォルト値 (参照型の場合は null) に置き換えます。

于 2012-08-30T18:02:14.287 に答える
0

高速なコードが必要な場合は、使用しないでくださいforeach。それ以外の場合は、次のようにして、2 番目のタプル要素に比例して描画できます。

def random[T](array: Array[(T, Double)]): T = {
  val cumulative = array.scanLeft(0d)(_ + _._2)
  val pick = rand.nextDouble() * cumulative.last

  array.
var min: Double = 0
var max: Double = 0

var theOne:T = null // error here !!!

array.foreach {
  x =>
    max += x._2
    if (ratio > min && ratio <= max)
      theOne = x._1

    min += ratio
}

theOne

}

于 2012-08-30T19:44:22.333 に答える