Le signe plus +
est utilisé pour l’addition et pour la concaténation de chaînes, mais son compagnon: le signe moins,, -
n’est généralement pas utilisé pour le rognage de chaînes ou pour un autre cas autre que la soustraction. Quelle pourrait être la raison ou les limites de cela?
Considérez l'exemple suivant en JavaScript:
var a = "abcdefg";
var b = "efg";
a-b == NaN
// but
a+b == "abcdefgefg"
coding-standards
history
operators
overload
Digvijay Yadav
la source
la source
+
opérateur binaire soit surchargé avec les deux significations totalement non liées «addition numérique» et «concaténation de chaîne». Heureusement, certaines langues offrent un opérateur de concaténation séparé tel que.
(Perl5, PHP),~
(Perl6),&
(VB),++
(Haskell), ...->
(pensez à déréférencer l'accès des membres en C, car les appels de méthodes virtuelles impliquent nécessairement une indirection de type pointeur). Aucune loi de conception de langage n'oblige les appels de méthode / l'accès des membres à utiliser un.
opérateur, bien que ce soit une convention de plus en plus courante. Saviez-vous que Smalltalk n'a pas d'opérateur d'appel de méthode? Une simple juxtapositionobject method
suffit.Réponses:
En bref, il n’ya pas d’opérations de soustraction sur les chaînes particulièrement utiles avec lesquelles les gens ont voulu écrire des algorithmes.
L’
+
opérateur dénote généralement le fonctionnement d’un monoïde additif , c’est-à-dire une opération associative avec un élément d’identité:Il est logique d'utiliser cet opérateur pour des opérations telles que l'addition d'entiers, la concaténation de chaînes et la définition de l'union, car elles ont toutes la même structure algébrique:
Et nous pouvons l’utiliser pour écrire des algorithmes pratiques, comme une
concat
fonction qui fonctionne sur une séquence de choses «concaténables», par exemple:Lorsque la soustraction
-
est impliquée, vous parlez généralement de la structure d'un groupe , ce qui ajoute un inverse -A pour chaque élément A, de sorte que:Et bien que cela ait un sens pour des choses comme la soustraction de nombres entiers et flottants, ou même pour la différence de valeurs, cela n'a pas beaucoup de sens pour les chaînes et les listes. Quel est l'inverse de
"foo"
?Il existe une structure appelée monoïde d'annulation , qui n'a pas d'inverse, mais possède la propriété d' annulation , de sorte que:
C'est la structure que vous décrivez, où
"ab" - "b" == "a"
, mais"ab" - "c"
n'est pas définie. C'est juste que nous n'avons pas beaucoup d'algorithmes utiles qui utilisent cette structure. J'imagine que si vous envisagez la concaténation comme une sérialisation, la soustraction peut être utilisée pour une sorte d'analyse syntaxique.la source
+
opération est également commutative pour les nombresA+B == B+A
, ce qui en fait un mauvais candidat pour la concaténation de chaînes. Ceci, ajouté à la priorité déroutante de l'opérateur, rend l'utilisation+
d'une erreur historique pour la concaténation de chaînes. Cependant, il est vrai que l'utilisation-
de n'importe quelle opération sur les cordes a rendu les choses bien pires….
à Perl; c'est~
en Perl6, peut-être d'autres..text.gz.text
...Parce que la concaténation de deux chaînes valides est toujours une opération valide, mais l'inverse n'est pas vrai.
Que devrait
a - b
être ici? Il n'y a vraiment aucun moyen de répondre à cette question, car la question elle-même n'est pas valide.la source
5 + False
Il me semble que cela devrait évidemment être une erreur , puisqu'un nombre n'est pas un booléen et qu'un booléen n'est pas un nombre.(a+b)-b = a
(je l' espère!), Mais(a-b)+b
parfoisa
, parfoisa+b
selon le casb
est une sous - chaînea
ou non? Quelle folie est-ce?Parce que l'
-
opérateur de manipulation de chaîne n'a pas assez de "cohésion sémantique". Les opérateurs ne doivent être surchargés que lorsque la surcharge des opérandes est clairement définie et que la soustraction de chaînes ne respecte pas cette barre.Par conséquent, les appels de méthode sont préférés:
En langage C #, nous utilisons
+
pour la concaténation de chaînes car la formeau lieu de
est pratique et peut-être plus facile à lire, même si un appel de fonction est probablement plus "correct", d’un point de vue sémantique.
L'
+
opérateur ne peut vraiment signifier qu'une chose dans ce contexte. Ce n'est pas aussi vrai-
car la notion de soustraction de chaînes est ambiguë (l'appel de la fonctionReplace(source, oldValue, newValue)
avec""
commenewValue
paramètre supprime tout doute, et la fonction peut être utilisée pour modifier des sous-chaînes, pas seulement pour les supprimer).Le problème, bien sûr, est que la surcharge de l'opérateur dépend des types qui lui sont transmis. Si vous transmettez une chaîne où un nombre aurait dû être, vous risquez d'obtenir un résultat inattendu. En outre, pour de nombreuses concaténations (dans une boucle, par exemple), un
StringBuilder
objet est préférable, car chaque utilisation de+
crée une nouvelle chaîne et les performances peuvent en souffrir. Donc, l'+
opérateur n'est même pas approprié dans tous les contextes.Il existe des surcharges d'opérateurs qui ont une meilleure cohésion sémantique que l'
+
opérateur pour la concaténation de chaînes. En voici un qui ajoute deux nombres complexes:la source
Le langage Groovy permet
-
:résultats:
Et:
résultats:
Et:
résultats:
la source
('ABABABABA' + 'B') - 'B'
est loin d'être identique à la valeur de départ'ABABABABA'
.(A + B) - A == B
pour chaque A et B. Puis-je appeler cela une soustraction à gauche?++
pour concaténation. Cela fonctionne sur n'importe quelle liste et une chaîne n'est qu'une liste de caractères. Cela a également\\
, qui supprime la première occurrence de chaque élément dans l'argument de droite de l'argument de gauche.Le signe plus a probablement un sens contextuel dans un plus grand nombre de cas, mais un contre-exemple (peut-être une exception qui prouve la règle) en Python est l'objet set, qui fournit,
-
mais non+
:Il n’a pas de sens d’utiliser le
+
signe parce que l’intention peut être ambiguë. Est-ce que cela signifie une intersection ou une union? Au lieu de cela, il utilise|
pour l'union et&
pour l'intersection:la source
set('abc') ^ set('bcd')
renvoieset(['a', 'd'])
, si vous vous interrogez sur la différence symétrique."
-
" est utilisé dans certains mots composés (par exemple, "sur site") pour joindre les différentes parties dans le même mot. Pourquoi n'utilisons-nous pas "-
" pour joindre différentes chaînes dans les langages de programmation? Je pense que cela aurait un sens parfait! Au diable cette+
absurdité!Cependant, essayons de voir cela sous un angle un peu plus abstrait.
Comment définiriez-vous l'algèbre des cordes? Quelles opérations auriez-vous et quelles lois leur seraient applicables? Quelles seraient leurs relations?
Rappelez-vous, il n’ya peut-être aucune ambiguïté! Tous les cas possibles doivent être bien définis, même si cela signifie qu'il n'est pas possible de le faire! Plus votre algèbre est petite, plus cela est facile.
Par exemple, que signifie réellement ajouter ou soustraire deux chaînes?
Si vous ajoutez deux chaînes (par exemple, let
a = "aa"
etb = "bb"
), obtiendriez-vousaabb
le résultat dea + b
?Que diriez-
b + a
vous Serait-cebbaa
? Pourquoi ne pasaabb
? Que se passe-t-il si vous soustrayezaa
du résultat de votre addition? Votre chaîne aurait-elle un concept de quantité négative deaa
?Revenez maintenant au début de cette réponse et remplacez-la
spaceshuttle
par la chaîne. Pour généraliser, pourquoi toute opération définie ou non définie pour un type quelconque?Ce que j'essaie de dire, c'est que rien ne vous empêche de créer une algèbre. Il peut être difficile de trouver des opérations significatives, voire utiles.
Pour les cordes, la concaténation est à peu près la seule chose sensée que j'ai jamais rencontrée. Peu importe quel symbole est utilisé pour représenter l'opération.
la source
'xy' * 3 == 'xyxyxy'
?