Scala - mutables (var) paramètre méthode de référence
EDIT: je reçois des upvotes ici. Juste pour mémoire, je n'ai plus pense que c'est important. Je n'ai pas besoin d'elle depuis que je l'ai posté.
Je voudrais faire suite à la Scala ...
def save(srcPath: String, destPath: String) {
if (!destPath.endsWith('/'))
destPath += '/'
//do something
}
... mais je ne peux pas car destPath
est un val. Est-il possible de déclarer destPath
var?
Remarque: il y a des questions similaires, mais dans tous les OP voulais juste modifier le tableau.
S'il vous plaît ne pas conseiller suivantes:
La mutation des paramètres d'entrée est souvent considéré comme de mauvais style et le rend
plus difficile de raisonner sur code.
Je pense que c'est valable dans la programmation impérative (Scala permet à la fois, non?) et d'ajouter quelque chose comme tmpDestPath
voudrais juste ajouter l'encombrement.
EDIT: Ne vous méprenez pas. Je sais que les chaînes ne sont pas mutables et je ne veux pas d'une référence à la référence, parce que je ne veux pas modifier les données de l'appelant. Je veux juste modifier référence locale de la chaîne de l'appelant m'a donné à ma chaîne (par exemple. orig + '/'). Je veux modifier cette valeur uniquement dans la portée de la méthode actuelle. Regardez, c'est parfaitement valide en Java:
void printPlusOne(int i) {
i++;
System.out.println("i is: " + i);
System.out.println("and now it's same: " + i);
}
Je n'ai pas à créer une nouvelle variable et je n'ai pas à calculer i+1 deux fois.
- Après la clarification, la réponse est: Vous ne pouvez pas.
- C'est ce que je soupçonnais. Je vais le poster à la scala-débat.
- Eh bien, de la Scala de la communauté n'est pas vraiment favorable à l'idée d'être en mesure de modifier directement les paramètres de la fonction, que ce soit par valeur ou par référence. Le raisonnement est le même que celui de pourquoi Scala manque aussi quelque chose d'autre à partir de votre exemple: unaire
++
opérateur(s) pour les types numériques. De telles choses lattes de non-fonctionnels, des effets secondaires de la programmation orientée style, qui est quelque chose que la Scala généralement vous encourage à éviter. Comme il est, si vous voulez à plusieurs reprises de les muter un paramètre de fonction, vous devez d'abord l'enregistrer dans unevar
, ce qui rend vos intentions plus clair, de toute façon! - En fait, ce n'est pas la raison de l'absence de
++
. Le problème avec++
est qu'il ne peut être mis en œuvre comme une méthode d'une classe -- il faudrait une langue fonctionnalité intégrée dans le compilateur, et spécifiques à certains types. - Derp. Je corrige la position des mains.
- Je n'en achète pas. Si vars sont admis dans le corps de la méthode, il n'y a pas de raison qu'ils ne devraient pas être autorisés dans les paramètres. Pour moi, la Scala est plus comme Python ou Perl où je peux choisir si je vais le faire fonctionnelle ou l'impératif de style.
- Et personne ne prend ce choix, loin de vous; vous êtes juste très légèrement incommodés par un besoin de placer le paramètre dans une variable locale. Scala est tout simplement de vous encourager à faire le plus fonctionnel chose. Vous êtes bien entendu libre de continuer à prendre ce avec le reste de la communauté–que je ne parle pas pour–mais j'ai tout simplement pour vous informer de ce à quoi s'attendre.
- Je suis d'accord avec woky et procède à la scala-débat à l'appui de son fil (si je peux le trouver). Il n'a pas de sens à force de la verbosité, parce que l'écrasement de la valeur dans le paramètre d'entrée n'est pas la fonction non-pur. Seulement la modification de données contenues dans ce que la valeur du paramètre références, la fonction non-pur, et qui s'applique à la val sur les membres de la classe pour les données. C'est un langage d'erreur de conception.
- J'ai ajouté un fil de discussion, "les paramètres de la fonction ne sont pas autorisés à être
var
", à la scala-débat puisque je ne pouvais pas trouver la vôtre. - Scala spécifiquement positionne comme un langage fonctionnel. En tant que tel, il serait logique d'en déduire qu'il ne fait pas de promesses sur qui permet à un développeur d'utiliser impératif paradigmes. Comme un lourd Python utilisateur je suis habitué à l'inverse. Beaucoup de gens dans cette communauté voulez plus de fonctionnalités, mais Guido (créateur et BDFL) a rappelé à de nombreuses reprises, Python n'est pas un langage fonctionnel, il a simplement certaines fonctions que les gens associent avec les langages fonctionnels parce qu'ils sont vraiment utiles.
- Si vous pensez, "je souhaite que mon langage de programmation pourrait muter paramètres", puis le problème n'est pas le langage de programmation.
- Pour l'enregistrement, le fait que vous n'avez pas besoin de plus cela n'est pas pertinent. C'est une très bonne question pour ceux d'entre nous qui savent que le fait de pouvoir re-utiliser un identificateur est beaucoup mieux que d'être forcé à avoir l'original inutile identifiant dans le champ d'application, et sans courir le danger de accidentellement en se référant, par conséquent, l'introduction d'un bug subtil. Le fait que la Scala ne permet pas la modification des arguments de méthode est un excellent exemple de ce que j'appelle fonctionnel nazisme.
- Je upvoted la question parce que c'est un très bon, et j'avais juste demandé à moi-même. L'obtention d'un droit de réponse "Vous ne pouvez pas" est également utile 🙂
Vous devez vous connecter pour publier un commentaire.
Vous ne pouvez pas.
Vous aurez à déclarer un supplément de
var
(ou l'utilisation d'un style fonctionnel :-)).Exemple simpliste:
La JVM ne permettent pas passé par référence des pointeurs vers des objets (qui est comment vous pouvez le faire en C++), de sorte que vous ne pouvez pas faire exactement ce que vous voulez.
Une option est de retour à la nouvelle valeur:
Une autre est de créer un wrapper:
les utilisateurs qui auront ensuite à utiliser sur la manière. (Bien sûr, ils vont être tentés de
save("/here",Mut("/there"))
qui permettra de jeter les modifications, mais c'est toujours le cas avec le passage par référence en arguments de la fonction.)Edit: ce que vous proposez est une des plus grandes sources de confusion chez les non-programmeurs experts. C'est, lorsque vous modifiez l'argument d'une fonction, vous êtes à la modification d'une copie locale (passage par valeur) ou de l'original (par référence)? Si vous ne peut même modifier il est assez évident que ce que vous faites est une copie locale.
Juste le faire de cette façon.
Il vaut la peine de l'absence de confusion à propos de ce qui se passe réellement.
Vous pourriez peut-être obtenir le type de système pour faire le travail pour vous, vous n'avez même pas besoin de s'inquiéter à propos de l'ajout d'une barre oblique à chaque fois:
Maintenant, vous n'avez pas besoin du code pour modifier l'entrée
String
:Vrai, il y a un peu de configuration au début, mais ce sera un peu moins avec les classes dans la version 2.10, et il supprime tout le fouillis de la méthode, qui a été ce qui vous inquiète.
Chaîne objets immuables Scala (et Java). Les solutions de rechange que je peux penser sont:
Dans le deuxième cas, vous devriez avoir quelque chose comme:
MODIFIER
Si je comprends bien, vous souhaitez utiliser l'argument comme une variable locale. Vous ne pouvez pas, parce que tous les arguments de méthode sont val de Scala.
La seule chose à faire est de le copier sur une variable locale d'abord:
Voici quelques suggestions:
1) mise à Jour de votre fonction un peu
2) Créer une fonction d'utilité à utiliser avant d'appeler save
Non, ce n'est pas permis en Scala. D'autres ont indiqué que certains de bas niveau des solutions de contournement (tout bon), mais je vais ajouter un niveau supérieur à un. Justement ce type de chaîne de normalisation fins, je garde autour d'un souteneur extension à la scala.Chaîne avec des méthodes comme suffixe, préfixe, removeSuffix, et removePrefix. suffixe et préfixe ou d'ajouter une chaîne à une autre, à moins que le préfixe ou de suffixe est déjà là. removeSuffix et removePrefix faire à l'évidence, la suppression d'une chaîne à partir de la fin ou le début d'une autre, si elle est présente. Votre cas d'utilisation serait écrit
Si vous faire un tas d'analyse de données ou d'un fichier des opérations, ces méthodes sont tellement pratique que vous ne serez pas croire que vous avez jamais fait sans eux.
stripPrefix
etstripSuffix
dansStringLike
? Des sons comme ils le font déjà ce que votreremovePrefix
etremoveSuffix
faire.Je sais que c'est une vieille question, mais si vous voulez réutiliser le nom d'argument peut-être: