Всем спасибо за обсуждение. Вообще говоря, у меня есть своя реализация класса Vector<T>
работающего подобно классу Vector<T>
в C++ библиотеке STL и с поддержкой “ссылочных” срезов (реализованных без копирования самих элементов исходного вектора), но доступ к элементам вектора выглядит при этом не очень красивым. т.е. Vec[i]^ (с этой надоедливой крышечкой), а до этого был вариант (с недефолтным индексным свойством): Vec.ptr[i]^.
И что удивительного?
type
r = record
f: integer;
f1: string;
end;
begin
var a: r;
a.f := 10;
a.f1 := 'QWERTY';
var o := a;
a.f := 20;
o.f1 := 'ASDFGHJ';
println(o);
println(a);
end.
(10,ASDFGHJ)
(20,QWERTY)
В Справке сказано: Поскольку запись, в отличие от класса, представляет собой размерный тип, то присваивание записей копирует содержимое полей одной переменной-записи в другую:
d2 := d1
Перед очередным “открытием Америки” бывает полезно ознакомиться с матчастью.
Да ради бога, только все равно не понял, зачем она, если срезы и так поддерживаются. Ради “Вах, какой йа маладэс!” ?
А при чём тут срезы, Vector это ведь List,
Человек не использовал List, а срезы он захотел.и реализовал.
А вот интересно, класс System.Array не помечен как Sealed, но унаследовать от него нельзя. Почему?
Потому что от него можно наследовать только внутренним типам компилятора. Это как System.Delegate
.
Жаль. Интересные были бы возможности.
На самом деле System.Array
это вообще волшебный тип и он пашет только в каких так особых условиях. Так - наследуйте интерфейсы те же что и массивы, если хотите сделать свой массив. Интерфейсы тоже через GetType
можно вытащить, кстати))
Опаньки, а вот теперь подробнее!
begin
var a := Arr(0);
a.GetType
.GetInterfaces
.PrintLines
end.
В приведенном вами примере var o := a
т.е. o
имеет такой же тип как и а
, что отличается от var o: object := a
, где а
приводится к типу object
. Поэтому не столь очевидно и немного удивительно (хотя вероятно и закономерно для размерного типа), что создается копия структуры на которую ссылается объект o
.
Я не знаю, как у разработчиков это реализовано, и я не знаю, зачем это может быть нужно - так странно писать? Обычно в Паскале подобное пишут до предела развращенные языками типа С умы, но тут нужен врач, так что комментировать не стану.
В NET эта стандартная возможность называется “упаковка размерного типа в ссылочный”. Всё есть потомок object
Что касается реализации собственных типов, то это личное дело. List’ом немного пользовался, но у разных типов своя идеология. Я захотел повозможности повторить (в некотором приближении) Vector как библиотеке STL C++, дополнив возможностью обращения к элементам массива (где хранятся элементы вектора) от некоторого начального индекса с некоторым шагом т.е. пересчитываю индексы вектора в индексы массива, и таким образом реализовал срез (без копирования). Бывает же необходимость обработать именно какую часть массива. Так я могу взять срез от вектора и применить какой-то метод для этого среза (например сортировку), и эта сортировка затронет только часть исходного вектора в пределах среза. Просто, лично для меня такой поход оказывается наглядным. А вообще, меня восхищает связка Pascal + .NET. Выглядит как внешне где-то близок к скриптовому языку, а по быстродействию ух! Так что, в отличие от скриптового (вернее интерпретируемого) языка (например Python) можно писать не только верхний уровень, а вообще всё. Простота и наглядность.
Ну не знаю…писать свой класс, чтобы сделать вот это?
begin
var a:=ArrRandom;
a.Println;
a:=(a[:2]+a[2:5].OrderByDescending(t->t)+a[5:]).ToArray;
a.Println
end.
Да я просто не понял, ЗАЧЕМ так делать в данном случае
Можно так, а можно и другими способами. Все зависит не только от того что желаю получить, но и то каким способом и от наглядности написанного. Мне в этом отношении нравится демократический подход платформы .NET. Даже если создается собственный шаблонный класс, то в нем можно реализовать итератор и интерфейс System.IEnumarable<T>
(sequence of T
) и все методы и функции расширения для System.IEnumarable<T>
будут доступны!