Конкатенация строк

Недавно, в #1131, @ibond проговорился о 1 тайной фиче:

begin
  var s :=
    'строчка1'#10
    'строчка2'#10
    'строчка3'#10
  ;
end.

Работает как будто между строками и символами стоят плюсы, вот только вычисляет эту строку на этапе компиляции.

И, в отличии от плюсов, это работает только с константными строками (опять же, потому что всё на этапе компиляции).

Как подметил @spectatorBH - даёшь тайные знания народу в справку (или куда то типо того)! :wink:
Ну а если серьёзно - надо всё же добавить куда то, скорее всего в справку. Сам ничего умнее придумать не могу, по этому поводу, поэтому процитирую @spectatorBH:

@ibond84 @miks1965 В любом случае, это ненормально. Это должно быть либо описано формально как фича в справке, либо исправлено как ошибка, т.к. на данный момент такое написание явно противоречит синтаксису Паскаля (причем любого, впрочем, как и С#). Откуда вообще такое чудо появилось?

Если бы такую “старую фичу для избранных” использовал какой-нибудь школьник, ему бы это засчитали как ошибку, и были бы правы.

1 лайк

Это не тайные знания, это работало еще в Турбо Паскале

Учите матчасть

Ну, вот чтоб её учить - надо чтоб она была где то задокументирована. И скачивать турбо паскаль и искать его справку никто не будет, это должно быть именно в вашей справке.

P.S. Символ перехода на следующую строку это ведь #13#10, а не #10#13 ))

1 лайк

В Windows это #13#10, в *nix - #10.

И потом, что Вас удивляет?

begin
  var s:='Мама'#32'мыла'#32'Раму';
  s.Println
end.

#n - это символ с десятичным кодом n. В строке символы сцепляются без всяких допзначков. Вас ведь #13#10 не удивляет, что два символа “впритирку”, почему должно удивлять, когда вместо ‘А и В’ пишут ‘A’#32’и’#32’B’ ?

Аналога следующего кода тоже нет в С#, насколько я знаю. Это тоже “странно”?

begin
   var (a, b, c) := (3, -4, 8);
   var y := -2*a+5*b+---+--+++-2*c;
   Println(y)
end.

Если вы про синтаксис - то что про это нигде не написано. Те кто старыми паскалями не пользовался - не знают и не могут никак узнать, потому в нигде не написано.

Если про символ перехода на новую строку - у @Admin в программе вроде неправильно, вот я и переспросил, это ошибка или ещё что то чего я не знаю.

Ну, если бы увидел до того как узнал про эту фичу - таки удивило бы. А как узнал - сразу попробовал несколько вещей, в том числе и символы так стакать. Раньше всегда писал #13+#10.

Ну, часть про C# в данном случае меня не волнует. Потому что у них есть "\n" и т.п., а раз в паскале нет - значит такая замена однозначно полезна.

Вероятнее всего, Вы далеко не все еще обнаружили, про которое “нигде не написано”. А где писать-то: Справка - не руководство по языку.

Поскольку никто так и не понял смысла моего комментария на гитхабе, поясню подробнее. Вот такой код никогда не компилировался ни в одном из известных мне Паскалей (хотя, конечно, я далеко не все его разновидности перепробовал):

 s1 := 'abc'  'xyz';
 s2 := 'abc'
       'xyz';

Только что перепроверил это в TP 7.0 (под DosBox), Virtual Pascal 2.1 и Free Pascal 2.x/3.x. – везде ругается на неверный синтакис. Хотя… может быть в Delphi это работает? Нет возможности сейчас быстро проверить (сам Delphi почти никогда в жизни не использовал).

@Admin :roll_eyes: Обратите внимание: речь в исходном вопросе вообще не шла о строках вида 'abc'#13#10'xyz' – это всегда и везде работало, просто Сергей был не в курсе, т.к. этот неочевидный момент тоже формально в справке у нас не описан, к сожалению.

Речь шла о неожиданной особенности: возможности конкатенации литерных строк, разделенных пробелами и/или написанными на разных строчках. Это уже не канонический синтаксис Паскаля. Подобная фича, конечно, существует в некоторых других ЯП (в основном, скриптовых), но там обычно в многострочных строках (multiline strings) не требуется явно писать коды CR/LF – они добавляются автоматом в каждой строчке, что куда проще и удобнее при необходимости впечатывать в код длинные тексты.

Поэтому данная возможность в целом хоть и не бесполезная, но в текущей реализации (если это вообще не случайный баг!) – довольно сомнительная, особенно разделение пробелами частей единой строки на одной строчке. Мне кажется, все это требует более критического осмысления и обсуждения.

Странный вопрос – в Справке и описать, т.к. никакого другого формального документа все равно нет и пока не предвидится. А откуда же еще начинающим брать информацию о правильном синтаксисе? Тем более о такой базовой вещи, как строки?

1 лайк

Скорее всего это баг

Турбо Паскаля?

Что тут обсуждать? Нормальная фича. Можно писать строку на нескольких строках, не соединяя плюсами.

Пожалуйста будьте точнее в формулировках. Я такого не утверждал. Речь шла не о #10, а о соединительных пробелах, которые в строку не добавляются.

Ваш вариант можно посмотреть по ссылке, для этого я её привёл (ссылка идёт прямо к вашему сообщению). А в моём варианте я показал где это может быть полезно.

Ну, в моём примере между строками есть переносы строки и пробелы-отступы и они все не добавляются, так что это в моём примере показано.

Я отвечал только Сергею.

Две строки подряд - да, это просто грязная реализация конкатенации с литералами-символами. Это надо убирать

1 лайк
1 лайк

Ещё раз, “+” работает на этапе выполнения, поэтому он медленнее. А конкатенация работает на этапе компиляции. Поэтому - не надо её убирать.

Я подправил название Issue до того как Вы ответили. Но, все-же, спасибо за замечание.

Пример который там приведён - является примером того, что очень удобно в той конкатенации что сейчас есть.По вашему, писать это всё в 1 строчку будет лучше?

Убрал пример. Issue закрыто.

Конкатенация koнстантных строк происходит на этапе компиляции

1 лайк

А это всё вопросы оптимизации кода компилятором. Почему нельзя во время компиляции суммировать явные значения? Например вот такой код:

var a := 2 + 3;
var s := 'String' + 'String';