2012-04-04 85 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,褶皱等)。

相关问题