2012-04-04 84 views
5

我想弄清楚這個問題,並嘗試了我在Scala上閱讀過的不同樣式,但沒有一個能夠工作。我的代碼是:爲什麼我的Scala函數返回類型Unit而不是最後一行是什麼?

.... 

val str = "(and x y)"; 

def stringParse (exp: String, pos: Int, expreshHolder: ArrayBuffer[String], follow: Int) 

    var b = pos; //position of where in the expression String I am currently in 
    val temp = expreshHolder; //holder of expressions without parens 
    var arrayCounter = follow; //just counts to make sure an empty spot in the array is there to put in the strings 

    if(exp(b) == '(') { 
     b = b + 1; 

     while(exp(b) == ' '){b = b + 1} //point of this is to just skip any spaces between paren and start of expression type 

     if(exp(b) == 'a') { 
       temp(arrayCounter) = exp(b).toString; 
       b = b+1; 
       temp(arrayCounter)+exp(b).toString; b = b+1; 
       temp(arrayCounter) + exp(b).toString; arrayCounter+=1} 
       temp; 

     } 

} 

val hold: ArrayBuffer[String] = stringParse(str, 0, new ArrayBuffer[String], 0); 
for(test <- hold) println(test); 

我的錯誤是:

Driver.scala:35: error: type mismatch; 
found : Unit 
required: scala.collection.mutable.ArrayBuffer[String] 
ho = stringParse(str, 0, ho, 0); 
       ^one error found 

當我添加方法聲明的參數後等號,就像這樣:

def stringParse (exp: String, pos: Int, expreshHolder: ArrayBuffer[String], follow: Int) ={....} 

它它改變「任何」。我很困惑這是如何工作的。有任何想法嗎?非常感激。

+1

+1對於新手總是會面對的事情+1。這個解釋也有點反直覺。 – aitchnyu 2012-04-04 06:41:50

回答

8

如果您想返回一個值,您必須添加等號。現在,你的函數的返回值是Any的原因是你有兩條控制路徑,每條返回一個不同類型的值-1當if條件滿足時(並且返回值將是temp),另一條是when如果條件不是(並且返回值將是b = b + 1,或b在它增加後)。

+0

如果if不被滿足,爲什麼返回值是b = b + 1?但我明白你的意思。在java中它不是這樣,所以它認爲scala包含其他情況很奇怪。 – Andy 2012-04-04 05:31:43

+0

不要介意爲什麼b = b + 1。這就說得通了。我在這裏對它進行了不同的格式化,所以當我在編輯器中查看它時,它是有道理的。感謝您指點我正確的方向! – Andy 2012-04-04 05:33:12

+0

首先,如果if條件不滿足,您必須決定從函數返回的值。然後你可以在if之前「使用」該值,或者添加一個else子句並將其放在那裏。 – 2012-04-04 05:41:55

9

這裏有一個關於如何之一可能接近這樣的問題更普遍的答案:

有時會發生你編寫一個函數,在你的腦袋承擔返回式X,但下山的路某處編譯器不同意。這幾乎總是在函數剛剛寫入時發生,因此,雖然編譯器不會給你實際的源代碼(它指向的是調用函數的那一行代替),但通常你知道函數的返回類型是問題。

如果您沒有立即看到類型問題,那麼顯式鍵入您的函數就有一個簡單的技巧。例如,如果你認爲你的函數應該返回Int,但是不知何故編譯器說它找到了Unit,它有助於將: Int添加到你的函數中。這樣,你可以幫助編譯器幫助你,因爲它會發現確切的地方,函數中的路徑返回一個非Int值,這是你首先要查找的實際問題。

+0

謝謝。是的,我嘗試過,但它仍然給我錯誤。我認爲這可能是一個問題,但它並沒有解決問題,至少對於我的問題。就其他情況而言,肯定會有所幫助。我對這門語言很陌生,我很欣賞這種投入。 – Andy 2012-04-04 20:18:01

0
class Test(condition: Boolean) { 

    def mixed = condition match { 
    case true => "Hi" 
    case false => 100 
    } 

    def same = condition match { 
    case true => List(1,2,3) 
    case false => List(4,5,6) 
    } 

    case class Foo(x: Int) 
    case class Bar(x: Int) 

    def parent = condition match { 
    case true => Foo(1) 
    case false => Bar(1) 
    } 
} 
val test = new Test(true) 

test.mixed // type: Any 
test.same // type List[Int] 
test.parent // type is Product, the case class super type 

編譯器將盡最大努力運用它可以根據可能的結果集類型的最具體類型從條件返回(匹配的if/else,褶皺等)。

相關問題