type
t1 = class
function operator() (a,b: byte) := a+b;
end;
begin
var a := new t1;
var i := a(1,2);
end.
Вроде можно было, но это не точно…
И так тоже не работает:
type
t1 = class
property exec1[a,b: byte]: byte read a+b;
property exec2(a,b: byte): byte read a+b;
end;
begin
var a := new t1;
var i1 := a.exec1[1,2];
var i2 := a.exec2(1,2);
end.
@Сергей, лично с подобным не сталкивался и думал заковырка в public static, но в доке MS упоминают скобки лишь в контексте индексации и приведения типов через ex/implicit, а задумка интересная. Через делегаты не пойдёт?
1) подскажите как правильно и без лишних прибамбасов вроде RegEx перезагрузить .Replace для строк, чтобы кроме указания искомого и замены можно было указывать кол-во удаляемых вхождений (cardinal?)
Пока такой вариант выкусывания подстроки
Function string.operator-(s1,s2:string):string;
begin
if IsNullOrEmpty(s1) or IsNullOrEmpty(s2) then exit; //nothing
var _pos := s1.IndexOf(s2,0);
if (_pos >-1) then Result:= s1.Substring(0, _pos) + s1.Substring(_pos + s2.Length);
// может есть что улучшить по новым канонам, кроме Left/Right или Result:=s1.Remove(_pos,s2.Length);?
end;
2) Как оптимальнее подсчитывать количество вхождений подстроки?
3) также пока не особо понятно почему в отличие от того же stringbuilder, перегрузка “плюса” через Concat не даёт ощутимых преимуществ при обработке массивов строк
Вот я не понимаю той смысловой нагрузки, которую Вы придаете взятым Вами же в кавычки словам в контексте программирования. По-моему, Вы (причем, уже не в первый раз) смешиваете алгоритм и его реализацию в конкретном языке.
Правильно с какой точки зрения? Алгоритмически правильно все, что приводит к нужному результату в рамках условия и поставленных ограничений. Программно правильно все, что реализует алгоритм на вычислительной установке в рамках имеющейся аппаратной и программной платформы.
Оптимально с какой точки зрения? Понимания кода, компактности кода, скорости выполнения программы, затратах на оперативную память, времени написания программы… ?
Спасибо, @Алекс, но там нет кавычек и, насколько я понимаю, полемику и умственные рефлексии хотя иногда и полезны, однако им место скорее в “Болталке” или оффтоп.
Разумеется, для решения большинства задач достаточно парадигмы структурного программирования, а в данном контексте (как ни странно) речь о современном подходе для PascalABC .NEТ
Что касается парадигмы структурного программирования, она никак не определяет ни правильности алгоритма (да и не может определять), ни оптимальности кода. Неправильно в структурном программировании то, что нарушает его концепцию - и только. Поэтому вопрос о “правильности” остается открытым".
Термин “современное программирование” каждый волен трактовать по-своему, но в любом случае в контексте поставленной задачи, а не в виде “сферического коня в вакууме”.
function Remove(self: string; s: string; c: integer): string; extensionmethod;
begin
var sb := new StringBuilder(self);
//ToDo
Result := sb.ToString;
end;
begin
'abcabcabc'
.Remove('b',2)
.Print;
end.
Потому что:
s1 + s2 + s3
Это:
(s1 + s2) + s3
То есть:
Concat(Concat(s1, s2), s3);
То есть внутренний Concat создаст лишнюю строку.
А это вообще зря. Concat реализован через StringBuilder, что, хоть и быстро, но, думаю, внутренняя реализация сложения 2 строк должна всё же быть быстрее, ибо там через неуправляемую часть кода всё делается (если я правильно помню).
Вот это как раз в болталку стоило бы. Потому что слова красивые но по делу мало. Лучше бы, всё же, ответили, что вы имеете в виду под “оптимально”.
Можно спросить, зачем придумана вся эта путаница с индексацией строк, в одном случае они индексируются с 1, в другом с 0? Например:
begin
var s := '15x + 17 = 0';
s.IndexOf('x').Println;//2
s[:s.IndexOf('x')].Println;//1
end.
я хочу выделить все символы строки до символа ‘x’, использую метод IndexOf, в методах считается, что строки индексируются с 0, потом беру срез и… а срез считает, что строки индексируются с 1. И поди запомни все это.
С 1 индексируется только в s[]. Это из за совместимости со старыми паскалями. Там, вроде, в s[0] хранилась длинна строки. Во всех остальных случаях индексация идёт человеческая, то есть с 0.
Как будто там есть хотя бы половина языка))) И это не экзотика, это даже не экстеншн-метод, а обычные и 1 из основных методов строк, так же как .Remove, к примеру.
Я не собираюсь в Вами спорить, потому что Вы как мыслили категориями языков семейства С, так и продолжаете мыслить. Для Вас “язык” - это все, что можно подлинковать из .NET-библиотек. В Справке описано то, что так или иначе относится именно к PascalABC.NЕТ.
Я не хочу перечислять тут то, на что потратил две недели, когда писал полсотни страниц части 6 своей будущей книги.
Я не нашёл там части про методы строк, поэтому залез в PABCSystem.pas. Там со строки 1469 перечислены все методы для строк. Ну и + экстенш-методы которые видны по точке.
И единственный который индексирует строку с 1 - это Copy, то есть старьё существующее только для совместимости. Оно даже исключения не вызывает, просто игнорируя ошибочные случаи, что в современном программировании считается очень плохим стилем.
Нет подождите, мне всё же интересно понять… То есть вы говорите что раз оно не описано в справке, даже если находится в том же пространстве имён (то есть его показывает по точке для любой строки, при чём в самом начале) - это не часть PascalABC.Net?
Я же говорю не про функцию, ради которой надо что то подключать, а про то, что поумолчанию есть в каждой программе. Я так же мог бы понять, если бы вы имели в виду что часть языка - это то что запрограммировали разработчики. Но тот же .Remove - это тоже встроенная в .Net функция, которая отличается от .CopyTo только тем, что её нету в справке паскаля. А по справке сравнивать странно потому что:
Так же, разработчики сами писали когда то, что не собираются делать справку по всему что даёт .Net, ибо оно уже задокументировано на msdn, это была бы лишняя трата времени. То есть та справка так же может считаться описывающей часть данного языка. Или нет?
И можете ещё подробнее объяснить:
Я вообще не понял к чему это тут. Я хоть 2 из них знаю, но не использую, откуда у меня какое то мышление в их стиле?
Ну если Вы не нашли в части, посвященной символам и строкам, материала про методы строк - это Ваша проблема. Кроме того, не одними методами живет язык - еще есть процедуры и функции.
Это вовсе не обязательно часть РasacalABС.NЕТ. И не нужно делать вид, что это Вас удивило. Вы же не считаете, что при использовании #include в С++ все перечисленное там станет частью языка? А в PascalABC.NЕТ по умолчанию часть библиотек уже прилинкована, но частью языка от этого содержимое библиотек не стало. Такими рассуждениями можно дойти до того, что весь .NET - тоже часть языка, если разработчики создадут соответствующее пространство имен.
Писал не раз, не хочу повторяться. Хотите - считайте это моим частным мнением.
Забавная дискуссия. Как не косяк, так везде С-мышление виновато! Ох же ж оно, Кернигана с Ритчи надо ретроактивно абортировать!
От сабжа ушли. Кто б там, и каким образом не был виноват в ситуации, факт остаётся фактом: то, что в пределах одного языка строки и массивы индексируются то с нуля, то с единицы - фундаментально неправильно. И, кстати, лечится оно собственной реализацией набора тех самых extension-методов для сих структур данных, если я все правильно понимаю (может быть, и нет, поправьте, если нельзя). Пользователь языка не должен уметь отличать методы PABC.NET от методов .NET. Я б сказал, это вещь, достойная Issue на гитхабе.
Наследие совместимости. Ну вот решил когда-то так Н.Вирт, что символы в строках надо от единицы нумеровать. Как по мне, так оно правильно именно от единицы. Вот опять мне тут сейчас про Кернигана с Ритчи напомнят, но до “языка Це” массивы индексировались либо от единицы (Фортран, Бейсик), либо от описанной нижней границы (Алгол, PL/1), а символы в строках нумеровались от единицы. И это понятно: нормальные люди, как правило, издавна ведут счет от единицы. Нумерация от нуля была только в ассемблере из-за удобства работы со смещением от начала массива.
Вы что предлагаете? Совместимость со всеми остальными паскалями уничтожить, или индексировать массивы от нуля, а строки от единицы всегда, для чего перегрузить все, взятое из .NET? А LINQ тоже будем перегружать? С Matches как - там тоже от нуля нумерация?