El signo más +
se usa para la suma y para la concatenación de cadenas, pero su compañero: el signo menos -
, generalmente no se ve para el recorte de cadenas o algún otro caso que no sea la resta. ¿Cuál podría ser la razón o las limitaciones para eso?
Considere el siguiente ejemplo en JavaScript:
var a = "abcdefg";
var b = "efg";
a-b == NaN
// but
a+b == "abcdefgefg"
coding-standards
history
operators
overload
Digvijay Yadav
fuente
fuente
+
operador binario esté sobrecargado con los dos significados totalmente independientes "suma numérica" y "concatenación de cadenas". Afortunadamente, algunos idiomas proporcionan un operador de concatenación separado como.
(Perl5, PHP),~
(Perl6),&
(VB),++
(Haskell), ...->
(piense en desreferenciar el acceso de miembros en C, ya que las llamadas a métodos virtuales necesariamente implican una indirección similar a un puntero). No existe una ley de diseño de lenguaje que requiera llamadas a métodos / acceso de miembros para usar un.
operador, aunque es una convención cada vez más común. ¿Sabía que Smalltalk no tiene operador de llamada a método? La yuxtaposición simpleobject method
es suficiente.Respuestas:
En resumen, no hay operaciones de sustracción particularmente útiles en cadenas con las que la gente haya querido escribir algoritmos.
El
+
operador generalmente denota la operación de un monoide aditivo , es decir, una operación asociativa con un elemento de identidad:Tiene sentido usar este operador para cosas como la suma de enteros, la concatenación de cadenas y la unión de conjuntos porque todos tienen la misma estructura algebraica:
Y podemos usarlo para escribir algoritmos útiles como una
concat
función que funciona en una secuencia de cualquier cosa "concatenable", por ejemplo:Cuando
-
se involucra la resta , generalmente se habla de la estructura de un grupo , que agrega una inversa -A para cada elemento A, de modo que:Y si bien esto tiene sentido para cosas como la resta de enteros y coma flotante, o incluso para establecer diferencias, no tiene mucho sentido para cadenas y listas. ¿Cuál es el inverso de
"foo"
?Hay una estructura llamada monoide canceroso , que no tiene inversas, pero tiene la propiedad de cancelación , de modo que:
Esta es la estructura que describe, donde
"ab" - "b" == "a"
, pero"ab" - "c"
no está definida. Es solo que no tenemos muchos algoritmos útiles que usen esta estructura. Supongo que si piensas en la concatenación como serialización, la resta podría usarse para algún tipo de análisis.fuente
+
operación también es conmutativa para los números, es decirA+B == B+A
, lo que lo convierte en un mal candidato para la concatenación de cadenas. Esto, más la confusa prioridad del operador, hace que el uso+
de la concatenación de cadenas sea un error histórico. Sin embargo, es cierto que usar-
cualquier operación de cadena empeoró las cosas ....
de Perl; es~
en Perl6, posiblemente otros..text.gz.text
...Porque la concatenación de dos cadenas válidas siempre es una operación válida, pero lo contrario no es cierto.
¿Qué debería
a - b
estar aquí? Realmente no hay una buena manera de responder esa pregunta, porque la pregunta en sí no es válida.fuente
5 + False
obviamente debería ser un error , ya que un número no es un booleano y un booleano no es un número.(a+b)-b = a
(¡con suerte!), Pero a(a-b)+b
vecesa
, a veces, ¿a+b
depende de sib
es una subcadenaa
o no? ¿Qué locura es esta?Porque el
-
operador para la manipulación de cadenas no tiene suficiente "cohesión semántica". Los operadores solo deben sobrecargarse cuando está absolutamente claro qué hace la sobrecarga con sus operandos, y la resta de cadenas no cumple con esa barra.En consecuencia, se prefieren las llamadas a métodos:
En el lenguaje C #, usamos
+
para la concatenación de cadenas porque el formularioen lugar de
es conveniente y posiblemente más fácil de leer, a pesar de que una llamada a la función es probablemente más "correcta", desde un punto de vista semántico.
El
+
operador realmente solo puede significar una cosa en este contexto. Esto no es tan cierto-
, ya que la noción de restar cadenas es ambigua (la llamadaReplace(source, oldValue, newValue)
a la función con""
elnewValue
parámetro elimina toda duda, y la función se puede usar para alterar subcadenas, no solo eliminarlas).El problema, por supuesto, es que la sobrecarga del operador depende de los tipos que se pasan al operador, y si pasa una cadena donde debería haber estado un número, puede obtener un resultado que no esperaba. Además, para muchas concatenaciones (es decir, en un bucle),
StringBuilder
es preferible un objeto, ya que cada uso de+
crea una nueva cadena y el rendimiento puede verse afectado. Por lo tanto, el+
operador ni siquiera es apropiado en todos los contextos.Hay sobrecargas del operador que tienen una mejor cohesión semántica que el
+
operador para la concatenación de cadenas. Aquí hay uno que agrega dos números complejos:fuente
El lenguaje Groovy sí permite
-
:devoluciones:
Y:
devoluciones:
Y:
devoluciones:
fuente
('ABABABABA' + 'B') - 'B'
no es lo mismo que el valor inicial'ABABABABA'
.(A + B) - A == B
por cada A y B. ¿Puedo llamar a eso una resta izquierda?++
para la concatenación. Funciona en cualquier lista y una cadena es solo una lista de caracteres. También tiene\\
, lo que elimina la primera aparición de cada elemento en el argumento derecho del argumento izquierdo.El signo más probablemente tenga sentido contextual en más casos, pero un contraejemplo (quizás una excepción que pruebe la regla) en Python es el objeto establecido, que proporciona
-
pero no+
:No tiene sentido usar el
+
signo porque la intención podría ser ambigua: ¿significa establecer intersección o unión? En cambio, usa|
para unión y&
para intersección:fuente
set('abc') ^ set('bcd')
devuelveset(['a', 'd'])
, si está preguntando sobre la diferencia simétrica."
-
" se usa en algunas palabras compuestas (por ejemplo, "en el sitio") para unir las diferentes partes en la misma palabra. ¿Por qué no usamos "-
" para unir diferentes cadenas en lenguajes de programación? ¡Creo que tendría mucho sentido! ¡Al diablo con estas+
tonterías!Sin embargo, intentemos ver esto desde un ángulo un poco más abstracto.
¿Cómo definirías el álgebra de cuerdas? ¿Qué operaciones tendrías y qué leyes tendrían para ellos? ¿Cuáles serían sus relaciones?
¡Recuerde, puede que no haya absolutamente ninguna ambigüedad! ¡Todos los casos posibles deben estar bien definidos, incluso si eso significa decir que no es posible hacer esto! Cuanto más pequeño es el álgebra, más fácil se hace.
Por ejemplo, ¿qué significa realmente sumar o restar dos cadenas?
Si agrega dos cadenas (por ejemplo, let
a = "aa"
yb = "bb"
), ¿obtendríaaabb
el resultado dea + b
?¿Qué tal
b + a
? ¿Sería esobbaa
? ¿Por qué noaabb
? ¿Qué sucede si restasaa
del resultado de tu suma? ¿Su cadena tendría un concepto de cantidad negativaaa
?Ahora regrese al comienzo de esta respuesta y sustituya en
spaceshuttle
lugar de la cadena. Para generalizar, ¿por qué hay alguna operación definida o no definida para ningún tipo?El punto que estoy tratando de aclarar es que no hay nada que te impida crear un álgebra para nada. Puede ser difícil encontrar operaciones significativas, o incluso operaciones útiles para ello.
Para las cadenas, la concatenación es prácticamente la única sensata que he encontrado. No importa qué símbolo se use para representar la operación.
fuente
'xy' * 3 == 'xyxyxy'
?