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 //不能为空

AnyRef extends Any //可以为空

因为您没有以任何方式限制类型 T,所以它不能保证 T 不是 anyval 的子类(如 Int 或 Double),因此不能允许您分配 null。一个简单的解决方案是用 _ 替换 null ,就像这样......

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

这将使 Scala 编译器将 _ 替换为 T 的适当默认值(引用类型为 null)。

于 2012-08-30T18:02:14.287 回答
0

如果您想拥有快速代码,请不要使用foreach. 否则,您可以执行以下操作以与第二个元组元素成比例地绘制:

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 回答