web-dev-qa-db-fra.com

Pourquoi le signe moins «-» n'est-il généralement pas surchargé de la même manière que le signe plus?

Le signe plus + est utilisé pour l'addition et la concaténation de chaînes, mais son compagnon: le signe moins, -, n'est généralement pas utilisé pour le découpage des chaînes ou dans un autre cas autre que la soustraction. Quelle pourrait être la raison ou les limites de cela?

Prenons l'exemple suivant en JavaScript:

var a = "abcdefg";
var b = "efg";

a-b == NaN
// but
a+b == "abcdefgefg"
65
Digvijay Yadav

En bref, il n'y a pas d'opérations de soustraction particulièrement utiles sur les chaînes avec lesquelles les gens ont voulu écrire des algorithmes.

Le + L'opérateur désigne généralement le fonctionnement d'un additif monoïde , c'est-à-dire une opération associative avec un élément d'identité:

  • A + (B + C) = (A + B) + C
  • A + 0 = 0 + A = A

Il est logique d'utiliser cet opérateur pour des choses comme l'addition d'entiers, la concaténation de chaînes et l'union d'ensemble car ils ont tous la même structure algébrique:

1 + (2 + 3) == (1 + 2) + 3
1 + 0 == 0 + 1 == 1

"a" + ("b" + "c") == ("a" + "b") + "c"
"a" + "" == "" + "a" == "a"

Et nous pouvons l'utiliser pour écrire des algorithmes pratiques comme une fonction concat qui fonctionne sur une séquence de toutes choses "concaténables", par exemple:

def concat(sequence):
    return sequence.reduce(+, 0)

Lorsque la soustraction - intervient, vous parlez généralement de la structure d'un groupe , qui ajoute un inverse −A pour chaque élément A , pour que:

  • A + −A = −A + A = 0

Et bien que cela ait du sens pour des choses comme la soustraction d'entiers et de virgules flottantes, ou même pour définir la différence, 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 annulatoire , qui n'a pas d'inverses, mais a la propriété d'annulation , de sorte que :

  • A - A = 0
  • A - 0 = A
  • (A + B) - B = A

Voici la structure que vous décrivez, où "ab" - "b" == "a", mais "ab" - "c" n'est pas défini. C'est juste que nous n'avons pas beaucoup d'algorithmes utiles qui utilisent cette structure. Je suppose que si vous considérez la concaténation comme une sérialisation, la soustraction pourrait être utilisée pour une sorte d'analyse.

116
Jon Purdy

Parce que la concaténation de deux chaînes valides est toujours une opération valide, mais l'inverse n'est pas vrai.

var a = "Hello";
var b = "World";

Qu'est-ce que doit a - b être ici? Il n'y a vraiment aucun bon moyen de répondre à cette question, car la question elle-même n'est pas valide.

37
Mason Wheeler

Parce que l'opérateur - Pour la manipulation de chaînes n'a pas suffisamment de "cohésion sémantique". Les opérateurs ne doivent être surchargés que lorsqu'il est absolument clair de ce que fait la surcharge avec ses opérandes et que la soustraction de chaîne ne respecte pas cette barre.

Par conséquent, les appels de méthode sont préférés:

public string Remove(string source, string toRemove)
public string Replace(string source, string oldValue, string newValue)

Dans le langage C #, nous utilisons + Pour la concaténation de chaînes car le formulaire

var result = string1 + string2 + string3;

au lieu de

var result = string.Concat(string1, string2, string3);

est pratique et sans doute 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 pour -, Car la notion de soustraction de chaînes est ambiguë (l'appel de fonction Replace(source, oldValue, newValue) avec "" Comme le paramètre newValue supprime tout doute, et la fonction peut être utilisée pour modifier des sous-chaînes, pas seulement les supprimer).

Le problème, bien sûr, est que la surcharge de l'opérateur dépend des types transmis à l'opérateur, et si vous passez une chaîne là où un nombre aurait dû être, vous pouvez obtenir un résultat inattendu. De plus, pour de nombreuses concaténations (c'est-à-dire en boucle), un objet StringBuilder est préférable, car chaque utilisation de + Crée une toute nouvelle chaîne et les performances peuvent en souffrir. L'opérateur + N'est donc 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:

public static Complex operator +(Complex c1, Complex c2) 
{
    return new Complex(c1.real + c2.real, c1.imaginary + c2.imaginary);
}
28
Robert Harvey

langue Groovy permet -:

println('ABC'-'B')

retour:

AC

Et:

println( 'Hello' - 'World' )

retour:

Hello

Et:

println('ABABABABAB' - 'B')

retour:

AABABABAB
8
Wim Deblauwe

Le signe plus est probablement contextuel dans plusieurs cas, mais un contre-exemple (peut-être une exception qui confirme la règle) dans Python est l'objet set, qui prévoit - mais non +:

>>> set('abc') - set('bcd')
set(['a'])
>>> set('abc') + set('bcd')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'set' and 'set'

Cela n'a pas de sens d'utiliser le + signe parce que l'intention peut être ambiguë - cela signifie-t-il définir l'intersection ou l'union? Au lieu de cela, il utilise | pour l'union et & pour l'intersection:

>>> set('abc') | set('bcd')
set(['a', 'c', 'b', 'd'])
>>> set('abc') & set('bcd')
set(['c', 'b'])
6
Aaron Hall

"-" 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 ce serait parfaitement logique! Au diable avec ce non-sens +!

Cependant, essayons de regarder cela sous un angle un peu plus abstrait.

Comment définiriez-vous l'algèbre des chaînes? Quelles opérations auriez-vous et quelles lois leur imposeraient-elles? Quelles seraient leurs relations?

N'oubliez pas qu'il n'y a absolument aucune ambiguïté! Chaque cas possible doit être bien défini, quitte à dire qu'il n'est pas possible de le faire! Plus votre algèbre est petite, plus c'est facile.

Par exemple, que signifie réellement ajouter ou soustraire deux chaînes?

Si vous ajoutez deux chaînes (par exemple, laissez a = "aa" Et b = "bb"), Obtiendrez-vous aabb comme résultat de a + b?

Que diriez-vous de b + a? Serait-ce bbaa? Pourquoi pas aabb? Que se passe-t-il si vous soustrayez aa du résultat de votre ajout? Votre chaîne aurait-elle un concept de quantité négative de aa en elle?

Revenez maintenant au début de cette réponse et remplacez spaceshuttle à la place de la chaîne. Pour généraliser, pourquoi une opération est-elle définie ou non pour un type quelconque?

Le point que j'essaie de faire est que rien ne vous empêche de créer une algèbre pour rien. Il peut être difficile de trouver des opérations significatives, voire des opérations utiles.

Pour les cordes, la concaténation est à peu près le seul sensé que j'aie jamais rencontré. Peu importe le symbole utilisé pour représenter l'opération.

3
Zavior