Классы типов в PascalABC.NET пока ещё очень слабые и с багами.
Надеюсь, баги будут устраняться.
Классы типов напоминают интерфейсы, но лучше. В них можно использовать операции.
Вот пример для начала:
type
Less[T] = typeclass
function operator<(x, y: T): boolean;
end;
Less[integer] = instance
function operator<(x, y: integer): boolean := x<y;
end;
function MinIndex<T>(a: array of T): integer; where Less[T];
begin
Result := -1;
var min := a[0];
for var i:=0 to a.Length - 1 do
if a[i]<min then
begin
Result := i;
min := a[i];
end;
end;
begin
var a := Arr(10,3,5,7,8);
MinIndex(a).Println;
end.
Здесь вишенкой на торте является возможность использовать операцию < обобщённом коде.
Это напоминает C++, но это не так. MinIndex будет работать только с массивами типа T, удовлетворяющего классу типов Less[T]
type
Ordering = (_EQ, _LT, _GT);
Eq[T] = typeclass
function operator=(x, y: T): boolean := not (x <> y);
function operator<>(x, y: T): boolean := not (x = y);
end;
Ord[T] = typeclass(Eq[T])
function compare(x, y: T): Ordering;
begin
if x = y then Result := _EQ
else if less(x, y) then Result := _LT
else Result := _GT;
end;
function Less(x, y: T): boolean := compare(x, y) = _LT;
function Greater(x, y: T): boolean := compare(x, y) = _GT;
function LessEqual(x, y: T): boolean := compare(x, y) <> _GT;
function GreaterEqual(x, y: T): boolean := compare(x, y) <> _LT;
function operator>(x, y: T): boolean := greater(x, y);
function operator<(x, y: T): boolean := less(x, y);
function operator>=(x, y: T): boolean := greaterEqual(x, y);
function operator<=(x, y: T): boolean := lessEqual(x, y);
function Min(x, y: T): T := x < y ? x : y;
function Max(x, y: T): T := x > y ? y : x;
end;
type
tc1[T] = typeclass
function operator>(a,b:T):boolean;
end;
t1=abstract class
v:real;
end;
tc1[t1] = instance
function operator>(a,b:t1):boolean := a.v>b.v;
end;
begin
var o1,o2:t1;
writeln(o1>o2);
end.
Хотя, тут, конечно, уже можно в самом классе определить оператор. Но разница в том что его придётся 2 раза определить, если он используется и во where и не_шаблонным кодом.
В смысле не ключевое – не выделяется жирным в редакторе? Тогда попробуйте установить вот этот файл PascalABCNET.xshd (11,7 КБ)
с кастомными настройками (просто замените оригинальный в папке c:\Program Files (x86)\PascalABC.NET\Highlighting\).
Как и с неймспейсами - сначала компилятор, потом анализатор кода и только после этого Ctrl+Space и выделение жирным. Оно, кстати, ещё и не форматируется (из за анализатора кода). В общем да, стадия на столько же экспериментальная как и у namespace, но в отличии от него - typeclass активно дорабатывается.
@admin объясните всё же проблему инстансов интерфейсов.
Интерфейсы это в основном ограниченые абстрактные классы, с только 1 личной фичей - их можно несколько сразу наследовать в 1 классе. Если взять это во внимание - я вижу только 1 случай с конфликтами:
type
I1=interface end;
I2=interface end;
t1=class(I1,I2) end;
tc1[T]=typeclass
function f1:integer;
end;
tc1[I1]=instance
function f1 := 1;
end;
tc1[I2]=instance
function f1 := 2;
end;
procedure p1<T>(a:T);
where tc1[T];
begin
writeln(a.f1);
end;
begin
p1(new t1)
end.
То есть, в случае когда в инстансах обоим интерфейсам есть одинаковая функция f1.
Вот только точно такой же конфликт появляется при 2 where:
type
t1=class end;
tc1[T]=typeclass
function f1:integer;
end;
tc2[T]=typeclass
function f1:integer;
end;
tc1[t1]=instance
function f1 := 1;
end;
tc2[t1]=instance
function f1 := 2;
end;
procedure p1<T>(a:T);
where tc1[T];
where tc2[T];
begin
writeln(a.f1);
end;
begin
p1(new t1);
end.
Это ведь не повод запрещать 2 where?)) Надо выводить “несколько подпрограмм могут быть вызваны”, а не запрещать потенциально полезные конструкции.
Поправьте если я чего то не понял, вместо того чтоб продолжать игнорировать этот вопрос.
Про инстансы интерфейсов уже есть Issue. Повторять не буду - мы это запретим.
Про секцию с двумя where - я Ваш код не понимаю. он не работает с override-ошибкой.
Принципиальная ошибка вашего кода - Вы определяете в instance то, чего нет в классе типов, а это неправильно. Вторая принципиальная ошибка - Вы пользуетесь a.f1, хотя ни в одном классе типов нет f1.
Там сообщение об ошибке неудачное - да, спасибо: Program1.pas(8) : Нет метода для переопределения
Оно дурацкое конечно. Но по сути правильно - нечего переопределять
Я и не прошу повторять. Я прошу объяснить почему, что именно с ними не так.
Прямо сейчас, в доступном билде, любой код выдаёт Undefined FileName, поэтому я по сути писал весь код без компилятора, вот и не заметил. Поправил. Но это не меняет сути, того что я пытался показать.
Ну так а может она не револьвентна для этого языка? Я в интернете несколько раз искал, не нашёл ничего про несовместимость интерфейсов и классов типов.