type
T = class
end;
function operator+(var x, y: T); extensionmethod := default(T);
procedure operator+=(var x, y: T); extensionmethod := exit;
function operator-(var x, y: T); extensionmethod := default(T);
procedure operator-=(var x, y: T); extensionmethod := exit;
function operator*(var x, y: T); extensionmethod := default(T);
procedure operator*=(var x, y: T); extensionmethod := exit;
function operator/(var x, y: T); extensionmethod := default(T);
procedure operator/=(var x, y: T); extensionmethod := exit;
function operator mod(var x, y: T); extensionmethod := default(T);
function operator div(var x, y: T); extensionmethod := default(T);
function operator=(var x, y: T); extensionmethod := false;
function operator<>(var x, y: T); extensionmethod := false;
function operator<(var x, y: T); extensionmethod := false;
function operator<=(var x, y: T); extensionmethod := false;
function operator>(var x, y: T); extensionmethod := false;
function operator>=(var x, y: T); extensionmethod := false;
// Недопустимо использование var в первом параметре extension-метода
//function ExtensionA(var self, y: T); extensionmethod := default(T);
//procedure ExtensionB(var self, y: T); extensionmethod := exit;
begin
end.
Хотелось бы выяснить причину данного запрета (для себя). Код выше доказывает то, что в операторах расширения var параметры разрешены, в отличии от процедур и функций расширения.
Нет. Такое использование и не предполагалось. Предполагался, следующий код:
type
T = record
public X: integer;
end;
procedure Change(var self: T); extensionmethod := self.X := 2;
begin
end.
Не могу оценить насколько было бы это полезно - на практике таким пользоваться не приходилось. Могу лишь указать на тот факт, что эта возможность языка предусматривалась бы не для повседневного пользования, как трейты. И также обращаю внимание на то, что данное сообщение не побуждение разработчиков изменять свой язык.
Это оператор, а их присваивать можно только коротким процедурам
Но вот здесь всё-таки должно выводиться 2, а потому нужен var:
type
T = record
public X: integer;
end;
procedure Change({var} self: T); extensionmethod := self.X := 2;
begin
var v := new T;
v.Change;
v.X.Print;//0
end.
@Admin может неявно делать self - var-параметром, если у него размерный тип? Тогда extensionmethod-ы будут работать так же как просто методы в случае записей.
Но, если пользователю не требуется var параметр? Предполагаю, что лучшим решением (с моей точки зрения, мнение разработчиков может быть отличным от моего) будет дать пользователю самому выбирать - ставить ли var или нет.
begin
var hs: HashSet<string>;
var s: string;
writeln(hs = s);
end.
Вместо человеко-читаемой ошибки Операция '=' не применима к типам HashSet<string> и string
Выдаёт: Нет перегруженной подпрограммы с такими типами параметров
Нет. Это перегруженная подпрограмма. Компилятор не различает операции и методы. Для него это всё подпрограммы. Перегруженные для разных типов. Когда вы определяете =, вы перегружаете эту операцию