2012-04-04 10 views
5

Estoy tratando de resolver el problema, y ​​probé diferentes estilos que he leído en Scala, pero ninguno de ellos funciona. Mi código es:¿Por qué mi función Scala vuelve al tipo Unidad y no a la última línea?

.... 

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); 

Mi error es:

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

Cuando agrego un signo igual después de los argumentos en la declaración del método, así:

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

Cambia a "Alguna". Estoy confundido sobre cómo funciona esto. ¿Algunas ideas? Muy apreciado.

+1

+1 por algo que un newb siempre enfrentará. La explicación también es un poco contraintuitiva también. – aitchnyu

Respuesta

8

Tiene que agregar el signo igual si desea devolver un valor. Ahora, la razón por la cual el valor de retorno de su función es Cualquiera es que tiene 2 rutas de control, cada una devolviendo un valor de un tipo diferente - 1 es cuando se cumple la condición de si (y el valor de retorno será temporal) y el otro es cuando si la condición no es (y el valor de retorno será b = b + 1, o b después de que se incremente).

+0

¿Por qué el valor de retorno sería b = b + 1 si no se cumple? Pero veo lo que quieres decir. En java no es así, por lo que es extraño pensar que Scala incluye los otros casos. – Andy

+0

No importa el por qué b = b + 1. Eso tiene sentido. He formateado de forma diferente aquí, así que cuando lo miré en mi editor, tenía sentido. ¡Gracias por señalarme en la dirección correcta! – Andy

+0

En primer lugar, debe decidir qué valor desea devolver de la función en caso de que no se cumpla la condición. Entonces puede "usar" ese valor antes de la cláusula if o agregar una else y ponerlo allí. –

9

Aquí es una respuesta más general sobre cómo se puede abordar este tipo de problemas:

A veces sucede que se escribe una función y en su cabeza asuma que regresa tipo X, pero en algún lugar en el camino que el compilador no está de acuerdo. Esto casi siempre ocurre cuando la función acaba de escribirse, por lo que aunque el compilador no le proporcione la fuente real (apunta a la línea a la que se llama su función) normalmente sabrá que el tipo de devolución de la función es el problema.

Si no ve el problema del tipo de inmediato, existe el truco simple para escribir explícitamente su función. Por ejemplo, si creía que su función debería haber devuelto Int, pero de alguna manera el compilador dice que encontró un Unit, ayuda agregar : Int a su función. De esta forma, ayudas al compilador a ayudarte, ya que detectará el lugar exacto, donde una ruta en tu función devuelve un valor que no es Int, que es el problema real que estabas buscando en primer lugar.

+0

Gracias. Sí, lo intenté, pero aún así me dio el error. Supuse que podría haber sido un problema, pero no lo resolvió, al menos para mi problema. En términos de otras situaciones que definitivamente hubieran ayudado. Soy nuevo en el lenguaje y aprecio la entrada. – Andy

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 

El compilador hará todo lo posible para aplicar el tipo más específico que puede basado en el conjunto posible de tipos de resultados devueltos desde el condicional (partido, if/else, doblar, etc.).

Cuestiones relacionadas