Здравствуйте, Khimik, Вы писали:
K>Можно ли назвать такие record-ы статическими классами? У них есть инкапсуляция, но нет наследования и полиморфизма (наследование кстати авторам ЯП было бы нетрудно добавить).
Нельзя. Для рекордов и классов по разному работает управление памятью и передача параметров.
K>Проблема для меня в том, что нельзя писать такой record для каждого нового типа данных, а ещё по этой причине не получится так сделать двумерные динамические массивы. Но может быть эту проблему можно решить с помощью дженериков?
Можно.
>>Я пока не освоился с дженериками в Delphi, примеры на сайте связаны с классами, а с рекордами их не применишь?
Для таких задач я бы еще посмотрел на возможность в современных Delphi использовать динамический массив + хелперы к нему.
Но иметь в виду что в динамическом массиве медленно работает изменением размера.
Поэтому У нас аналогичная штука организована так
RArray<T> = record
private
a: TArray<T>;
const START_CAP = 16;
procedure grow(); inline;
function getItem(aIndex: Integer): T;
procedure setItem(aIndex: Integer; aValue: T);
function getLast(): T;
function getFirst(): T;
public
count: Integer;
constructor Create(aStartCap: Integer); overload;
constructor Create(aProc: TProcProc<T>); overload;
constructor Create(aList: TList<T>); overload;
constructor Create(aArray: RArray<T>); overload;
constructor Create(aT: T); overload;
class function init(): RArray<T>; static;
class function empty(): RArray<T>; static;
class function cast<Ch: T>(aArray: RArray<Ch>): RArray<T>; static;
procedure add(aElem: T); overload;
procedure add<V: T>(aArray: RArray<V>); overload;
procedure add(aArray: RArray<T>); overload;
procedure addTo(var aArray: RArray<T>);
procedure clear();
procedure delete(aIndex: Integer);
procedure sort(aComparer: IComparer<T>);
procedure asc(aFunc: TFunc<T, Double>);
procedure desc(aFunc: TFunc<T, Double>);
procedure reverse();
procedure assign(aSource: RArray<T>; aOperator: TListAssignOp = laCopy);
procedure assignOr(aSource: RArray<T>; aToken: TToken<T>);
function indexOf(aItem: T): Integer; overload;
function GetEnumerator: RArrayEnumerator<T>;
function some(aBool: TTBool<T>): Boolean;
function every(aBool: TTBool<T>): Boolean;
function forEach(aProc: TProc<T>): RArray<T>;
function map<TOut>(aFunc: TFunc<T, TOut>): RArray<TOut>; overload;
function map<TOut>(aProc: TOne2ManyP<T, TOut>): RArray<TOut>; overload;
function map(aFunc: TFunc<T, T>): RArray<T>; overload;
function filter(aFunc: TTBool<T>): RArray<T>;
function distinct(): RArray<T>;
function first(): RArray<T>;
function toList(): TList<T>;
function stream(): TRStream<T>;
property last: T read getLast;
property firstItem: T read getFirst;
property Item[index: integer]: T read getItem write setItem; default;
end;
TRStream<T> = class
private
fFeProc: TProc<T>;
fIsCanceled: Boolean;
fOnClose: TProc;
class var counter: Integer;
function _or(aBool: TTBool<T>): Boolean; overload;
function _every(aBool: TTBool<T>): Boolean; overload;
protected
procedure beforeClose(); virtual;
public
class constructor Create();
constructor Create();
destructor Destroy; override;
procedure close(); virtual;
function forEachS(aProc: TProc<T>): TRStream<T>; virtual;
procedure foreach(aProc: TProc<T>); virtual;
procedure iterate();
procedure cancel(); virtual;
function some(aBool: TTBool<T>): Boolean;
function every(aBool: TTBool<T>): Boolean;
function _or(aBool: TTBool<T>; var aResult: Boolean): TRStream<T>; overload;
function thread(): TRStream<T>;
function map<R>(aFunc: TFunc<T, R>): TRStream<R>; overload;
function map<R>(aProc: TOne2ManyP<T, R>): TRStream<R>; overload;
function map<R>(aFunc: TArrayFunc<T, R>): TRStream<R>; overload;
function map<R; Context: class>(aProc: TProcProcVar2<T, R, Context>): TRStream<R>; overload;
function map<R>(aFunc: TListFunc<T, R>): TRStream<R>; overload;
function map<R>(aFunc: TOne2StreamF<T, R>): TRStream<R>; overload;
function map<R>(aFunc: TStream2StreamF<T, R>): TRStream<R>; overload;
function map(aFunc: TFunc<T, T>): TRStream<T>; overload;
function map(aProc: TOne2ManyP<T, T>): TRStream<T>; overload;
function map(aProcs: array of TOne2ManyP<T, T>): TRStream<T>; overload;
function map(aFunc: TOne2StreamF<T, T>): TRStream<T>; overload;
function map(aFunc: TStream2StreamF<T, T>): TRStream<T>; overload;
function filter(aFunc: TTBool<T>): TRStream<T>;
function first(): TRStream<T>;
function distinct(aPool: TTokenPool<T> = nil): TRStream<T>; overload;
function distinct(aToken: TToken<T>): TRStream<T>; overload;
function tolist(aList: TList<T>): TRStream<T>;
procedure list(aList: TList<T>);
function toArray(var aArray: RArray<T>): TRStream<T>; overload;
function toArray(): RArray<T>; overload;
function debug(var aList: TList<T>): TRStream<T>;
function reduce(aFunc: TReduceFunc<T>): TRStream<T>;
function notMarked(aToken: TToken<T>): TRStream<T>;
function unmark(aToken: TToken<T>): TRStream<T>;
function mark(aToken: TToken<T>): TRStream<T>;
function onClose(aProc: TProc): TRStream<T>;
class function just(aT: T): TRStream<T>;
class function stream(aList: TList<T>): TRStream<T>; overload;
class function stream(aArray: RArray<T>): TRStream<T>; overload;
class function stream(aProc: TProcProc<RArray<T>>): TRStream<T>; overload;
end;