2010-07-14 2 views
3

Ce ne compile pas avec Scala 2.7.7.final ou 2.8.0.final pour moi:Pourquoi ai-je besoin de crochets pour cette fonction nullaire dans cette expression Scala?

new FileInputStream("test.txt") getChannel transferTo(
    0, Long.MaxValue, new FileOutputStream("test-copy.txt") getChannel) 

Ce ne compile avec Scala 2.7.7.final et 2.8.0.final pour moi:

new FileInputStream("test.txt") getChannel() transferTo(
    0, Long.MaxValue, new FileOutputStream("test-copy.txt") getChannel) 

Pourquoi est-ce que je dois faire getChannel() au lieu de simplement getChannel ici?

+0

Est-ce que getChannel est une méthode? –

+1

En supposant que vous utilisez Java FileIn/OutputStreams, même le deuxième exemple ne compile pas ici car les arguments de 'transferTo' sont hors service. Vouliez-vous placer le canal de FileOutputStream à la queue de la liste d'arguments de 'transferTo' au lieu de la tête? Cela compile ici. –

+0

Merci Dan. J'ai corrigé le code dans ma question. C'est un cas de code dans mon éditeur par rapport au code dans mon carton. Je serai plus prudent avec le code que je posterai à l'avenir :) –

Répondre

3

La raison est très simple. . Si vous utilisez des espaces au lieu de celui à la méthode de la chaîne appelle ensuite:

a b c d  //is parsed as a call to 
(a.b(c))(d) 

Dans votre cas, les deux derniers paramètres sont appelés comme (parce que d est plus d'un paramètre, d, e et f disent) :

a b c(d, e, f) //is parsed as a call to 
a.b(c(d, e, f)) 

soit le même que dans le premier cas. Cependant, vous voulez que l'appel soit:

(a b).c(d, e, f) 

Ce qui n'est pas la même chose!

  • a = new FileInputStream("test.txt")
  • b = getChannel
  • c = transferTo
  • d = new FileOutputStream("test-copy.txt") getChannel
  • e = 0
  • f = Long.MaxValue

Cela n'a pas changé entre 2,7 et 2,8 jusqu'à un s Je suis au courant!

+0

Merci oxbox_lakes, le point 2.7/2.8 est précis. J'ai réessayé les deux cas en 2.7.7.final et 2.8.0.final et j'ai trouvé que le comportement était le même. J'ai modifié ma question pour refléter cela et limiter la confusion. –

+1

Je suis assez sûr que l'analyse est 'a.b (c (d, e, f))' - c'est à dire, appliquer une inférence sur les objets (paramètres) avant la résolution de l'opérateur. –

+1

Apoles pour l'erreur Daniel - fixé maintenant –

0

Je crois parce qu'il n'est pas clair pour le compilateur comment diviser les jetons. Est-ce new FileInputStream("test.txt")(getChannel, transferTo(...))? new (FileInputStream("test.txt"), getChannel, transferTo(...))? (new FileInputStream("test.txt")).getChannel(transferTo(...))? Le compilateur n'a pas assez d'informations pour savoir que transferTo est une propriété de l'objet renvoyé par getChannel.

Pour plus de clarté maximum que vous auriez quelque chose comme:

(new FileInputStream("test.txt")).getChannel().transferTo(
    (new FileOutputStream("test-copy.txt")).getChannel(), 0, Long.MaxValue) 
6

La règle générale est que le compilateur interprète des chaînes comme

new FileInputStream("test.txt") getChannel transferTo(...) 

comme

object method parameter method parameter method parameter 

donc dans votre cas, cela signifie que

new FileInputStream("test.txt") // object 
getChannel       // method 
transferTo(...)     // parameter 

de sorte que le compilateur essaie d'appeler transferTo en tant que fonction libre, il peut transmettre son résultat en paramètre à getChannel.Lorsque vous ajoutez les parenthèses, vous obtenez

new FileInputStream("test.txt") getChannel() transferTo(...) 

new FileInputStream("test.txt") // object 
getChannel       // method 
()         // parameter (empty parameter list) 
transferTo       // method 
(...)        // parameter 
Questions connexes