Quelles sont les règles précises quand vous pouvez omettre les parenthèses, les points, les accolades, = (fonctions), etc.?
Quelles sont les règles précises quand vous pouvez omettre (omettre) les parenthèses, les points, les accolades, = (fonctions), etc.?
Par exemple,
(service.findAllPresentations.get.first.votes.size) must be equalTo(2).
service
est mon objetdef findAllPresentations: Option[List[Presentation]]
votes
retourneList[Vote]
- doit et être sont à la fois les fonctions de spécifications
Pourquoi je ne peux pas aller:
(service findAllPresentations get first votes size) must be equalTo(2)
?
L'erreur de compilation est:
"RestServicesSpecTest.c'.service.findAllPresentations
de type
L'Option[Liste[com.sharca.Présentation]]
ne prend pas de paramètres"
Pourquoi il pense que je suis en train de passer un paramètre? Pourquoi dois-je utiliser des points pour chaque appel de méthode?
Pourquoi doit (service.findAllPresentations get first votes size)
être equalTo(2) résultat:
"non trouvé: valeur première"
Encore, les "doit être equalTo 2" de
(service.findAllPresentations.get.first.votes.size)
doit être equalTo 2, qui est, le chaînage de méthode fonctionne bien? - objet de la chaîne chaîne chaîne param.
J'ai regardé à travers la Scala livre et le site web et ne peut pas vraiment trouver une explication complète.
Est-il en fait, comme Rob H explique dans un Débordement de Pile question Les caractères qui puis-je omettre dans Scala?, que la seule valable en cas d'utilisation de l'omission d'un le". " est pour "opérande de l'opérateur opérande" opérations de style, et pas pour le chaînage de méthode?
Vous devez vous connecter pour publier un commentaire.
Vous semblez avoir tombé sur la réponse. De toute façon, je vais essayer de le rendre clair.
Vous pouvez omettre dot lors de l'utilisation du préfixe, infixe et postfix notations, ce que l'on appelle opérateur de notation. Alors que l'aide de l'opérateur de notation, et alors seulement, vous pouvez omettre les parenthèses s'il y a moins de deux paramètres passés à la méthode.
Maintenant, l'opérateur de la notation est une notation pour méthode d'appel, ce qui signifie qu'il ne peut pas être utilisé en l'absence de l'objet qui est appelé.
Je vais brièvement détail les notations.
Préfixe:
Seulement
~
,!
,+
et-
peut être utilisé en préfixe de notation. C'est la notation que vous utilisez lorsque vous écrivez!flag
ouval liability = -debt
.Infixe:
C'est la notation où la méthode apparaît entre un objet et ses paramètres. Les opérateurs arithmétiques tous ici.
Postfix (également suffixe):
Que la notation est utilisé lorsque la méthode suit un objet et ne reçoit pas de paramètres. Par exemple, vous pouvez écrire
list tail
, et c'est postfix notation.Vous pouvez la chaîne d'infixe notation des appels sans problème, tant qu'aucune méthode n'est au cari. Par exemple, j'aime utiliser le style suivant:
C'est la même chose que:
Maintenant, pourquoi suis-je à l'aide de parenthèses ici, si le filtre et la carte en prendre qu'un seul paramètre? C'est parce que je suis de passage des fonctions anonymes pour eux. Je ne peux pas mélanger les les fonctions anonymes définitions avec infixe de style parce que j'ai besoin d'une limite pour la fin de ma fonction anonyme. Aussi, la définition du paramètre de la fonction anonyme qui pourrait être interprété comme le dernier paramètre de la infix méthode.
Vous pouvez utiliser infixe avec plusieurs paramètres:
Fonctions curryfiées sont difficile à utiliser avec la notation infixe. Les fonctions de pliage sont un exemple clair de:
Vous devez utiliser des parenthèses à l'extérieur de l'infixe appel. Je ne suis pas sûr exactement les règles en jeu ici.
Maintenant, nous allons parler de postfix. Postfix peut être difficile à utiliser, car il ne peut jamais être utilisé n'importe où à l'exception de la fin de l'expression. Par exemple, vous ne pouvez pas effectuer les opérations suivantes:
Parce que la queue n'apparaît pas à la fin de l'expression. Vous ne pouvez pas le faire:
Vous pouvez utiliser la notation infixe en utilisant des parenthèses pour marquer la fin d'expressions:
Noter que postfix notation est découragé parce que il peut être dangereux.
J'espère que cela a effacé tous les doutes. Si non, il suffit de déposer un commentaire et je vais voir ce que je peux faire pour l'améliorer.
Définitions de classe:
val
ouvar
peuvent être omis dans les paramètres de classe qui permettra de rendre le paramètre privé.Ajoutant var ou val va l'amener à être public (c'est la méthode des accesseurs et des mutateurs sont générées).
{}
peut être omis si la classe n'a pas de corps, c'est -De l'instanciation de classe:
Générique paramètres peuvent être omis si elles peuvent être déduites par le compilateur. Toutefois, si vos types ne correspondent pas, alors le paramètre type est toujours inférer de sorte qu'il corresponde. Donc, sans en préciser le type, vous ne pouvez pas obtenir ce que vous attendez - que, compte tenu de
Cela vous donnera une erreur de type (Int trouvé, Chaîne attendue)
Alors que cela fonctionne bien:
Parce que le paramètre de type T, on déduit que la moins fréquente supertype des deux - Tout.
Des définitions de fonction:
=
peut être supprimé si la fonction renvoie l'Unité (rien).{}
pour le corps de la fonction peut être supprimé si la fonction est un seul état, mais seulement si l'instruction renvoie une valeur (vous avez besoin de la=
signe), qui est,mais cela ne fonctionne pas:
Le type de retour de la fonction peut être omise si elle peut être déduite (une méthode récursive doit avoir son type de retour spécifiée).
()
peut être supprimé si la fonction ne prend aucun argument, qui est,qui par convention est réservée à des méthodes qui n'ont pas d'effets secondaires - plus sur cela plus tard.
()
n'est pas réellement chuté en soi lors de la définition d'un passer par nom paramenter, mais il est en fait un assez sémantiquement différente de la notation, qui est,Dit pop prend un laissez-passer-par-nom de paramètre, ce qui résulte en une Chaîne de caractères (qui est, il peut être un bloc de code qui retourne une chaîne de caractères), par opposition aux paramètres de la fonction,
qui dit
myOp
prend une fonction qui a zéro des paramètres et retourne une Chaîne de caractères.(Vous l'esprit, passer par paramètres de nom compilé en fonctions; il est tout simplement la syntaxe plus agréable.)
()
peuvent être déposés dans le paramètre de la fonction de définition si la fonction ne prend qu'un seul argument, par exemple:Mais si elle a plus d'un argument, vous devez inclure le ():
États:
.
peuvent être déposés à l'utilisation de l'opérateur de notation, qui peut seulement être utilisé pour des opérateurs infixes (opérateurs de méthodes qui prennent des arguments). Voir La réponse de Daniel pour plus d'informations..
peut également être supprimée pour les fonctions de postfixliste de queue
()
peut être supprimée pour les opérateurs de suffixeliste.queue
()
ne peut pas être utilisé avec les méthodes définies comme suit:Parce que cette notation est réservée par la convention pour les méthodes qui n'ont pas d'effets secondaires, comme le numéro de Liste de la queue (qui est, l'invocation d'une fonction, sans effets secondaires signifie que la fonction n'a aucun effet observable, à l'exception de sa valeur de retour).
()
peut être abandonnée pour l'opérateur de notation lors du passage dans un seul argument()
peut être nécessaire d'utiliser postfix opérateurs qui ne sont pas à la fin d'une instruction()
peut être nécessaire de désigner des instructions imbriquées, les extrémités des fonctions anonymes, ou pour les opérateurs qui prennent plus d'un paramètreLorsque vous appelez une fonction qui prend une fonction, vous ne pouvez pas omettre le () de l'intérieur de la définition de la fonction, par exemple:
Lors de l'appel d'une fonction qui prend un paramètre de nom, vous ne pouvez pas spécifier l'argument comme un paramètre moins fonction anonyme. Par exemple, étant donné:
Vous devez l'appeler comme:
ou
mais pas:
De l'OMI, à la surutilisation de l'abandon des types de retour peuvent être nocifs pour le code pour être ré-utilisé. Il suffit de regarder la spécification pour un bon exemple de la réduction de la lisibilité en raison du manque d'informations explicites dans le code. Le nombre de niveaux d'indirection pour réellement comprendre ce que le type d'une variable est peut être les noix. Nous espérons de meilleurs outils possible d'éviter ce problème et de garder notre code concis.
(OK, dans la quête de compiler une plus complète, concise réponse (si j'ai oublié quelque chose, ou bien quelque chose de faux ou inexact s'il vous plaît commentaire), j'ai ajouté au début de la réponse. Veuillez noter que ce n'est pas un langage de spécification, donc je ne suis pas en train de faire exactement académiquement correct - juste plus comme une carte de référence.)
Une collection de citations de donner un aperçu sur les différentes conditions...
Personnellement, je pensais qu'il serais plus dans le cahier des charges. Je suis sûre qu'il doit être, je ne suis pas à la recherche pour les bons mots...
Il ya un couple de sources cependant, et j'ai recueilli leur ensemble, mais rien de vraiment complet /complet /compréhensible /qui explique les problèmes ci-dessus, pour moi...:
De le chapitre 2, "Type Moins, Faire Plus", de la Programmation Scala:
De chapitre 1, "de Zéro à Soixante: Introduction à Scala", de la Programmation Scala:
De blog Scala Syntaxe Apprêt:
À partir de la spécification du langage:
De Scala pour Java Réfugiés Partie 6: Arriver Sur Java:
Les caractères qui puis-je omettre dans Scala?
Mais également ce qui me confond est cette citation:
Car autant que je peux voir, il y a est un objet pour recevoir l'appel...
En fait, en deuxième lecture, c'est peut-être la clé:
Comme indiqué sur le post de blog: http://www.codecommit.com/blog/scala/scala-for-java-refugees-part-6 .
Alors peut-être que c'est en fait un très stricte de syntaxe "sucre" qui seulement œuvres où vous sont effectivement l'appel d'une méthode sur un objet, qui prend un paramètre. par exemple,
Et rien d'autre.
Cela expliquerait mes exemples dans la question.
Mais comme je l'ai dit, si quelqu'un pouvait point être exactement où, dans la langue spec c'est spécifiée, serait très apprécié.
Ok, certains gentil garçon (paulp_ de #scala) l'a souligné, où dans la langue spec de cette information est:
Hmm - pour moi, il n'a pas de maillage avec ce que je vois, ou je n'ai tout simplement pas le comprendre 😉
Il n'y en a pas. Vous serez susceptibles de recevoir des conseils autour de si oui ou non la fonction a des effets secondaires. C'est faux. La correction est de ne pas utiliser d'effets secondaires à l'raisonnable de la mesure permise par la Scala. Dans la mesure où il ne peut pas, alors tous les paris sont éteints. Tous paris. L'utilisation de parenthèses est un élément de l'ensemble "ensemble" et le superflu. Il ne fournit pas de valeur une fois que tous les paris sont éteints.
Ce conseil est essentiellement une tentative de effet système qui échoue (à ne pas confondre avec: il est moins utile que les autres de l'effet des systèmes).
Essayez de ne pas d'effets secondaires. Après cela, d'accepter que tous les paris sont éteints. Se cachant derrière une de facto syntaxique notation pour un effet de système peut et ne, seulement causer des dommages.
Je le trouve plus facile de suivre cette règle d'or: dans les expressions des espaces alterner entre les méthodes et les paramètres. Dans votre exemple,
(service.findAllPresentations.get.first.votes.size) must be equalTo(2)
s'analyse comme(service.findAllPresentations.get.first.votes.size).must(be)(equalTo(2))
. Notez que les parenthèses autour de l'2 sont plus à l'associativité de l'espace. Des points sont également les plus associativité, de sorte(service.findAllPresentations.get.first.votes.size) must be.equalTo(2)
analysaient comme(service.findAllPresentations.get.first.votes.size).must(be.equalTo(2))
.service findAllPresentations get first votes size must be equalTo 2
s'analyse commeservice.findAllPresentations(get).first(votes).size(must).be(equalTo).2
.