stringtranslate.com

D (язык программирования)

D , также известный как dlang , — это мультипарадигмальный язык системного программирования , созданный Уолтером Брайтом из Digital Mars и выпущенный в 2001 году. Андрей Александреску присоединился к проектированию и разработке в 2007 году. Хотя он возник как реинжиниринг C++ , D теперь это совершенно другой язык, черпающий вдохновение из других языков программирования высокого уровня, в частности Java , Python , Ruby , C# и Eiffel .

Справочник по языку D описывает это следующим образом:

D — это язык системного программирования общего назначения с синтаксисом, подобным C, который компилируется в собственный код. Он статически типизирован и поддерживает как автоматическое (сбор мусора), так и ручное управление памятью. Программы D структурированы как модули, которые можно компилировать отдельно и связывать с внешними библиотеками для создания собственных библиотек или исполняемых файлов.

Функции

D не совместим с исходным кодом C и C++ в целом. Однако любой код, который допустим как для C, так и для D, должен вести себя одинаково.

Как и в C++, в D есть замыкания , анонимные функции , выполнение функций во время компиляции , диапазоны, встроенные концепции итерации контейнеров и вывод типов . В отличие от C++, D также реализует проектирование по контракту , модули , сборку мусора , массивы первого класса , нарезку массива , вложенные функции и отложенное вычисление . D использует одиночное наследование в стиле Java с интерфейсами и примесями , а не множественное наследование в стиле C++ . С другой стороны, синтаксис объявлений, операторов и выражений D очень похож на синтаксис C++.

D — язык системного программирования. Как и C++, D поддерживает низкоуровневое программирование , включая встроенный ассемблер , который символизирует различия между D и языками приложений, такими как Java и C# . Встроенный ассемблер позволяет программистам вводить ассемблерный код, специфичный для машины , в стандартный код D — метод, используемый системными программистами для доступа к низкоуровневым функциям процессора, необходимым для запуска программ, которые напрямую взаимодействуют с базовым оборудованием , например, с операционными системами и драйверами устройств. , а также написание высокопроизводительного кода (т. е. с использованием векторных расширений, SIMD ), который сложно сгенерировать компилятору автоматически.

D поддерживает перегрузку функций и перегрузку операторов . Символы (функции, переменные, классы) можно объявлять в любом порядке — форвардные объявления не требуются.

В D строки текстовых символов представляют собой массивы символов, а массивы в D проверяются по границам. [11] D имеет типы первого класса для комплексных и мнимых чисел. [12]

Парадигмы программирования

D поддерживает пять основных парадигм программирования :

Императив

Императивное программирование на D почти идентично программированию на C. Функции, данные, операторы, объявления и выражения работают так же, как и в C, и к библиотеке времени выполнения C можно получить прямой доступ. С другой стороны, некоторые заметные различия между D и C в области императивного программирования включают foreachконструкцию цикла D, которая позволяет выполнять цикл по коллекции, и вложенные функции , которые представляют собой функции, которые объявляются внутри других функций и могут обращаться к локальным переменным охватывающей функции. .

импорт стандартный . стдио ; void main () { int multiplier = 10 ; int Scaled ( int x ) { return x * multiplier ; }                foreach ( i ; 0 .. 10 ) { writefln ( «Привет, мир %d! Scaled = %d» , i , Scaled ( i )); } }         

Объектно-ориентированный

Объектно-ориентированное программирование в D основано на единой иерархии наследования, все классы которой являются производными от класса Object. D не поддерживает множественное наследование; вместо этого он использует интерфейсы в стиле Java , которые сравнимы с чистыми абстрактными классами C++, и миксины , которые отделяют общую функциональность от иерархии наследования. D также позволяет определять статические и финальные (не виртуальные) методы в интерфейсах.

Интерфейсы и наследование в D поддерживают ковариантные типы для возвращаемых типов переопределенных методов.

D поддерживает пересылку типов, а также дополнительную пользовательскую динамическую отправку .

Классы (и интерфейсы) в D могут содержать инварианты , которые автоматически проверяются до и после доступа к общедоступным методам в соответствии с методологией проектирования по контракту .

Многие аспекты классов (и структур) могут автоматически анализироваться во время компиляции (форма отражения с использованием type traits) и во время выполнения (RTTI/ TypeInfo), чтобы облегчить общий код или автоматическую генерацию кода (обычно с использованием методов времени компиляции).

Функциональный

D поддерживает такие функции функционального программирования , как функциональные литералы , замыкания , рекурсивно-неизменяемые объекты и использование функций высшего порядка . Существует два синтаксиса анонимных функций, включая форму с несколькими операторами и «сокращенную» запись с одним выражением: [13]

функция int ( int ) g ; г знак равно ( Икс ) { вернуть Икс * Икс ; }; // от руки g = ( x ) => x * x ; // сокращение                  

Существует два встроенных типа для функциональных литералов: function, который является просто указателем на функцию, выделенную в стеке, и delegate, который также включает указатель на соответствующий кадр стека , окружающую «среду», которая содержит текущие локальные переменные. Вывод типа может использоваться с анонимной функцией, и в этом случае компилятор создает a, delegateесли только он не может доказать, что указатель среды не является необходимым. Аналогично, для реализации замыкания компилятор помещает вложенные локальные переменные в кучу только в случае необходимости (например, если замыкание возвращается другой функцией и выходит из области действия этой функции). При использовании вывода типа компилятор также добавит атрибуты, такие как pureи, nothrowк типу функции, если сможет доказать их применимость.

