На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! ПРАВИЛА РАЗДЕЛА · FAQ раздела Delphi · Книги по Delphi
Пожалуйста, выделяйте текст программы тегом [сode=pas] ... [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.
Следующие вопросы задаются очень часто, подробно разобраны в FAQ и, поэтому, будут безжалостно удаляться:
1. Преобразовать переменную типа String в тип PChar (PAnsiChar)
2. Как "свернуть" программу в трей.
3. Как "скрыться" от Ctrl + Alt + Del (заблокировать их и т.п.)
4. Как прочитать список файлов, поддиректорий в директории?
5. Как запустить программу/файл?
... (продолжение следует) ...

Вопросы, подробно описанные во встроенной справочной системе Delphi, не несут полезной тематической нагрузки, поэтому будут удаляться.
Запрещается создавать темы с просьбой выполнить какую-то работу за автора темы. Форум является средством общения и общего поиска решения. Вашу работу за Вас никто выполнять не будет.


Внимание
Попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
Повторная попытка - 60 дней. Последующие попытки бан.
Мат в разделе - бан на три месяца...
Модераторы: jack128, D[u]fa, Shaggy, Rouse_
Страницы: (2) 1 [2]  все  ( Перейти к последнему сообщению )  
> Непонятки
    Цитата jack128 @
    по поводу inline variables вот

    На апдейтовом делфи рио, приведеный там код с TDictionary пашет.

    По моему примеру я немного ошибся с терминологией по массивам уже больно запутано в делфи :D
    Ща сек все разберу по полочкам...

    Итак давайте разберем их на моем примере. Есть статические и динамческие массивы:
    ExpandedWrap disabled
      type
        TVoices = array [1..3] of IVoice;
      begin
        // dynamic array
        var voices:= TArray<IVoice>.Create(TDog.Create, TCat.Create, TDog.Create);
       
        // static array
        var voices: TVoices;
        voices[1] := TDog.Create;
        voices[2] := TCat.Create;
        voices[3] := TDog.Create;
       
       ....

    а также есть так называемые открытые массивы, они существуют только как параметры, например array of T в функции Map:
    ExpandedWrap disabled
      class function TArrayHelper.Map<T, R>(const Values: array of T; //<-- open array parameter
        AProc: TMapProc<T, R>): TArray<R>;

    в него можно передать как статик так и динамик массив
    ExpandedWrap disabled
      var funcs := TArray.Map<IVoice, TFunc<string>>(voices, //<-- dynamic or static array
      .....

    У меня же по коду идет ни тот ни другой :D
    Какой? На новых делфи (не знаю с какой точно версии), но в Рио можно делать такую шутку:
    ExpandedWrap disabled
      var voices:= [TDog.Create, TCat.Create, TDog.Create];

    это объявление динамического массива констант (dynamic array constant), не путайте с array of const. array of const - это особый тип открытого массива, который задается как параметр функции, пример тому знаменитая функция Format :D
    Так вот я передаю динамический массив констант voices в функцию Map, которая ждет либо динамический либо статический массив, наш же имеет другой тип! Чтобы решить траблу можно сделать как я привел выше в примере, т.е указать явно тип переменой и уже потом инициализировть массив
    ExpandedWrap disabled
      var voices: TArray<IVoice> := [TDog.Create, TCat.Create, TDog.Create];
      ...

    или сразу создать динамич. массив через TArray<T>.Create
    ExpandedWrap disabled
      var voices:= TArray<IVoice>.Create(TDog.Create, TCat.Create, TDog.Create);
      ...
    Сообщение отредактировано: Cfon -
      Цитата Cfon @
      У меня же по коду идет ни тот ни другой
      Какой? На новых делфи (не знаю с какой точно версии), но в Рио можно делать такую шутку:

      var voices:= [TDog.Create, TCat.Create, TDog.Create];

      это объявление динамического массива констант (dynamic array constant)


      У меня нету Rio, не могу проверить. Сразу возникает вопрос, какой тип у переменной voices? TArray<TVarRec>? TArray<TObject>? TArray<IVoice> ? Где нить описана логика вывода типа массива? Термин "dynamic array constant" не разу не слышал.
        Цитата jack128 @
        У меня нету Rio, не могу проверить. Сразу возникает вопрос, какой тип у переменной voices? TArray<TVarRec>? TArray<TObject>? TArray<IVoice> ?

        Ни один из приведенных :huh:, типом voices является dynamic array constants или я хз какой он там на самом деле :jokingly: (в переводе по гугл транслейту :D это константы динамического массива )
        Если я пишу следущее то ошибка компиляции
        ExpandedWrap disabled
          var voices:= [TDog.Create, TCat.Create, TDog.Create];
           
          var funcs := TArray.Map<IVoice, TFunc<string>>(voices, //<-- вот на эту строчку
              function (v: IVoice; i: integer): TFunc<string>
              begin
                ..
              end);
          // [dcc32 Error]: E2010 Incompatible types: 'array of IVoice' and 'Dynamic array'

        Что тут 'array of IVoice' а что 'Dynamic array' я хз :D
        по идее voices это 'Dynamic array', а параметр функции это 'array of IVoice'
        Цитата jack128 @
        Где нить описана логика вывода типа массива? Термин "dynamic array constant" не разу не слышал.

        Вот тут я нашел про них
        http://rvelthuis.de/articles/articles-openarr.html

        Да еще забыл упомянуть про конструкторы открытого массива (open array constructor) они напоминают форму dynamic array constants, но передаются сразу как параметры функции, моем случае будет так
        ExpandedWrap disabled
          var funcs := TArray.Map<IVoice, TFunc<string>>([TDog.Create, TCat.Create, TDog.Create], //<-- open array constructor
              function (v: IVoice; i: integer): TFunc<string>
              begin
                ....
              end);

        В такой форме код компилица.
        А не стоп, не только как параметр функции, но и вот тут вроде как тоже open array constructor :D:
        ExpandedWrap disabled
          var voices: TArray<IVoice> := [TDog.Create, TCat.Create, TDog.Create]; //<-- open array constructor


        Самое не понятное для меня было следущее:
        Я поначалу не сразу просек про параметр открытый массив (open array parameter)
        ExpandedWrap disabled
          class function TArrayHelper.Map<T, R>(const Values: array of T; //<-- open array parameter
            AProc: TMapProc<T, R>): TArray<R>;
          ...

        я думал что это одно и тоже что и
        ExpandedWrap disabled
          class function TArrayHelper.Map<T, R>(const Values: TArray<T>; //<-- dynamic array parameter
            AProc: TMapProc<T, R>): TArray<R>;
          ...

        поскольку TArray<T> описан как
        ExpandedWrap disabled
          type TArray<T> = array of T

        но приведенный выше пример является динамич. массивом, а не открытым массивом. Разница их в том как я уже писал выше в открытый массив можно передать и статич.массив и динамич.массив и конструктор открытого массива! Ой *бать замутили :lool:, а в дин.массив естесно кроме динамик нельзя ничего передать. Уфф вроде разобрался :D
        Сообщение отредактировано: Cfon -
          Цитата Cfon @
          Где нить описана логика вывода типа массива? Термин "dynamic array constant" не разу не слышал.

          Вот тут я нашел про них
          http://rvelthuis.de/articles/articles-openarr.html

          в примере из статьи как раз все понятно, там явно указан тип переменной:

          ExpandedWrap disabled
            var
              MyDynArray: array of Integer; // безымянный дин массив интов
            begin
              MyDynArray := [17, 325, 11];


          В твоем случае ж случае тип переменной как то выводится компилятором, вот мне и интересно как.

          Цитата Cfon @
          типом voices является dynamic array constants

          Забьем пока на тип массива, хотя бы с типом элемента массива разобраться бы.

          ExpandedWrap disabled
            var voices:= [TDog.Create, TCat.Create, TDog.Create];
            voices[0].Free; // компилируется ??
            voices[1]._AddRef(); // компилируется?
            var x := voices[1000]; // компилируется ?
            Цитата jack128 @
            Забьем пока на тип массива, хотя бы с типом элемента массива разобраться бы.

            ExpandedWrap disabled
              var voices:= [TDog.Create, TCat.Create, TDog.Create];
              voices[0].Free; // компилируется ??
              voices[1]._AddRef(); // компилируется?
              var x := voices[1000]; // компилируется ?

            ExpandedWrap disabled
              voices[0].Free; // компилируется ??  да  
              voices[1]._AddRef(); // компилируется? нет [dcc32 Error]: E2003 Undeclared identifier: '_AddRef'
              var x := voices[1000]; // компилируется ? да

            все кроме второго компиляца и без рантайм ошибок.

            Если посмотреть на список Code Insight для voices[i], то он напоминает TObject, но если я передаю voices в процедуру:
            ExpandedWrap disabled
              procedure Test(A: TArray<TObject>);
              begin
              end;
               
              begin
                var voices:=[TDog.Create, TCat.Create, TDog.Create];
                Test(voices);
              end;
              // [dcc32 Error]: E2010 Incompatible types: 'System.TArray<System.TObject>' and 'Dynamic array'

            Ради интереса посмотрел в простом цикле
            ExpandedWrap disabled
                var voices:=[TDog.Create, TCat.Create, TDog.Create];
                for var I := 0 to High(voices) do
                begin
                  Writeln(voices[i].ClassName);
                end;
              // Output:
              // TDog
              // TCat
              // TDog

            Пробую привести к IVoice ошибка пишет что voice[i] - TObject :lool:
            ExpandedWrap disabled
                var voices:=[TDog.Create, TCat.Create, TDog.Create];
                for var I := 0 to High(voices) do
                begin
                  Writeln(IVoice(voices[i]).Voice);
                end;
                // [dcc32 Error]: E2010 Incompatible types: 'IVoice' and 'TObject'


            Прокатило если определить открытый массив TObject :D
            ExpandedWrap disabled
              procedure Test(A: array of TObject);
              begin
                for var I := 0 to High(A) do
                begin
                  Writeln(A[i].ClassName);
                end;
              end;
               
              begin
                Test(voices);
              // Output:
              // TDog
              // TCat
              // TDog
              end.

            Какие выводы? voices это array of TObject :huh:
            Сообщение отредактировано: Cfon -
              А теперь хардкор :D
              Предлагаю вашему вниманию версию примера с функцией Reduce. Добавляем поддержку Reduce к нашему TArrayHelper. Что делает Reduce? Она обрабатывает исходный массив и сводит (reduce) к другому типу потенциально любому типу! Давайте посмотрим как это выглядит:
              ExpandedWrap disabled
                type
                  TForEachProc<T> = reference to procedure (Value: T; Index: Integer);
                  TMapProc<T, R> = reference to function (Value: T; Index: Integer): R;
                  TReduceProc<T, R> = reference to function (Accumulator: R; Value: T): R;
                 
                  TArrayHelper = class helper for TArray
                    class procedure ForEach<T>(const Values: array of T; AProc: TForEachProc<T>); static;
                    class function Map<T, R>(const Values: array of T; AProc: TMapProc<T, R>): TArray<R>; static;    
                    class function Reduce<T, R>(const Values: array of T; AProc: TReduceProc<T, R>; InitValue: R): R; static;
                  end;
                 
                { TArrayHelper }
                 
                ....
                 
                class function TArrayHelper.Reduce<T, R>(const Values: array of T;
                  AProc: TReduceProc<T, R>; InitValue: R): R;
                begin
                  Result := InitValue;
                  for var I := 0 to High(Values) do
                    Result := AProc(Result, Values[i]);
                end;
                 
                 
                begin
                  var voices:= TArray<IVoice>.Create(TDog.Create, TCat.Create, TDog.Create);
                 
                  var funcs := TArray.Reduce<IVoice, TArray<TFunc<string>>>(voices,
                    function (accum: TArray<TFunc<string>>; value: IVoice): TArray<TFunc<string>>
                    begin
                      Result:= accum + [function: string
                        begin
                          Result := value.Voice
                        end];
                    end, []);
                 
                  // test
                  for var fn in funcs do Writeln(fn());
                 
                  Readln;
                end.

              Результат тот же, но пришлось моск изрядно напрячь, код явно не для слабонервных :D
              Хотя для хакселистов он покажется простым :jokingly:
              Понятно что данную задачу Map решает проще, но сам по себе Reduce пригодиться во многих других задачах где Map будет бессилен. А Reduce это такой швейцарски нож решит любую задачу.
              Сообщение отредактировано: Cfon -
                Вот, полюбопытствуй.
                  Вообще насчет адресов методов и прочего, вот как вариант
                  ExpandedWrap disabled
                    var
                      voices: TArray<IVoice>;
                      m: TMethod;
                      ob: TObject;
                    begin
                      ob := voices[0] as TAnimal;
                      m.Data := (ob);
                      m.Code := (ob).MethodAddress('Voice');
                      memLog.Lines.Add(TFuncOfObj<string>(m)());


                  TMethod самодостаточный (содержит как адрес метода, так и адрес самого объекта).
                  Единственное, что у меня почему-то MethodAddress возвращает nil даже со включенным RTTI, хотя нигде нет упоминаний, что этой функции вообще требуются какие-то условия. Вот тут инфа с примерами https://stackoverflow.com/questions/4186458...red-in-a-string
                    Цитата jack128 @
                    Вот, полюбопытствуй.

                    Я ее давно скачал, чтобы в перспективе поюзать DI container :D.
                    Функционал енумератора Spring4D смотрел.. пока туман :D
                    Доков нет плохо, как я понял там Select аналог Map?

                    Цитата Fr0sT @
                    Вообще насчет адресов методов и прочего, вот как вариант

                    Что то мудрено, через анонимку то изичи :D
                    Сообщение отредактировано: Cfon -
                      Варик на Spring4D :D
                      ExpandedWrap disabled
                        uses Spring.Collections;
                         
                        begin
                          var voices := TArray<IVoice>.Create(TDog.Create, TCat.Create, TDog.Create);
                         
                          var funcs := TEnumerable.Select<IVoice, TFunc<string>>(
                            TCollections.CreateList<IVoice>(voices),
                            function (v: IVoice): TFunc<string>
                            begin
                              Result:= function: string
                                begin
                                  Result := v.Voice;
                                end;
                            end);
                         
                          // test
                          for var fn in funcs do Writeln(fn());
                         
                          Readln;
                        end.
                      Сообщение отредактировано: Cfon -
                        Цитата Cfon @
                        Функционал енумератора Spring4D смотрел.. пока туман :D
                        Доков нет плохо, как я понял там Select аналог Map?

                        А все нашел примеры, это шарповый LINQ Enumerable один в один :D
                        https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable?view=netframework-4.7.2
                        Скомуниздили из линка энумератор спринги :D
                        Сообщение отредактировано: Cfon -
                          А зачем, собственно, сохранять методы в отрыве от объектов?
                            Цитата Fr0sT @
                            А зачем, собственно, сохранять методы в отрыве от объектов?

                            Какие методы от каких объектов?
                              Voice. От созданных
                                Цитата Fr0sT @
                                Voice. От созданных

                                Э-э-э, я думал мы про Enumerable шарповский уже говорим.

                                По поводу Voice - никто не хотел отдельно от объектовинтерфейсов хранить методы. Хотелось неявное преобразование из метода интерфейса к анонимной функции, как это сделано с методами объекта.
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0602 ]   [ 16 queries used ]   [ Generated: 28.03.24, 15:34 GMT ]