Знак плюс +
используется для сложения и конкатенации строк, но его компаньон: знак минус -
, как правило, не виден для обрезки строк или какого-либо другого случая, кроме вычитания. В чем может быть причина или ограничения для этого?
Рассмотрим следующий пример в JavaScript:
var a = "abcdefg";
var b = "efg";
a-b == NaN
// but
a+b == "abcdefgefg"
coding-standards
history
operators
overload
Дигвиджай Ядав
источник
источник
+
оператор перегружен двумя совершенно не связанными значениями «числовое сложение» и «конкатенация строк». К счастью, некоторые языки предоставляют отдельный оператор конкатенации, такой как.
(Perl5, PHP),~
(Perl6),&
(VB),++
(Haskell),…->
(подумайте о разыменовании доступа к элементу в C, поскольку вызовы виртуальных методов обязательно включают в себя указатель-подобную косвенность). Не существует закона языковой структуры, который требует вызовов методов / доступа к элементу для использования.
оператора, хотя это все более распространенное соглашение. Знаете ли вы, что в Smalltalk нет оператора вызова метода? Простое сопоставлениеobject method
достаточно.Ответы:
Короче говоря, нет никаких особенно полезных операций, подобных вычитанию, над строками, с которыми люди хотели бы написать алгоритмы.
+
Оператора как правило , обозначает операцию аддитивного моноида , то есть ассоциативная операция с единицей:Имеет смысл использовать этот оператор для таких вещей, как сложение целых чисел, конкатенация строк и объединение множеств, поскольку все они имеют одинаковую алгебраическую структуру:
И мы можем использовать его для написания удобных алгоритмов, таких как
concat
функция, которая работает с последовательностью любых «конкатенируемых» вещей, например:Когда происходит вычитание
-
, вы обычно говорите о структуре группы , которая добавляет обратный -A для каждого элемента A, так что:И хотя это имеет смысл для таких вещей, как целочисленное и вычитание с плавающей точкой, или даже для разности множеств, это не имеет особого смысла для строк и списков. Что является обратным
"foo"
?Существует структура, называемая отменяющим моноидом , которая не имеет инверсий, но имеет свойство отмены , так что:
Это структура, которую вы описываете, где
"ab" - "b" == "a"
, но"ab" - "c"
не определены. Просто у нас не так много полезных алгоритмов, которые используют эту структуру. Я предполагаю, что если вы думаете о конкатенации как о сериализации, то вычитание может быть использовано для какого-то анализа.источник
+
операция также является коммутативной для чисел, то естьA+B == B+A
делает ее плохим кандидатом для конкатенации строк. Это, плюс запутанный приоритет оператора, делает использование+
для конкатенации строк исторической ошибкой. Тем не менее, это правда , что использование-
для любой операции струны сделаны вещи гораздо хуже ....
у Perl; это~
в Perl6, возможно, другие..text.gz.text
...Потому что конкатенация любых двух допустимых строк всегда является допустимой операцией, но обратное неверно.
Что
a - b
здесь должно быть? Там действительно нет хорошего способа ответить на этот вопрос, потому что сам вопрос не является действительным.источник
5 + False
должно быть ошибкой , поскольку число не является логическим, а логическое не является числом.(a+b)-b = a
(надеюсь!), Но(a-b)+b
иногдаa
, иногдаa+b
зависит от того,b
является ли подстрокаa
или нет? Что это за безумие?Потому что
-
оператору для манипулирования строками не хватает «семантической сплоченности». Операторы должны быть перегружены, только когда абсолютно ясно, что перегрузка делает со своими операндами, а вычитание строки не соответствует этой полосе.Следовательно, вызовы методов предпочтительнее:
В языке C # мы используем
+
для конкатенации строк, потому что формавместо
это удобно и, возможно, легче читать, даже если вызов функции, вероятно, более «правильный» с семантической точки зрения.
+
Оператор может действительно означать только одну вещь в этом контексте. Это не верно как для-
, так как понятия вычитая строки неоднозначен (вызов функцииReplace(source, oldValue, newValue)
с""
какnewValue
параметр снимает все сомнения, и эта функция может быть использована для изменения подстроки, а не просто удалить их).Проблема, конечно, состоит в том, что перегрузка оператора зависит от типов, передаваемых оператору, и если вы передадите строку, где должно быть число, вы можете получить результат, который вы не ожидали. Кроме того, для многих конкатенаций (т. Е. В цикле)
StringBuilder
предпочтительным является объект, поскольку при каждом использовании+
создается новая строка, и производительность может пострадать. Таким образом,+
оператор даже не подходит во всех контекстах.Существуют перегрузки операторов, которые имеют лучшую семантическую связность, чем
+
оператор для конкатенации строк. Вот тот, который добавляет два комплексных числа:источник
Groovy язык действительно позволяет
-
:возвращает:
А также:
возвращает:
А также:
возвращает:
источник
('ABABABABA' + 'B') - 'B'
далеко не совпадает с начальным значением'ABABABABA'
.(A + B) - A == B
для каждого A и B. Могу ли я назвать это левым вычитанием?++
для конкатенации. Он работает с любым списком, а строка - это просто список символов. Это также имеет\\
, что удаляет первый вхождение каждого элемента в правом аргументе из левого аргумента.Знак плюса, вероятно, контекстуально имеет смысл в большем количестве случаев, но контрпример (возможно, исключение, которое подтверждает правило) в Python - это объект set, который предусматривает,
-
но не обеспечивает+
:Не имеет смысла использовать
+
знак, потому что намерение может быть неоднозначным - означает ли это установить пересечение или объединение? Вместо этого он использует|
для объединения и&
для пересечения:источник
set('abc') ^ set('bcd')
возвращаетсяset(['a', 'd'])
, если вы спрашиваете о симметричной разности.«
-
» используется в некоторых составных словах (например, «на месте») для объединения разных частей в одно и то же слово. Почему мы не используем "-
" для объединения различных строк в языках программирования? Я думаю, что это будет иметь смысл! К черту эту+
ерунду!Однако, давайте попробуем взглянуть на это немного более абстрактно.
Как бы вы определили строковую алгебру? Какие операции вы бы провели, и какие законы для них? Какими будут их отношения?
Помните, что не может быть никакой двусмысленности! Каждый возможный случай должен быть четко определен, даже если это означает, что это невозможно сделать! Чем меньше ваша алгебра, тем легче это сделать.
Например, что на самом деле означает сложение или вычитание двух строк?
Если вы добавите две строки (например, let
a = "aa"
иb = "bb"
), вы получитеaabb
в результатеa + b
?Как насчет
b + a
? Это будетbbaa
? Почему нетaabb
? Что произойдет, если вы вычтетеaa
результат своего сложения? Будет ли в вашей строке понятие отрицательного количестваaa
?Теперь вернитесь к началу этого ответа и подставьте
spaceshuttle
вместо строки. Чтобы обобщить, почему любая операция определена или не определена для любого типа?Я пытаюсь подчеркнуть, что ничто не мешает вам создать алгебру для чего-либо. Может быть трудно найти значимые операции или даже полезные операции для этого.
Для строк конкатенация является практически единственным разумным вариантом, с которым я когда-либо сталкивался. Не имеет значения, какой символ используется для представления операции.
источник
'xy' * 3 == 'xyxyxy'
?