2012-08-30 30 views
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 
    } 

如何避免此問題?scala只有類可以聲明但不確定的成員

+1

解決這個最簡單的方法是做'null.asInstanceOf [T]'。如果你想得到更好的答案(即描述如何改進你的代碼真的很難看的答案),你應該描述你想要做的事情。目前你的代碼沒什麼意義,因爲比例> min'永遠不會是真的,但是對於第一個元素。 – sschaef

+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) 
+3

您可以使用'res getOrElse null'而不是'match'。 – senia

+0

@senia謝謝。你是對的。 –

+1

@Ben Kyrlach你不能指定** var theOne:T = _ **,因爲它的局部變量。 –

1

這裏的問題是,你不提供保證null是一個有效的價值爲鍵入T. Scala的類型層次結構像這樣開始。

任何

AnyVal延伸的任何//不能爲空

AnyRef延伸的任何//可以爲空

因爲你沒有限制以任何方式類型T,它沒有保證T不是anyval的子類(如Int或Double),因此不能讓您指定null。一個簡單的辦法是更換空_這樣的...

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

這將使得Scala編譯器更換_與對於T適當的默認值(NULL引用類型)。

+1

var theOne:T = _仍然無法編譯。 –

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 

}

相關問題