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
}
如何避免此问题?
答案 0 :(得分: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)
答案 1 :(得分:1)
这里的问题是你没有保证null是类型T的有效值.Scala的类型层次结构是这样开始的。
任何
AnyVal extends Any //不能为null
AnyRef extends Any //可以为null
因为你没有以任何方式约束类型T,所以它不能保证T不是anyval的子类(如Int或Double),因此不能允许你赋值null。一个简单的解决方案是将_替换为_,如此...
class Container[T] {
var t: T = _
}
这将使Scala编译器用适当的T默认值替换_(引用类型为null)。
答案 2 :(得分: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
}