2011-06-20 12 views
10

Estoy tratando de obtener una función para compilar/trabajar en Scala, y obtener varios mensajes de error totalmente inanes que no puedo encontrarle sentido. Si escribo mi código como este:Errores básicos de Scala que no tienen sentido

def checkUniqueReviewNumber(number: String): Boolean = { 
    val qc = new QualityClient 
    if(review.isEmpty) 
     false 
    else { 
     val qrList = qc.listInPL(Vars.currentPLId.get.get,null,null,null,null,null,null,false,false,CurrentUser.getUser.key).qualityReviews 
     !qrList.exists(qr:QualityReview => qr.reviewNumber == number) 
    } 
    } 

me sale el error:

.../QualityReviewCreate.scala:189: error: not found: type == 
    [scalac]  !qrList.exists(qr:QualityReview => qr.reviewNumber == number) 

Y si escribo el código de la misma familia:

def checkUniqueReviewNumber(number: String): Boolean = { 
    val qc = new QualityClient 
    if(review.isEmpty) 
     false 
    else { 
     val qrList = qc.listInPL(Vars.currentPLId.get.get,null,null,null,null,null,null,false,false,CurrentUser.getUser.key).qualityReviews 
     !qrList.exists(qr:QualityReview => qr.reviewNumber.equals(number)) 
    } 
    } 

consigo los errores:

... /QualityReviewCreate.scala:189: error: ')' expected but '(' found. 
    [scalac]  !qrList.exists(qr:QualityReview => qr.reviewNumber.equals(number)) 
    [scalac]                ^
    ... /QualityReviewCreate.scala:189: error: ';' expected but ')' found. 
    [scalac]  !qrList.exists(qr:QualityReview => qr.reviewNumber.equals(number)) 
    [scalac]                  ^
    [scalac] two errors found 

Los tipos implicados pueden estar contribuyendo g aquí, pero si es así, estoy absolutamente confundido sobre por qué. qrList debe ser una Java ArrayList de QualityReview, que es un objeto java con un campo java String llamado reviewNumber.

¿Alguien entiende lo que está pasando aquí?

Respuesta

22

El problema es que el análisis de Scala para funciones anónimas con tipos de argumentos explícitos es ambiguo, y en ocasiones eso lleva a algunos caprichos muy extraños. Este es uno de ellos. Tome la siguiente expresión:

(qr:QualityReview => qr.reviewNumber == number) 

Scala es (aparentemente) el análisis de la siguiente manera:

(qr:(QualityReview => qr.reviewNumber == number)) 

Esto no es lo que quería. De hecho, ni siquiera es una función anónima. Desugaring la expresión se obtiene la siguiente:

(qr: Function1[QualityReview, ==[qr.reviewNumber, number]]) 

Así, en otras palabras, estamos atribuyendo un tipo de qr, donde ese tipo está dada por Function1 parametrizada con QualityReview y el tipo determinado por == parametrizado por los tipos qr.reviewNumber y number . Todo esto es válido para Scala, y sospecho que nada de eso es lo que pretendías.

El error se produce cuando Scala va en busca de un tipo con el nombre ==, que por supuesto no lo encuentra (que podría existir, pero no lo hace). Si hubiera pasado ese error, se habría topado rápidamente con problemas para encontrar los tipos qr.reviewNumber y number.

Hay varias formas de evitar este problema. En general, recomendaría utilizar un estilo ligeramente diferente al declarar sus funciones. El Scala Style Guide es un buen lugar para comenzar. En el caso de esta función, la forma más fácil de solucionar el problema es soltar la anotación de tipo (QualityReview). También puede resolver el problema poniendo paréntesis alrededor de qr:QualityReview. Además, creo que un espacio después del colon podría solucionar el problema, aunque no estoy seguro. Finalmente, el uso de llaves en vez de paréntesis generalmente hace que el compilador prefiera interpretar => como un delimitador lambda en lugar de un tipo. Yo habría escrito su exists expresión de la siguiente manera:

!(qrList exists { qr => qr.reviewNumber == number }) 

En realidad, probablemente habría usado la sintaxis de los guiones, pero eso es una cuestión totalmente diferente.:-)

!(qrList exists { _.reviewNumber == number }) 
Cuestiones relacionadas