Другие функциональные возможности, такие как каррирование и общие функции высшего порядка, такие как Map , Filter и Reduc , доступны через модули стандартной библиотеки std.functionalи std.algorithm.

импорт стандартный . стдио , станд . алгоритм , стандарт . диапазон ;   void main () { int [] a1 = [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ]; int [] a2 = [ 6 , 7 , 8 , 9 ];                      // должен быть неизменяемым, чтобы обеспечить доступ изнутри чистой функции immutable Pivot = 5 ;     int mySum ( int a , int b ) pure nothrow // чистая функция { if ( b <= Pivot ) // ссылка на охватывающую область return a + b ; иначе вернуть ;}                      // передача делегата (закрытие) автоматический результат = сокращение ! mySum ( цепочка ( a1 , a2 )); writeln ( "Результат:" , результат ); // Результат: 15         // передача литерала делегата result = сокращение !(( a , b ) => ( b <= Pivot ) ? a + b : a )( Chain ( a1 , a2 )); writeln ( "Результат: " , результат ); // Результат: 15 }                  

Альтернативно, приведенные выше композиции функций могут быть выражены с использованием унифицированного синтаксиса вызова функций (UFCS) для более естественного чтения слева направо:

 автоматический результат = a1 . цепочка ( а2 ). уменьшать ! мояСумма (); writeln ( "Результат:" , результат );      результат = а1 . цепочка ( а2 ). уменьшить !(( a , b ) => ( b <= пивот ) ? a + b : a )(); writeln ( "Результат:" , результат );               

Параллелизм

Концепции параллельного программирования реализованы в библиотеке и не требуют дополнительной поддержки со стороны компилятора. Однако система типа D и компилятор гарантируют, что совместное использование данных может быть обнаружено и прозрачно управляемо.

импорт стандартный . stdio : writeln ; импорт стандартный . диапазон : йота ; импорт стандартный . параллелизм : параллельный ;         void main () { foreach ( i ; iota ( 11 ) .parallel ) { // Тело цикла foreach выполняется параллельно для каждого i writeln ( "processing" , i ); } }         

iota(11).parallelэквивалентно std.parallelism.parallel(iota(11))использованию UFCS.

Тот же модуль также поддерживает операции taskPool, которые можно использовать для динамического создания параллельных задач, а также операции отображения-фильтрации-уменьшения и свертывания стилей над диапазонами (и массивами), что полезно в сочетании с функциональными операциями. std.algorithm.mapвозвращает лениво вычисляемый диапазон, а не массив. Таким образом, элементы автоматически вычисляются каждой рабочей задачей параллельно.

импорт стандартный . stdio : writeln ; импорт стандартный . алгоритм : карта ; импорт стандартный . диапазон : йота ; импорт стандартный . параллелизм : TaskPool ;            /* На Intel i7-3930X и gdc 9.3.0: * 5140 мс при использовании std.algorithm.reduce * 888 мс при использовании std.parallelism.taskPool.reduce * * На AMD Threadripper 2950X и gdc 9.3.0: * 2864 мс при использовании std.algorithm .reduce * 95 мс с использованием std.parallelism.taskPool.reduce */ void main () { auto nums = iota ( 1.0 , 1_000_000_000.0 );       авто x = TaskPool . уменьшать ! "a + b" ( 0.0 , карта ! "1.0 / (a ​​* a)" ( nums ) );       writeln ( "Сумма: " , x ); } 

Параллелизм

Параллелизм полностью реализован в библиотеке и не требует поддержки со стороны компилятора. Возможны альтернативные реализации и методологии написания параллельного кода. Использование системы типизации D действительно помогает обеспечить безопасность памяти.

импорт стандартный . стдио , станд . параллелизм , стандарт . вариант ;   void foo () { bool cont = true ;      while ( cont ) { receive ( //Делегаты используются для соответствия типу сообщения. ( int msg ) = > writeln ( "int got: " , msg ), ( Tid sender ) { cont = false ; sender.send (- 1 ) ); }, ( Variant v ) => writeln ( "huh?" ) // Вариант соответствует любому типу ); } }                        void main () { auto tid = spawn (& foo ); // создаем новый поток, выполняющий foo()       foreach ( i ; 0 .. 10 ) tid . отправить ( я ); // отправляем несколько целых чисел       время . отправить ( 1.0f ); // отправляем плавающий tid . отправить ( «привет» ); // отправляем строку tid . отправить ( этотид ); // отправляем структуру (Tid)      получить (( int x ) => writeln ( «Основной поток получил сообщение: « , x )); }    

Метапрограммирование

Метапрограммирование поддерживается посредством шаблонов, выполнения функций во время компиляции, кортежей и строковых миксинов. Следующие примеры демонстрируют некоторые возможности D во время компиляции.

Шаблоны в D могут быть написаны в более императивном стиле по сравнению с функциональным стилем шаблонов C++. Это обычная функция, вычисляющая факториал числа:

ulong факториал ( ulong n ) { if ( n < 2 ) вернуть 1 ; иначе вернуть n * факториал ( n - 1 ); }              

Здесь показано использование static ifусловной конструкции D во время компиляции для создания шаблона, который выполняет те же вычисления с использованием кода, аналогичного коду функции выше:

шаблон Factorial ( ulong n ) { static if ( n < 2 ) enum Factorial = 1 ; else enum Factorial = n * Факториал !( n - 1 ); }                   

В следующих двух примерах шаблон и функция, определенные выше, используются для вычисления факториалов. Типы констант не обязательно указывать явно, поскольку компилятор определяет их типы из правых частей присваивания:

enum fact_7 = Факториал !( 7 );   

Это пример выполнения функции во время компиляции (CTFE). Обычные функции могут использоваться в константных выражениях времени компиляции при условии, что они соответствуют определенным критериям:

перечисление факт_9 = факториал ( 9 );   

Функция std.string.formatвыполняет printfформатирование данных в формате -like (также во время компиляции, через CTFE), а прагма «msg» отображает результат во время компиляции:

импорт стандартный . строка : формат ; прагма ( msg , format ( «7! = %s» , fact_7 )); прагма ( сообщение , формат ( «9! = %s» , fact_9 ));       

Строковые миксины в сочетании с выполнением функций во время компиляции позволяют генерировать D-код с использованием строковых операций во время компиляции. Это можно использовать для анализа предметно-ориентированных языков , которые будут скомпилированы как часть программы:

импортировать ФуТоД ; // гипотетический модуль, содержащий функцию, которая анализирует исходный код Foo // и возвращает эквивалентный код D void main () { mixin ( fooToD ( import ( "example.foo" ))); }      

Управление памятью

Память обычно управляется с помощью сборки мусора , но определенные объекты могут быть финализированы немедленно, когда они выходят за пределы области действия. Именно это использует большинство программ и библиотек, написанных на D.

В случае, если требуется больший контроль над расположением памяти и более высокая производительность, возможно явное управление памятью с помощью перегруженного оператора new , прямым вызовом C malloc и free или реализацией пользовательских схем распределения (т. е. в стеке с резервным вариантом, распределение в стиле RAII, ссылка подсчет, общий подсчет ссылок). Сборкой мусора можно управлять: программисты могут добавлять и исключать диапазоны памяти из наблюдения сборщика, могут отключать и включать сборщик, а также принудительно запускать либо генерационный, либо полный цикл сбора. [14] В руководстве приведено множество примеров того, как реализовать различные высокооптимизированные схемы управления памятью, когда сборка мусора в программе неадекватна. [15]

В функциях structэкземпляры по умолчанию размещаются в стеке, а classэкземпляры по умолчанию размещаются в куче (с ссылкой только на экземпляр класса, находящийся в стеке). Однако это можно изменить для классов, например, используя шаблон стандартной библиотеки std.typecons.scopedили используя newструктуры и присваивая указатель вместо переменной, основанной на значении. [16]

В функциях статические массивы (известного размера) размещаются в стеке. Для динамических массивов можно использовать core.stdc.stdlib.allocaфункцию (аналогично allocaC) для выделения памяти в стеке. Возвращенный указатель может быть использован (переведен) в (типизированный) динамический массив посредством среза (однако следует избегать изменения размера массива, включая добавление; и по очевидным причинам они не должны возвращаться из функции). [16]

Ключевое scopeслово можно использовать как для аннотирования частей кода, так и для переменных и классов/структур, чтобы указать, что они должны быть уничтожены (вызов деструктора) немедленно при выходе из области видимости. Независимо от того, какая память будет освобождена, также зависит от реализации и различий между классами и структурами. [17]

std.experimental.allocatorсодержит модульные и компонуемые шаблоны распределителей для создания пользовательских высокопроизводительных распределителей для особых случаев использования. [18]

СейфД

SafeD [19] — это имя, данное подмножеству D, которое может быть гарантированно безопасным для памяти (нет записи в память, которая не была выделена или была переработана). Отмеченные функции @safeпроверяются во время компиляции, чтобы гарантировать, что они не используют какие-либо функции, которые могут привести к повреждению памяти, такие как арифметика указателей и непроверяемые приведения, а любые другие вызываемые функции также должны быть помечены как @safeили @trusted. Функции могут быть отмечены @trustedдля случаев, когда компилятор не может отличить безопасное использование функции, отключенной в SafeD, от потенциального случая повреждения памяти. [20]

Безопасность на весь срок службы

Первоначально под названиями DIP1000 [21] и DIP25 [22] (теперь часть спецификации языка [23] ) D обеспечивает защиту от некоторых некорректных конструкций, включающих время жизни данных.

Существующие в настоящее время механизмы в основном работают с параметрами функций и стековой памятью, однако лидеры языка программирования заявляют о стремлении обеспечить более тщательную обработку времени жизни в языке программирования D [24] (под влиянием идей языка программирования Rust). ).

Пожизненная сохранность заданий

В коде @safe проверяется время существования назначения, включающего ссылочный тип , чтобы убедиться, что время жизни получателя больше, чем время жизни назначенного.

Например:

@safe void test () { int tmp = 0 ; // #1 int * рад ; // #2 рад = & tmp ; // Если порядок объявлений №1 и №2 обратный, это не удастся. { инт плохо = 45 ; // Время жизни "плохого" распространяется только на ту область, в которой оно определено. * рад = плохо ; // Это действительно. рад = & плохо ; // Срок жизни рад больше, чем плохой, поэтому это неверно. } }                             

Аннотации времени жизни параметров функции в коде @safe

При применении к параметру функции, который имеет тип указателя или ссылку, ключевые слова return и область действия ограничивают время существования и использование этого параметра.

Стандарт языка диктует следующее поведение: [25]

Аннотированный пример приведен ниже.

@безопасный :интервал * гп ; void Thorin ( scope int *); пустота глоин ( int *); int * balin ( возвращает область действия int * p , область действия int * q , int * r ) { gp = p ; // Ошибка, p переходит в глобальную переменную gp. гп = q ; // Ошибка, q переходит в глобальную переменную gp. гп = р ; // ХОРОШО.                          Торин ( р ); // Хорошо, p не экранирует функцию Thorin(). Торин ( q ); // ХОРОШО. Торин ( р ); // ХОРОШО.      глоин ( р ); // Ошибка, p выходит за пределы globin(). глоин ( q ); // Ошибка, q выходит из globin(). глоин ( р ); // Хорошо, что r экранирует glein().      вернуть п ; // ХОРОШО. вернуть д ; // Ошибка, невозможно вернуть 'scope' q. вернуть р ; // ХОРОШО. }        

Взаимодействие с другими системами

Поддерживается бинарный интерфейс приложений C (ABI) , а также все фундаментальные и производные типы C, что обеспечивает прямой доступ к существующему коду и библиотекам C. Привязки D доступны для многих популярных библиотек C. Кроме того, стандартная библиотека C является частью стандарта D.

В Microsoft Windows D может получить доступ к коду модели компонентных объектов (COM).

Если об управлении памятью позаботиться должным образом, многие другие языки могут быть смешаны с D в одном двоичном файле. Например, компилятор GDC позволяет связывать и смешивать C, C++ и другие поддерживаемые языковые коды, такие как Objective-C. Код D (функции) также может быть помечен как использующий ABI C, C++, Pascal и, таким образом, передаваться в библиотеки, написанные на этих языках, в качестве обратных вызовов . Аналогичным образом данные могут обмениваться кодами, написанными на этих языках, обоими способами. Обычно это ограничивает использование примитивных типов, указателей, некоторых форм массивов, объединений , структур и только некоторых типов указателей на функции.

Поскольку многие другие языки программирования часто предоставляют API C для написания расширений или запуска интерпретатора языков, D также может напрямую взаимодействовать с этими языками, используя стандартные привязки C (с тонким файлом интерфейса D). Например, существуют двунаправленные привязки для таких языков, как Python , [26] Lua [27] [28] и других языков, часто использующие генерацию кода во время компиляции и методы отражения типов во время компиляции.

Взаимодействие с кодом C++

Для кода D, отмеченного как extern(C++), указаны следующие характеристики:

Пространства имен C++ используются через синтаксис, extern(C++, namespace)где пространство имен — это имя пространства имен C++.

Пример взаимодействия C++

Сторона C++

#include <iostream> с использованием пространства имен std ; класс Base { public : virtual void print3i ( int a , int b , int c ) = 0 ; };               класс Произведенный : public Base { public : int field ; Производное ( целое поле ) : поле ( поле ) {}             void print3i ( int a , int b , int c ) { cout << "a = " << a << endl ; cout << "b = " << b << endl ; cout << "c = " << c << endl ; }                              int mul ( int коэффициент ); };  int Derived::mul ( int Factor ) { возвращаемое поле * Factor ; }      Derived * createInstance ( int i ) { return new Derived ( i ); }     void deleteInstance ( Derived *& d ) { delete d ; д = 0 ; }       

Сторона D

extern ( C ++) { абстрактный класс Base { void print3i ( int a , int b , int c ); }             Производный класс : Base { int field ; @отключить это (); переопределить void print3i ( int a , int b , int c ); окончательный int mul ( int коэффициент ); }                      Производный createInstance ( int i ); void deleteInstance ( ref Derived d ); }      void main () { import std . стдио ;    авто d1 = createInstance ( 5 ); writeln ( d1 . поле ); writeln ( d1 . mul ( 4 ));      База b1 = d1 ; б1 . print3i ( 1 , 2 , 3 );       удалитьэкземпляр ( d1 ); утверждать ( d1 имеет значение null );    авто d2 = createInstance ( 42 ); writeln ( d2 . поле );     удалить экземпляр ( d2 ); утверждать ( d2 имеет значение null ); }   

Лучше С

Язык программирования D имеет официальное подмножество, известное как Better C. [29] Этот подмножество запрещает доступ к функциям D, требующим использования библиотек времени выполнения, отличных от библиотеки C.

Включенный с помощью флагов компилятора «-betterC» в DMD и LDC и «-fno-druntime» в GDC, Better C может вызывать только код D, скомпилированный под тем же флагом (и связанный код, отличный от D), но код, скомпилированный без Вариант Better C может вызывать код, скомпилированный с его помощью: однако это приведет к несколько разному поведению из-за различий в том, как C и D обрабатывают утверждения.

Функции, включенные в Better C

Функции, исключенные из Better C

История

Уолтер Брайт начал работу над новым языком в 1999 году. D был впервые выпущен в декабре 2001 года [1] и достиг версии 1.0 в январе 2007 года. [30] Первая версия языка (D1) была сосредоточена на императивном, объектно-ориентированном и метапрограммировании. парадигмы, [31] аналогичные C++.

Некоторые члены сообщества D, недовольные Phobos, официальной средой выполнения и стандартной библиотекой D , создали альтернативную среду выполнения и стандартную библиотеку под названием Tango. Первое публичное объявление о Tango произошло через несколько дней после выпуска D 1.0. [32] Tango приняла другой стиль программирования, включающий ООП и высокую модульность. Будучи проектом под руководством сообщества, Tango был более открыт для вкладов, что позволяло ему развиваться быстрее, чем официальная стандартная библиотека. В то время Tango и Phobos были несовместимы из-за разных API-интерфейсов поддержки времени выполнения (сборщик мусора, поддержка потоков и т. д.). Это сделало невозможным использование обеих библиотек в одном проекте. Существование двух библиотек, обе широко используемых, привело к серьезным спорам из-за того, что некоторые пакеты используют Phobos, а другие - Tango. [33]

В июне 2007 года была выпущена первая версия D2. [34] Начало развития D2 ознаменовало стабилизацию D1. Первая версия языка была помещена на обслуживание, в нее вносились только исправления и исправления ошибок реализации. D2 внесла в язык критические изменения , начиная со своей первой экспериментальной системы const . Позже в D2 были добавлены многочисленные другие функции языка, такие как замыкания , чистота и поддержка парадигм функционального и параллельного программирования. D2 также решил проблемы стандартной библиотеки, отделив среду выполнения от стандартной библиотеки. О завершении порта D2 Tango было объявлено в феврале 2012 года. [35]

Выпуск книги Андрея Александреску «Язык программирования D» 12 июня 2010 года ознаменовал стабилизацию языка D2, который сегодня обычно называют просто «D».

В январе 2011 года разработка D перешла с системы отслеживания ошибок/отправки исправлений на GitHub . Это привело к значительному увеличению вклада в компилятор, среду выполнения и стандартную библиотеку. [36]

В декабре 2011 года Андрей Александреску объявил, что поддержка D1, первой версии языка, будет прекращена 31 декабря 2012 года. [37] Последний выпуск D1, D v1.076, состоялся 31 декабря 2012 года. [38]

Код официального компилятора D, компилятора Digital Mars D Уолтера Брайта, изначально был выпущен под специальной лицензией , квалифицируясь как доступный исходный код , но не соответствующий определению открытого исходного кода . [39] В 2014 году интерфейс компилятора был повторно лицензирован как открытый исходный код по лицензии Boost Software License . [3] Этот повторно лицензированный код исключал серверную часть, которая была частично разработана в Symantec . 7 апреля 2017 года весь компилятор стал доступен по лицензии Boost после того, как Symantec разрешила также повторно лицензировать серверную часть. [4] [40] [41] [42] 21 июня 2017 года язык D был принят для включения в GCC. [43]

Реализации

Большинство современных реализаций D компилируются непосредственно в машинный код .

Готовые к производству компиляторы:

Игрушечные и экспериментальные компиляторы:

Используя вышеуказанные компиляторы и наборы инструментов, можно скомпилировать программы D для множества различных архитектур, включая IA-32 , amd64 , AArch64 , PowerPC , MIPS64 , DEC Alpha , Motorola m68k , SPARC , s390 , WebAssembly . Основными поддерживаемыми операционными системами являются Windows и Linux , но различные компиляторы также поддерживают Mac OS X , FreeBSD , NetBSD , AIX , Solaris/OpenSolaris и Android либо в качестве хоста, либо в качестве целевого устройства, либо в качестве обоих. Цель WebAssembly (поддерживается через LDC и LLVM) может работать в любой среде WebAssembly, например в современном веб-браузере ( Google Chrome , Mozilla Firefox , Microsoft Edge , Apple Safari ) или выделенных виртуальных машинах Wasm.

Инструменты разработки

Редакторы и интегрированные среды разработки (IDE), поддерживающие подсветку синтаксиса и частичное завершение кода для языка, включают SlickEdit , Emacs , vim , SciTE , Smultron , Zeus, [55] и Geany среди других. [56]

Существуют IDE D с открытым исходным кодом для Windows , некоторые из которых написаны на D, например Poseidon, [68] D-IDE, [69] и Entice Designer. [70]

Приложения D можно отлаживать с помощью любого отладчика C/C++, например GDB или WinDbg , хотя поддержка различных функций языка, специфичных для D, крайне ограничена. В Windows программы D можно отлаживать с помощью Ddbg или инструментов отладки Microsoft (WinDBG и Visual Studio) после преобразования отладочной информации с помощью cv2pdb. ZeroBUGS, заархивированный 23 декабря 2017 года в отладчике Wayback Machine для Linux, имеет экспериментальную поддержку языка D. Ddbg можно использовать с различными IDE или из командной строки; ZeroBUGS имеет собственный графический интерфейс пользователя (GUI).

DustMite — это инструмент для минимизации исходного кода D, полезный при обнаружении проблем с компилятором или тестированием. [71]

dub — популярный менеджер пакетов и сборки для приложений и библиотек D, который часто интегрируется в поддержку IDE. [72]

Примеры

Пример 1

Этот пример программы печатает аргументы командной строки. Функция mainявляется точкой входа в программу D и argsпредставляет собой массив строк, представляющих аргументы командной строки. A stringв D — это массив символов, представленный immutable(char)[].

импорт стандартный . stdio : writefln ;  void main ( string [] args ) {    Еогеасп ( я , аргумент ; аргументы )    writefln ( "args[%d] = '%s'" , i , arg );  }

Оператор foreachможет перебирать любую коллекцию. В этом случае он создает последовательность индексов ( i) и значений ( arg) из массива args. Типы индекса iи значения argопределяются из типа массива args.

Пример 2

Ниже показаны некоторые возможности D и компромиссы при проектировании D в короткой программе. Он перебирает строки текстового файла с именем words.txt, который содержит разные слова в каждой строке, и печатает все слова, которые являются анаграммами других слов.

импорт стандартный . стдио , станд . алгоритм , стандарт . диапазон , стандарт . нить ;    пустая функция () {   dstring [] [ dstring ] подпись2 слова ;   foreach ( dchar [] w ; lines ( File ( "words.txt" ))) {     ш = ш . чавкать (). понижать ();   неизменяемая подпись = w . дуп . Сортировать (). выпускать (). идентификатор ;    подпись2слова [ подпись ] ~= w . идентификатор ;   } Еогеасп ( слова ; подпись2слова ) {    если ( слова . длина > 1 ) {     writeln ( words.join ( " " )) ; } }}
  1. signature2words— это встроенный ассоциативный массив, который сопоставляет ключи dstring (32-битные / символьные) с массивами dstrings. Это похоже defaultdict(list)на Python .
  2. lines(File())выдает строки лениво, с переводом строки. Затем его необходимо скопировать, idupчтобы получить строку, которая будет использоваться для значений ассоциативного массива ( idupсвойство arrays возвращает неизменяемый дубликат массива, который необходим, поскольку dstringна самом деле тип immutable(dchar)[]). Встроенные ассоциативные массивы требуют неизменяемых ключей.
  3. Оператор ~=добавляет новую строку значений к значениям связанного динамического массива.
  4. toLowerи joinявляются chompстроковыми функциями, которые D позволяет использовать с синтаксисом метода. Имена таких функций часто похожи на строковые методы Python. Преобразует toLowerстроку в нижний регистр, join(" ")объединяет массив строк в одну строку, используя один пробел в качестве разделителя, и chompудаляет новую строку из конца строки, если она присутствует. Более w.dup.sort().release().idupчитабелен, но эквивалентен, release(sort(w.dup)).idupнапример. Эта функция называется UFCS (унифицированный синтаксис вызова функций) и позволяет расширять любые встроенные или сторонние типы пакетов функциональностью, подобной методу. Подобный стиль написания кода часто называют конвейерным (особенно когда используемые объекты лениво вычисляются, например итераторы/диапазоны) или интерфейсом Fluent .
  5. Это sortфункция std.algorithm, которая сортирует массив на месте, создавая уникальную подпись для слов, которые являются анаграммами друг друга. Метод release()возвращаемого значения sort()удобен для хранения кода в виде одного выражения.
  6. Второй foreachперебирает значения ассоциативного массива и может определить тип words.
  7. signatureприсваивается неизменяемой переменной, выводится ее тип.
  8. Вместо обычного UTF-8dchar[] используется UTF-32 , иначе сортировка отказывается. Есть более эффективные способы написать эту программу, используя только UTF-8. char[]sort()

Использование

Известные организации, использующие язык программирования D для проектов, включают Facebook , [73] eBay , [74] и Netflix . [75]

D успешно использовался для игр AAA , [76] языковых интерпретаторов, виртуальных машин, [77] [78] ядра операционной системы , [79] программирования графического процессора , [80] веб-разработки , [81] [82] численного анализа , [83] Приложения с графическим пользовательским интерфейсом , [84] [85] Система информации о пассажирах , [86] Машинное обучение, [87] Обработка текста, веб-серверы и серверы приложений и исследования.

Печально известная северокорейская хакерская группа, известная как Lazarus , использовала CVE-2021-44228, также известную как « Log4Shell », для развертывания трех семейств вредоносных программ , написанных на DLang. [88]

Смотрите также

Рекомендации

  1. ^ ab «Журнал изменений D до 7 ноября 2005 г.» . D Язык программирования 1.0 . Цифровой Марс . Проверено 1 декабря 2011 г.
  2. ^ «Журнал изменений: 2.104.0» . Проверено 25 июня 2023 г.
  3. ^ abc «Внешний интерфейс dmd теперь переключен на лицензию Boost» . Проверено 9 сентября 2014 г.
  4. ^ abc «Бэкенд dmd преобразован в Boost License». 7 апреля 2017 года . Проверено 9 апреля 2017 г.
  5. ^ «Часто задаваемые вопросы по D 2.0» . Проверено 11 августа 2015 г.
  6. ^ «Язык программирования D — Fileinfo.com» . Проверено 15 ноября 2020 г.[ нужна цитата ]
  7. ^ «Язык программирования D — dlang.org» . Проверено 15 ноября 2020 г.[ нужна цитата ]
  8. ^ «Включено: Показать HN: хороший API строк C» . Хакерские новости . 3 декабря 2022 г. Проверено 4 декабря 2022 г.
  9. ^ Александреску, Андрей (2010). Язык программирования D (Первое изд.). Река Аппер-Сэддл, Нью-Джерси: Аддисон-Уэсли. п. 314. ИСБН 978-0321635365.
  10. ^ «Создание Assert() в Swift, Часть 2: __FILE__ и __LINE__» . Проверено 25 сентября 2014 г.
  11. ^ «Строки D против строк C++». Цифровой Марс. 2012.
  12. ^ «Сложные типы D и C++ std::complex». Цифровой Марс . 2012. Архивировано из оригинала 13 января 2008 года . Проверено 4 ноября 2021 г.
  13. ^ «Выражения». Цифровой Марс . Проверено 27 декабря 2012 г.
  14. Ссылки D Язык программирования 1.0 . Цифровой Марс . Проверено 6 июля 2010 г.
  15. ^ «Управление памятью». D Язык программирования 2.0 . Цифровой Марс . Проверено 17 февраля 2012 г.
  16. ^ ab «Иди своим путем (Часть первая: Стек)» . Блог D. 7 июля 2017 года . Проверено 7 мая 2020 г.
  17. ^ «Атрибуты — язык программирования D» . dlang.org . Проверено 7 мая 2020 г.
  18. ^ "std.experimental.allocator - язык программирования D" . dlang.org . Проверено 7 мая 2020 г.
  19. ^ Бартош Милевский. «Язык программирования SafeD-D» . Проверено 17 июля 2014 г.
  20. Стивен Швейгхоффер (28 сентября 2016 г.). «Как написать @trusted-код на D» . Проверено 4 января 2018 г.
  21. ^ «Указатели с областью действия». Гитхаб . 3 апреля 2020 г.
  22. ^ «Запечатанные ссылки».
  23. ^ «Спецификация языка D: Функции — параметры возвращаемой области» .
  24. ^ «Собственность и заимствование в D». 15 июля 2019 г.
  25. ^ «Спецификация языка D: Функции — Классы хранения параметров функций» .
  26. Ссылки Гитхаб . 7 мая 2020 г. Проверено 7 мая 2020 г.
  27. ^ Паркер, Майк. «Пакет заброшенного Lua на DUB». Реестр пакетов DUB . Проверено 7 мая 2020 г.
  28. ^ Паркер, Майк. «Пакетbindbc-lua в DUB». Реестр пакетов DUB . Проверено 7 мая 2020 г.
  29. ^ «Лучше С».
  30. ^ "Журнал изменений D" . D Язык программирования 1.0 . Цифровой Марс . Проверено 11 января 2012 г.
  31. ^ «Введение». D Язык программирования 1.0 . Цифровой Марс . Проверено 1 декабря 2011 г.
  32. ^ «Анонсируем новую библиотеку» . Проверено 15 февраля 2012 г.
  33. ^ «Wiki4D: Стандартная библиотека» . Проверено 6 июля 2010 г.
  34. ^ «Журнал изменений - язык программирования D» . D Язык программирования 2.0 . Языковой фонд D. Проверено 22 ноября 2020 г.
  35. ^ «Танго для D2: все пользовательские модули перенесены» . Проверено 16 февраля 2012 г.
  36. ^ Уолтер Брайт. «Re: GitHub или dsource?» . Проверено 15 февраля 2012 г.
  37. ^ Андрей Александреску. «Выпуск D1 будет прекращен 31 декабря 2012 г.» . Проверено 31 января 2014 г.
  38. ^ "Журнал изменений D" . D Язык программирования 1.0 . Цифровой Марс . Проверено 31 января 2014 г.
  39. ^ "backendlicense.txt". Исходный код DMD . Гитхаб. Архивировано из оригинала 22 октября 2016 года . Проверено 5 марта 2012 г.
  40. ^ "Комментарий Уолтера Брайта на Reddit" . 5 марта 2009 года . Проверено 9 сентября 2014 г.
  41. ^ D-Compiler-unter-freier-Lizenz на linux-magazin.de (2017, на немецком языке)
  42. ^ переключите серверную часть на лицензию Boost № 6680 от Уолтера Брайта на github.com.
  43. ^ D Язык принят для включения в GCC
  44. Ссылки
  45. ^ «Серия выпусков GCC 9 — изменения, новые функции и исправления - Проект GNU - Фонд свободного программного обеспечения (FSF)» . gcc.gnu.org . Проверено 7 мая 2020 г.
  46. ^ «Еще один интерфейс для GCC» . forum.dlang.org . Проверено 7 мая 2020 г.
  47. ^ «Изменения, новые функции и исправления серии выпусков GCC 9» .
  48. ^ «Проект компилятора LLVM D на GitHub» . Гитхаб . Проверено 19 августа 2016 г.
  49. ^ «BuildInstructionsPhobosDruntimeTrunk – ldc – Язык программирования D – Trac» . Проверено 11 августа 2015 г.
  50. ^ «Проект D .NET на CodePlex» . Архивировано из оригинала 26 января 2018 года . Проверено 3 июля 2010 г.
  51. Джонатан Аллен (15 мая 2009 г.). «Исходный код компилятора D.NET теперь доступен». ИнфоQ . Проверено 6 июля 2010 г.
  52. ^ «Сделайте SDC компилятором Snazzy D» . Гитхаб . Проверено 24 сентября 2023 г.
  53. ^ DConf 2014: SDC, компилятор D как библиотека Амори Сечета. YouTube . Проверено 8 января 2014 г.Архивировано в Ghostarchive и Wayback Machine.
  54. ^ "deadalnix/SDC". Гитхаб . Проверено 8 января 2014 г.
  55. ^ "Wiki4D: EditorSupport/ZeusForWindows" . Проверено 11 августа 2015 г.
  56. ^ «Wiki4D: Поддержка редактора» . Проверено 3 июля 2010 г.
  57. ^ "Basile.B / dexed" . ГитЛаб . Проверено 29 апреля 2020 г.
  58. ^ "Моно-D-D Wiki" . wiki.dlang.org . Проверено 30 апреля 2020 г.
  59. ^ «Mono-D – Поддержка D для MonoDevelop» . Архивировано из оригинала 1 февраля 2012 года . Проверено 11 августа 2015 г.
  60. ^ «Хостинг проектов Google» . Проверено 11 августа 2015 г.
  61. ^ "Спуск" . Проверено 11 августа 2015 г.
  62. ^ «Визуальный язык программирования D-D» . Проверено 11 августа 2015 г.
  63. Шютце, Райнер (17 апреля 2020 г.). «rainers/visuald: Visual D — расширение Visual Studio для языка программирования D». github.com . Проверено 30 апреля 2020 г.
  64. ^ "дланг-vscode". Гитхаб . Проверено 21 декабря 2016 г.
  65. ^ "код-d". Гитхаб . Проверено 21 декабря 2016 г.
  66. ^ «Мишель Фортен – D для Xcode» . Проверено 11 августа 2015 г.
  67. ^ "Dav1dde/люмен" . Гитхаб . Проверено 11 августа 2015 г.
  68. ^ "Посейдон" . Проверено 11 августа 2015 г.
  69. ^ «Mono-D – Поддержка D для MonoDevelop» . Проверено 11 августа 2015 г.
  70. ^ «Entice Designer – Dprogramming.com – Язык программирования D» . Проверено 11 августа 2015 г.
  71. ^ «Что такое DustMite?». Гитхаб . Проверено 29 апреля 2020 г.
  72. ^ «dlang/dub: Система управления пакетами и сборками для D» . Гитхаб . Проверено 29 апреля 2020 г.
  73. ^ «Под капотом: warp, быстрый препроцессор C и C++». 28 марта 2014 года . Проверено 4 января 2018 г.
  74. ^ «Более быстрые инструменты командной строки в D» . 24 мая 2017 года . Проверено 4 января 2018 г.
  75. ^ «Представляем векторный поток» . 2 августа 2017 г. Проверено 4 января 2018 г.
  76. ^ «Квантовый перерыв: игры AAA с некоторым кодом D» . Проверено 4 января 2018 г.
  77. ^ «Виртуальная машина Хиггса JavaScript» . Гитхаб . Проверено 4 января 2018 г.
  78. ^ «Реализация AD языка программирования ECMA 262 (Javascript)» . Гитхаб . Проверено 4 января 2018 г.
  79. ^ «Основной момент проекта: ядро ​​PowerNex» . 24 июня 2016 года . Проверено 4 января 2018 г.
  80. ^ «DCompute: запуск D на графическом процессоре» . 30 октября 2017 г. Проверено 4 января 2018 г.
  81. ^ «vibe.d — высокопроизводительный набор инструментов для асинхронного ввода-вывода, параллелизма и веб-приложений, написанный на D» . Проверено 4 января 2018 г.
  82. ^ «Основной момент проекта: Diamond MVC Framework» . 20 ноября 2017 года . Проверено 4 января 2018 г.
  83. ^ «Числовой возраст D: Mir GLAS быстрее, чем OpenBLAS и Eigen» . Проверено 4 января 2018 г.
  84. ^ «О Тиликсе и D: Интервью с Джеральдом Нанном». 11 августа 2017 года . Проверено 4 января 2018 г.
  85. ^ «Основной проект: DlangUI» . 7 октября 2016 г. Проверено 4 января 2018 г.
  86. ^ "Основной проект: Фанкверк" . 28 июля 2017 года . Проверено 4 января 2018 г.
  87. ^ "Netflix/vectorflow" . GitHub.com . Netflix, Inc. 5 мая 2020 г. . Проверено 7 мая 2020 г.
  88. ^ «Хакеры Lazarus распространяют новое вредоносное ПО RAT, используя ошибку Log4j двухлетней давности» . 11 декабря 2023 г. Проверено 11 декабря 2023 г.

дальнейшее чтение

Внешние ссылки