Re: Статические классы и дженерики (Delphi)
От: swame  
Дата: 08.12.18 06:46
Оценка:
Здравствуйте, 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;
Отредактировано 08.12.2018 7:04 swame . Предыдущая версия . Еще …
Отредактировано 08.12.2018 6:48 swame . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.