D (язык программирования)
Эта статья содержит контент, написанный как реклама . ( январь 2024 г. ) |
Парадигма | Мультипарадигмальность : функциональная , императивная , объектно-ориентированная. |
---|---|
Разработано | Уолтер Брайт , Андрей Александреску (с 2007 г.) |
Разработчик | Языковой фонд D |
Впервые появился | 8 декабря 2001 г [1] |
Стабильная версия | 2.108.0 [2] / 1 апреля 2024 г |
Дисциплина набора текста | Предполагаемый , статичный , сильный |
ТЫ | FreeBSD , Linux , MacOS , Windows |
Лицензия | Способствовать росту [3] [4] [5] |
Расширения имен файлов | .д [6] [7] |
Веб-сайт | дланг |
Основные реализации | |
DMD ( эталонная реализация ), GCC ,
ГДК , НРС , СЗС | |
Под влиянием | |
БАЗОВЫЙ , [8] C , C++ , C# , Эйфель , [9] Ява , Питон | |
Под влиянием | |
Джинн , MiniD, Писатель , Свифт , [10] Vala , C++11 , C++14 , C++17 , C++20 , Go , C# и другие. | |
|
D , также известный как dlang , — это мультипарадигмальный язык системного программирования , созданный Уолтером Брайтом из Digital Mars и выпущенный в 2001 году. Андрей Александреску присоединился к проектированию и разработке в 2007 году. Хотя он возник как реинжиниринг C++ , D теперь это совершенно другой язык, черпающий вдохновение из других языков программирования высокого уровня, в частности Java , Python , Ruby , C# и Eiffel .
Справочник по языку D описывает это следующим образом:
D — это язык системного программирования общего назначения с синтаксисом, подобным C, который компилируется в собственный код. Он статически типизирован и поддерживает как автоматическое (сбор мусора), так и ручное управление памятью. Программы D структурированы как модули, которые можно компилировать отдельно и связывать с внешними библиотеками для создания собственных библиотек или исполняемых файлов. [11]
Особенности [ править ]
D не совместим с исходным кодом C и C++ в целом. Однако любой код, который допустим как для C, так и для D, должен вести себя одинаково.
Как и в C++, в D есть замыкания , анонимные функции , выполнение функций во время компиляции , диапазоны, встроенные концепции итерации контейнеров и вывод типов . В отличие от C++, D также реализует проектирование по контракту , модули , сборку мусора , первого класса массивы , нарезку массива , вложенные функции и отложенное вычисление . в стиле Java D использует одиночное наследование с интерфейсами и примесями, а не множественное наследование в стиле C++ . С другой стороны, синтаксис объявлений, операторов и выражений D очень похож на синтаксис C++.
D — язык системного программирования. Как и C++, D поддерживает низкоуровневое программирование, включая встроенный ассемблер , который символизирует различия между D и языками приложений, такими как Java и C# . Встроенный ассемблер позволяет программистам вводить ассемблерный код , специфичный для машины , в стандартный код D — метод, используемый системными программистами для доступа к низкоуровневым функциям процессора, необходимым для запуска программ, которые напрямую взаимодействуют с базовым оборудованием , например, с операционными системами и драйверами устройств. , а также написание высокопроизводительного кода (т. е. с использованием векторных расширений, SIMD ), который сложно сгенерировать компилятору автоматически.
D поддерживает перегрузку функций и перегрузку операторов . Символы (функции, переменные, классы) можно объявлять в любом порядке — форвардные объявления не требуются.
В D строки текстовых символов представляют собой массивы символов, а массивы в D проверяются по границам. [12] D имеет типы первого класса для комплексных и мнимых чисел. [13]
Парадигмы программирования [ править ]
D поддерживает пять основных парадигм программирования :
Императив [ править ]
Императивное программирование на D почти идентично программированию на C. Функции, данные, операторы, объявления и выражения работают так же, как и в C, и к библиотеке времени выполнения C можно получить прямой доступ. С другой стороны, некоторые заметные различия между D и C в области императивного программирования включают в себя foreach
конструкция цикла, позволяющая выполнять цикл по коллекции, и вложенные функции , которые объявляются внутри других функций и могут обращаться к локальным переменным включающей функции .
импорт стандартный . стдио ;
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 поддерживает такие функции функционального программирования , как функциональные литералы , замыкания , рекурсивно-неизменяемые объекты и использование функций высшего порядка . Существует два синтаксиса анонимных функций, включая форму с несколькими операторами и «сокращенную» нотацию с одним выражением: [14]
int функция ( int ) g ;
г знак равно ( Икс ) { вернуть Икс * Икс ; }; // от руки
g = ( x ) => x * x ; // сокращение
Существует два встроенных типа функциональных литералов: function
, который является просто указателем на функцию, выделенную в стеке, и delegate
, который также включает указатель на соответствующий кадр стека , окружающую «среду», содержащую текущие локальные переменные. Вывод типа может использоваться с анонимной функцией, и в этом случае компилятор создает delegate
если только он не сможет доказать, что указатель среды не нужен. Аналогично, чтобы реализовать замыкание, компилятор помещает вложенные локальные переменные в кучу только в случае необходимости (например, если замыкание возвращается другой функцией и выходит из области действия этой функции). При использовании вывода типа компилятор также добавит такие атрибуты, как pure
и nothrow
к типу функции, если можно доказать их применимость.
Другие функциональные возможности, такие как каррирование и общие функции высшего порядка, такие как карта , фильтр и сокращение, доступны через модули стандартной библиотеки. 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 полученное: " msg ) ,
( Tid sender ) { cont = false ; sender.send , ( - 1 ); },
( Variant v ) => writeln ( "huh?" ) // Вариант соответствует любому типу
);
}
}
void main ()
{
auto tid = spawn (& foo ); // создаем новый поток, выполняющий foo()
foreach ( i ; 0 .. 10 )
tid . отправить ( я ); // отправляем несколько целых чисел
tid . отправить ( 1.0f ); // отправляем плавающий
tid . отправить ( «привет» ); // отправляем строку
tid . отправить ( этотид ); // отправляем структуру (Tid)
получения (( int x ) => writeln ( «Основной поток получил сообщение: « , x ));
}
Metaprogramming [ edit ]
Метапрограммирование поддерживается посредством шаблонов, выполнения функций во время компиляции, кортежей и строковых миксинов. Следующие примеры демонстрируют некоторые возможности 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 );
The std.string.format
функция выполняет printf
-подобное форматированию данных (также во время компиляции, через 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, подсчет ссылок, общий подсчет ссылок). Сборкой мусора можно управлять: программисты могут добавлять и исключать диапазоны памяти из наблюдения сборщика, могут отключать и включать сборщик, а также принудительно запускать либо генерационный, либо полный цикл сбора. [15] В руководстве приведено множество примеров того, как реализовать различные высокооптимизированные схемы управления памятью, когда в программе неадекватна сборка мусора. [16]
В функциях struct
экземпляры по умолчанию размещаются в стеке, а class
экземпляры по умолчанию размещаются в куче (с ссылкой только на экземпляр класса, находящийся в стеке). Однако это можно изменить для классов, например, используя шаблон стандартной библиотеки. std.typecons.scoped
или с помощью new
для структур и присвоения указателю вместо переменной, основанной на значении. [17]
В функциях статические массивы (известного размера) размещаются в стеке. Для динамических массивов можно использовать core.stdc.stdlib.alloca
функция (аналогично alloca
в C), чтобы выделить память в стеке. Возвращенный указатель может быть использован (переведен) в (типизированный) динамический массив посредством среза (однако следует избегать изменения размера массива, включая добавление; и по очевидным причинам они не должны возвращаться из функции). [17]
А scope
Ключевое слово можно использовать как для аннотирования частей кода, так и для переменных и классов/структур, чтобы указать, что они должны быть уничтожены (вызов деструктора) немедленно при выходе из области видимости. Независимо от того, какая память будет освобождена, также зависит от реализации и различий между классами и структурами. [18]
std.experimental.allocator
содержит модульные и компонуемые шаблоны распределителей для создания пользовательских высокопроизводительных распределителей для особых случаев использования. [19]
СафеД [ править ]
СейфД [20] это имя, присвоенное подмножеству D, которое может быть гарантированно безопасным для памяти (без записи в память, которая не была выделена или была переработана). Функции отмечены @safe
проверяются во время компиляции, чтобы гарантировать, что они не используют какие-либо функции, которые могут привести к повреждению памяти, такие как арифметика указателей и непроверяемые приведения типов, а любые другие вызываемые функции также должны быть помечены как @safe
или @trusted
. Функции могут быть отмечены @trusted
для случаев, когда компилятор не может отличить безопасное использование функции, отключенной в SafeD, от потенциального повреждения памяти. [21]
Безопасность на весь срок службы [ править ]
Изначально под баннерами ДИП1000 [22] и ДИП25 [23] (теперь часть спецификации языка [24] ), D обеспечивает защиту от некоторых некорректных конструкций, включающих время жизни данных.
Существующие в настоящее время механизмы в основном имеют дело с параметрами функций и стековой памятью, однако руководство языка программирования заявляет о своей цели обеспечить более тщательную обработку времени жизни в языке программирования D. [25] (под влиянием идей языка программирования Rust ).
Пожизненная безопасность заданий [ править ]
В коде @safe проверяется время существования назначения, включающего ссылочный тип , чтобы убедиться, что время жизни правопреемника больше, чем время жизни назначенного.
Например:
@safe void test ()
{
int tmp = 0 ; // #1
int * рад ; // #2
рад = & tmp ; // Если порядок объявлений №1 и №2 обратный, это не удастся.
{
интервал плохо = 45 ; // Время жизни "плохого" распространяется только на ту область, в которой оно определено.
* рад = плохо ; // Это действительно.
рад = & плохо ; // Срок жизни рад больше, чем плохой, поэтому это неверно.
}
}
Аннотации времени жизни параметров функции в коде @safe [ править ]
При применении к параметру функции, который имеет тип указателя или ссылку, ключевые слова return и область действия ограничивают время существования и использование этого параметра.
Стандарт языка диктует следующее поведение: [26]
Класс хранилища | Поведение (и ограничения) параметра с классом хранения |
---|---|
объем | Ссылки в параметре не могут быть экранированы. Игнорируется для параметров без ссылок |
возвращаться | Параметр может быть возвращен или скопирован в первый параметр, но в противном случае он не выходит из функции. Такие копии должны не пережить аргумент(ы), из которых они были получены. Игнорируется для параметров без ссылок |
Аннотированный пример приведен ниже.
@safe :
int * gp ;
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 экранирует globin().
вернуть п ; // ХОРОШО.
вернуть д ; // Ошибка, невозможно вернуть 'scope' q.
вернуть р ; // ХОРОШО.
}
Взаимодействие с другими системами [ править ]
а , двоичный интерфейс приложений C (ABI) Поддерживается D также все фундаментальные и производные типы C, что обеспечивает прямой доступ к существующему коду и библиотекам C. Привязки доступны для многих популярных библиотек C. C Кроме того, стандартная библиотека является частью стандарта D.
В Microsoft Windows D может получить доступ к коду модели компонентных объектов (COM).
Если об управлении памятью позаботиться должным образом, многие другие языки могут быть смешаны с D в одном двоичном файле. Например, компилятор GDC позволяет связывать и смешивать C, C++ и другие поддерживаемые языковые коды, такие как Objective-C. Код D (функции) также может быть помечен как использующий ABI C, C++, Pascal и, таким образом, передаваться в библиотеки, написанные на этих языках, в качестве обратных вызовов . Аналогичным образом данные могут обмениваться между кодами, написанными на этих языках, обоими способами. Обычно это ограничивает использование примитивных типов, указателей, некоторых форм массивов, объединений , структур и только некоторых типов указателей на функции.
Поскольку многие другие языки программирования часто предоставляют API C для написания расширений или запуска интерпретатора языков, D также может напрямую взаимодействовать с этими языками, используя стандартные привязки C (с тонким файлом интерфейса D). Например, существуют двунаправленные привязки для таких языков, как Python , [27] Два [28] [29] и другие языки, часто использующие методы генерации кода и отражения типов во время компиляции.
Взаимодействие с кодом C++ [ править ]
Для кода D, отмеченного как extern(C++)
, указаны следующие особенности:
- Соглашения об изменении имен должны соответствовать соглашениям C++ в целевой системе.
- Для вызовов функций ABI должен быть эквивалентным.
- Виртуальная таблица должна соответствовать одиночному наследованию (единственному уровню, поддерживаемому спецификацией языка D).
Пространства имен 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 ;
Derived ( int field ) : field ( field ) {}
void print3i ( int a , int b , int c )
{
cout << "a = " << a << endl ;
cout << "b = " << b << endl ;
cout << "c = " << c << endl ;
}
Int mul ( инт- коэффициент );
};
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 );
}
Лучше C [ править ]
Язык программирования D имеет официальное подмножество, известное как Better C. [30] Это подмножество запрещает доступ к функциям D, требующим использования библиотек времени выполнения, отличных от библиотеки C.
Включенный с помощью флагов компилятора «-betterC» в DMD и LDC и «-fno-druntime» в GDC, Better C может вызывать только код D, скомпилированный под тем же флагом (и связанный код, отличный от D), но код, скомпилированный без Вариант Better C может вызывать код, скомпилированный с его помощью: однако это приведет к несколько другому поведению из-за различий в том, как C и D обрабатывают утверждения.
включенные в Better , Функции C
- Неограниченное использование функций времени компиляции (например, функции динамического выделения D можно использовать во время компиляции для предварительного выделения данных D)
- Полные возможности метапрограммирования
- Вложенные функции, вложенные структуры, делегаты и лямбды.
- Функции-члены, конструкторы, деструкторы, операционная перегрузка и т. д.
- Полная модульная система
- Нарезка массива и проверка границ массива
- РАИИ
- область действия (выход)
- Защита памяти
- Взаимодействие с C++
- COM-классы и классы C++
- ошибки подтверждения направляются в библиотеку времени выполнения C
- переключатель с помощью струн
- окончательный переключатель
- юниттеста блоки
- printf проверка формата
Функции, исключенные из Better C [ править ]
- Вывоз мусора
- Информация о типе и информация о модуле
- Встроенная резьба (например,
core.thread
) - Динамические массивы (хотя части статических массивов работают) и ассоциативные массивы
- Исключения
- синхронизированы и
core.sync
- Конструкторы или деструкторы статических модулей
История [ править ]
Уолтер Брайт начал работу над новым языком в 1999 году. Впервые D был выпущен в декабре 2001 года. [1] и достиг версии 1.0 в январе 2007 года. [31] Первая версия языка (D1) была сосредоточена на императивной, объектно-ориентированной и метапрограммной парадигмах. [32] похож на С++.
Некоторые члены сообщества D, недовольные Phobos, официальной средой выполнения и стандартной библиотекой D , создали альтернативную среду выполнения и стандартную библиотеку под названием Tango. Первое публичное объявление о Tango произошло через несколько дней после выпуска D 1.0. [33] Tango принял другой стиль программирования, включающий ООП и высокую модульность. Будучи проектом под руководством сообщества, Tango был более открыт для вкладов, что позволяло ему развиваться быстрее, чем официальная стандартная библиотека. В то время Tango и Phobos были несовместимы из-за разных API-интерфейсов поддержки времени выполнения (сборщик мусора, поддержка потоков и т. д.). Это сделало невозможным использование обеих библиотек в одном проекте. Существование двух библиотек, обе широко используемых, привело к серьезным спорам из-за того, что некоторые пакеты используют Phobos, а другие - Tango. [34]
В июне 2007 года была выпущена первая версия D2. [35] Начало развития D2 ознаменовало стабилизацию D1. Первая версия языка была помещена на обслуживание, в нее вносились только исправления и исправления ошибок реализации. D2 внесла критические изменения в язык , начиная со своей первой экспериментальной системы const . Позже в D2 были добавлены многочисленные другие функции языка, такие как замыкания , чистота и поддержка парадигм функционального и параллельного программирования. D2 также решил проблемы стандартной библиотеки, отделив среду выполнения от стандартной библиотеки. О завершении порта D2 Tango было объявлено в феврале 2012 года. [36]
Выпуск Андрея Александреску книги «Язык программирования D» 12 июня 2010 года ознаменовал стабилизацию языка D2, который сегодня обычно называют просто «D».
В январе 2011 года разработка D перешла с системы отслеживания ошибок/отправки исправлений на GitHub . Это привело к значительному увеличению вклада в компилятор, среду выполнения и стандартную библиотеку. [37]
В декабре 2011 года Андрей Александреску объявил, что поддержка D1, первой версии языка, будет прекращена 31 декабря 2012 года. [38] Последний выпуск D1, D v1.076, вышел 31 декабря 2012 года. [39]
Код официального компилятора D, компилятора Digital Mars D Уолтера Брайта, изначально был выпущен под специальной лицензией , квалифицируясь как доступный исходный код , но не соответствующий определению открытого исходного кода . [40] компилятора В 2014 году интерфейс был повторно лицензирован как открытый исходный код по лицензии Boost Software License . [3] Этот повторно лицензированный код исключил серверную часть, которая была частично разработана в Symantec . 7 апреля 2017 года весь компилятор стал доступен по лицензии Boost после того, как Symantec разрешила также повторно лицензировать серверную часть. [4] [41] [42] [43] 21 июня 2017 года язык D был принят для включения в GCC. [44]
Реализации [ править ]
Большинство современных реализаций D компилируются непосредственно в машинный код .
Готовые к производству компиляторы:
- DMD - Компилятор Digital Mars D Уолтера Брайта является официальным компилятором D; с открытым исходным кодом под лицензией Boost Software License . [3] [4] Интерфейс DMD используется GDC (теперь в GCC) и LDC, чтобы улучшить совместимость между компиляторами. Изначально интерфейс был написан на C++, но сейчас большая его часть написана на самом D (самостоятельный хостинг). Оптимизаторы серверной части и машинного кода основаны на компиляторе Symantec. Сначала он поддерживал только 32-битную версию x86, а Уолтер Брайт добавил поддержку 64-битной версии AMD64 и PowerPC. Позже бэкэнд и почти весь компилятор были перенесены с C++ на D для полного самостоятельного размещения.
- GCC — Коллекция компиляторов GNU , объединенная с GDC. [45] в GCC 9 29 октября 2018 г. [46] Первые рабочие версии GDC с GCC на базе GCC 3.3 и GCC 3.4 на 32-битной версии x86 для Linux и macOS. [47] был выпущен 22 марта 2004 года. С тех пор GDC получил поддержку дополнительных платформ, улучшенную производительность и исправленные ошибки, одновременно отслеживая исходный код DMD для интерфейса и спецификации языка. [48]
- LDC — компилятор, основанный на интерфейсе DMD, который использует LLVM в качестве серверной части компилятора. Первая версия релизного качества была опубликована 9 января 2009 года. [49] Он поддерживает версию 2.0. [50]
Игрушечные и экспериментальные компиляторы:
- D Compiler for .NET — серверная часть для компилятора языка программирования D 2.0. [51] [52] Он компилирует код в байт-код Common Intermediate Language (CIL), а не в машинный код. Затем CIL можно запустить через Common Language Infrastructure (CLI) виртуальную машину . Проект не обновлялся годами, и автор указал, что проект больше не активен.
- SDC – шикарный компилятор D [53] использует собственный интерфейс и LLVM в качестве серверной части компилятора. Он написан на D и использует планировщик для обработки разрешения символов, чтобы элегантно обрабатывать функции D во время компиляции. В настоящее время этот компилятор поддерживает ограниченное подмножество языка. [54] [55]
Используя вышеуказанные компиляторы и наборы инструментов, можно скомпилировать программы 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, [56] и Гиани среди других. [57]
- Dexed (ранее совместное редактирование), [58] графическая среда разработки, ориентированная на D, написанная на Object Pascal.
- Моно-Д [59] — это многофункциональная кроссплатформенная графическая среда разработки, ориентированная на D, основанная на MonoDevelop /Xamarin Studio, написанная в основном на C Sharp. [60]
- Eclipse для D включают DDT Плагины [61] и Descent (мертвый проект). [62]
- Интеграция Visual Studio обеспечивается VisualD. [63] [64]
- Интеграция кода Visual Studio с расширениями, такими как Dlang-Vscode. [65] или Код-D. [66]
- доступен пакет Для TextMate , а IDE Code::Blocks включает частичную поддержку этого языка. Однако стандартные функции IDE, такие как завершение кода или рефакторинг, пока недоступны, хотя они частично работают в Code::Blocks (из-за сходства D с C).
- Плагин Xcode 3 «D for Xcode» позволяет создавать проекты и разработку на основе D. [67]
- KDevelop (а также его текстовый редактор Kate). Доступен плагин автозаполнения [68]
Существуют IDE D с открытым исходным кодом для Windows , некоторые из них написаны на D, например Poseidon, [69] Д-IDE, [70] и Entice Designer. [71]
Приложения 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, полезный при обнаружении проблем с компилятором или тестированием. [72]
dub — популярный менеджер пакетов и сборки для приложений и библиотек D, который часто интегрируется в поддержку IDE. [73]
Примеры [ править ]
Возможно, этот раздел содержит оригинальные исследования . ( сентябрь 2020 г. ) |
Пример 1 [ править ]
Этот пример программы печатает аргументы командной строки. main
функция является точкой входа в программу D, и args
представляет собой массив строк, представляющих аргументы командной строки. А string
в D — это массив символов, представленный immutable(char)[]
.
импорт стандартный . stdio : writefln ;
void main ( string [] args ) {
foreach ( i , arg ; args )
writefln ( «args[%d] = '%s'» , i , arg );
}
The foreach
оператор может перебирать любую коллекцию. В этом случае он создает последовательность индексов ( i
) и ценности ( arg
) из массива args
. Индекс i
и ценность arg
их типы выводятся из типа массива args
.
Пример 2 [ править ]
Ниже показаны некоторые возможности D и компромиссы при проектировании D в короткой программе. Он перебирает строки текстового файла с именем words.txt
, который содержит разные слова в каждой строке и печатает все слова, являющиеся анаграммами других слов.
импорт стандартный . стдио , станд . алгоритм , стандарт . диапазон , стандарт . нить ;
void main () {
dstring [] [ dstring ] Signature2words ;
foreach ( dchar [] w ; линии ( Файл ( "words.txt" ))) {
w = w . чавкать (). понижать ();
неизменяемая подпись = w . дуп . Сортировать (). выпускать (). идентификатор ;
подпись2слова [ подпись ] ~= w . идентификатор ;
}
foreach ( words ; Signature2words ) {
if ( words . length > 1 ) {
writeln ( words . join ( " " ));
}
}
}
signature2words
— это встроенный ассоциативный массив, который сопоставляет ключи dstring (32-битные / символьные) с массивами dstrings. Это похоже наdefaultdict(list)
в Питоне .lines(File())
выдает строки лениво, с переводом строки. Затем его необходимо скопировать с помощьюidup
чтобы получить строку, которая будет использоваться для значений ассоциативного массива (теперьidup
свойство arrays возвращает неизменяемый дубликат массива, который необходим, посколькуdstring
тип на самом делеimmutable(dchar)[]
). Встроенные ассоциативные массивы требуют неизменяемых ключей.- The
~=
Оператор добавляет новую строку значений к значениям связанного динамического массива. toLower
,join
иchomp
представляют собой строковые функции, которые D позволяет использовать с синтаксисом метода. Имена таких функций часто похожи на строковые методы Python.toLower
преобразует строку в нижний регистр,join(" ")
объединяет массив строк в одну строку, используя один пробел в качестве разделителя, иchomp
удаляет новую строку из конца строки, если она присутствует.w.dup.sort().release().idup
более читабелен, но эквивалентенrelease(sort(w.dup)).idup
например. Эта функция называется UFCS (унифицированный синтаксис вызова функций) и позволяет расширять любые встроенные или сторонние типы пакетов функциональностью, подобной методу. Подобный стиль написания кода часто называют конвейерным (особенно когда используемые объекты лениво вычисляются, например итераторы/диапазоны) или интерфейсом Fluent .- The
sort
— это функция std.algorithm, которая сортирует массив на месте, создавая уникальную подпись для слов, которые являются анаграммами друг друга.release()
метод для возвращаемого значенияsort()
удобно хранить код в виде одного выражения. - Второй
foreach
перебирает значения ассоциативного массива, он может определить типwords
. signature
присваивается неизменяемой переменной, выводится ее тип.- UTF-32
dchar[]
используется вместо обычного UTF-8char[]
в противном случаеsort()
отказывается сортировать. Есть более эффективные способы написать эту программу, используя только UTF-8.
Использует [ править ]
Известные организации, использующие язык программирования D для проектов, включают Facebook , [74] eBay , [75] и Нетфликс . [76]
D успешно использовался для ААА-игр , [77] языковые переводчики, виртуальные машины, [78] [79] ядро операционной системы , [80] графического процессора , программирование [81] Веб-разработка , [82] [83] численный анализ , [84] приложения с графическим интерфейсом , [85] [86] пассажиров информационная система для , [87] машинное обучение, [88] обработка текста, веб-серверы и серверы приложений, а также исследования.
Пресловутая северокорейская хакерская группа, известная как Lazarus, использовала CVE-2021-44228, также известную как « Log4Shell », для развертывания трех семейств вредоносных программ , написанных на DLang. [89]
Обзор [ править ]
Отсутствие прозрачности, гибкости и предсказуемости в процессе внесения исправлений известных недостатков и ошибок, а также сложность внесения мелких и крупных изменений в язык D, немедленно описываются в статье в блоге. [90] от бывшего участника. Описанное там явное разочарование привело к OpenD. форку [91] 1 января 2024 года.
См. также [ править ]
Ссылки [ править ]
- ^ Перейти обратно: а б «Журнал изменений D на 7 ноября 2005 г.» . D Язык программирования 1.0 . Цифровой Марс . Проверено 1 декабря 2011 г.
- ^ «2.108.0» . Проверено 2 апреля 2024 г.
- ^ Перейти обратно: а б с «Внешний интерфейс dmd теперь переключен на лицензию Boost» . Проверено 9 сентября 2014 г.
- ^ Перейти обратно: а б с «dmd Backend преобразован в Boost License» . 7 апреля 2017 года . Проверено 9 апреля 2017 г.
- ^ «Часто задаваемые вопросы по D 2.0» . Проверено 11 августа 2015 г.
- ^ «Язык программирования D — Fileinfo.com» . Проверено 15 ноября 2020 г. [ нужна цитата ]
- ^ «Язык программирования D — dlang.org» . Проверено 15 ноября 2020 г. [ нужна цитата ]
- ^ «Включено: Показать HN: хороший API строк C» . Хакерские новости . 3 декабря 2022 г. Проверено 4 декабря 2022 г.
- ^ Александреску, Андрей (2010). Язык программирования D (Первое изд.). Река Аппер-Сэддл, Нью-Джерси: Аддисон-Уэсли. п. 314 . ISBN 978-0321635365 .
- ^ «Создание Assert() в Swift, часть 2: __FILE__ и __LINE__» . Проверено 25 сентября 2014 г.
- ^ «Введение — язык программирования D» . dlang.org . Проверено 21 апреля 2024 г. В эту статью включен текст из этого бесплатного контента . Лицензировано в соответствии с BSL-1.0 ( заявление о лицензии/разрешение ).
- ^ «D-строки против строк C++» . Цифровой Марс. 2012.
- ^ «Сложные типы D и C++ std::complex» . Цифровой Марс . 2012. Архивировано из оригинала 13 января 2008 года . Проверено 4 ноября 2021 г.
- ^ «Выражения» . Цифровой Марс . Проверено 27 декабря 2012 г.
- ^ "std.gc" . D Язык программирования 1.0 . Цифровой Марс . Проверено 6 июля 2010 г.
- ^ "Управление памятью" . D Язык программирования 2.0 . Цифровой Марс . Проверено 17 февраля 2012 г.
- ^ Перейти обратно: а б «Иди своим путем (Часть первая: Стек)» . Блог D. 7 июля 2017 года . Проверено 7 мая 2020 г.
- ^ «Атрибуты — язык программирования D» . dlang.org . Проверено 7 мая 2020 г.
- ^ «std.experimental.allocator — язык программирования D» . dlang.org . Проверено 7 мая 2020 г.
- ^ Бартош Милевский. «Язык программирования SafeD-D» . Проверено 17 июля 2014 г.
- ^ Стивен Швейгхоффер (28 сентября 2016 г.). «Как написать @trusted-код на D» . Проверено 4 января 2018 г.
- ^ «Указатели с прицелом» . Гитхаб . 3 апреля 2020 г.
- ^ «Закрытые ссылки» .
- ^ «Спецификация языка D: Функции — возвращаемые параметры области видимости» .
- ^ «Собственность и заимствование в D» . 15 июля 2019 г.
- ^ «Спецификация языка D: Функции — Классы хранения параметров функций» .
- ^ «ПиД» . Гитхаб . 7 мая 2020 г. Проверено 7 мая 2020 г.
- ^ Паркер, Майк. «Пакет заброшенного-lua в DUB» . Реестр пакетов DUB . Проверено 7 мая 2020 г.
- ^ Паркер, Майк. «Пакетbindbc-lua в DUB» . Реестр пакетов DUB . Проверено 7 мая 2020 г.
- ^ «Лучше С» .
- ^ «Журнал изменений D» . D Язык программирования 1.0 . Цифровой Марс . Проверено 11 января 2012 г.
- ^ "Вступление" . D Язык программирования 1.0 . Цифровой Марс . Проверено 1 декабря 2011 г.
- ^ «Анонсируем новую библиотеку» . Проверено 15 февраля 2012 г.
- ^ «Wiki4D: Стандартная библиотека» . Проверено 6 июля 2010 г.
- ^ «Журнал изменений – язык программирования D» . D Язык программирования 2.0 . Языковой фонд D. Проверено 22 ноября 2020 г.
- ^ «Танго для D2: Портированы все пользовательские модули» . Проверено 16 февраля 2012 г.
- ^ Уолтер Брайт. «Re: GitHub или dsource?» . Проверено 15 февраля 2012 г.
- ^ Андрей Александреску. «Выпуск D1 будет прекращен 31 декабря 2012 г.» . Проверено 31 января 2014 г.
- ^ «Журнал изменений D» . D Язык программирования 1.0 . Цифровой Марс . Проверено 31 января 2014 г.
- ^ "backendlicense.txt" . Исходный код DMD . Гитхаб. Архивировано из оригинала 22 октября 2016 года . Проверено 5 марта 2012 г.
- ^ «Комментарий Уолтера Брайта на Reddit» . 5 марта 2009 года . Проверено 9 сентября 2014 г.
- ^ D-Компилятор под свободной лицензией на linux-magazin.de (2017, на немецком языке)
- ^ переключите серверную часть на лицензию Boost № 6680 от Уолтера Брайта на github.com.
- ^ D Язык принят для включения в GCC
- ^ «ГДК» .
- ^ «Серия выпусков GCC 9 — Изменения, новые функции и исправления — Проект GNU — Фонд свободного программного обеспечения (FSF)» . gcc.gnu.org . Проверено 7 мая 2020 г.
- ^ «Еще один интерфейс для GCC» . forum.dlang.org . Проверено 7 мая 2020 г.
- ^ «Изменения, новые функции и исправления серии выпусков GCC 9» .
- ^ «Проект компилятора LLVM D на GitHub» . Гитхаб . Проверено 19 августа 2016 г.
- ^ «BuildInstructionsPhobosDruntimeTrunk – ldc – Язык программирования D – Trac» . Проверено 11 августа 2015 г.
- ^ «Проект D .NET на CodePlex» . Архивировано из оригинала 26 января 2018 года . Проверено 3 июля 2010 г.
- ^ Джонатан Аллен (15 мая 2009 г.). «Исходный код компилятора D.NET теперь доступен» . ИнфоQ . Проверено 6 июля 2010 г.
- ^ «Сделайте SDC компилятором Snazzy D» . Гитхаб . Проверено 24 сентября 2023 г.
- ^ DConf 2014: SDC, D-компилятор как библиотека Амори Сеше . YouTube . Проверено 8 января 2014 г. Архивировано в Ghostarchive и Wayback Machine.
- ^ "дедалникс/SDC " Гитхаб . Получено 8 января.
- ^ «Wiki4D: EditorSupport/ZeusForWindows» . Проверено 11 августа 2015 г.
- ^ «Wiki4D: Поддержка редактора» . Проверено 3 июля 2010 г.
- ^ «Базиль.Б/дексед» . ГитЛаб . Проверено 29 апреля 2020 г.
- ^ «Моно-Д-Д Вики» . wiki.dlang.org . Проверено 30 апреля 2020 г.
- ^ «Поддержка Mono-D – D для MonoDevelop» . Архивировано из оригинала 1 февраля 2012 года . Проверено 11 августа 2015 г.
- ^ «Хостинг проектов Google» . Проверено 11 августа 2015 г.
- ^ "спуск" . Проверено 11 августа 2015 г.
- ^ «Визуальный язык программирования D-D» . Проверено 11 августа 2015 г.
- ^ Шютце, Райнер (17 апреля 2020 г.). «rainers/visuald: Visual D — расширение Visual Studio для языка программирования D» . github.com . Проверено 30 апреля 2020 г.
- ^ "дланг-vscode" . Гитхаб . Проверено 21 декабря 2016 г.
- ^ «код-d» . Гитхаб . Проверено 21 декабря 2016 г.
- ^ «Мишель Фортен – D для Xcode» . Проверено 11 августа 2015 г.
- ^ «Дав1дде/люмен» . Гитхаб . Проверено 11 августа 2015 г.
- ^ «Посейдон» . Проверено 11 августа 2015 г.
- ^ «Поддержка Mono-D – D для MonoDevelop» . Проверено 11 августа 2015 г.
- ^ «Entice Designer – Dprogramming.com – Язык программирования D» . Проверено 11 августа 2015 г.
- ^ «Что такое DustMite?» . Гитхаб . Проверено 29 апреля 2020 г.
- ^ "dlang/dub: Система управления пакетами и сборками для D" . Гитхаб . Проверено 29 апреля 2020 г.
- ^ «Под капотом: warp, быстрый препроцессор C и C++» . 28 марта 2014 года . Проверено 4 января 2018 г.
- ^ «Быстрые инструменты командной строки в D» . 24 мая 2017 года . Проверено 4 января 2018 г.
- ^ «Знакомство с векторным потоком» . 2 августа 2017 г. Проверено 4 января 2018 г.
- ^ «Квантовый прорыв: ААА-игры с некоторым кодом D» . Проверено 4 января 2018 г.
- ^ «Виртуальная машина Хиггса JavaScript» . Гитхаб . Проверено 4 января 2018 г.
- ^ «AD-реализация языка программирования ECMA 262 (Javascript)» . Гитхаб . Проверено 4 января 2018 г.
- ^ «Изюминка проекта: ядро PowerNex» . 24 июня 2016 года . Проверено 4 января 2018 г.
- ^ «DCompute: запуск D на графическом процессоре» . 30 октября 2017 г. Проверено 4 января 2018 г.
- ^ «vibe.d — высокопроизводительный набор инструментов для асинхронного ввода-вывода, параллелизма и веб-приложений, написанный на D» . Проверено 4 января 2018 г.
- ^ «Основной проект: Diamond MVC Framework» . 20 ноября 2017 года . Проверено 4 января 2018 г.
- ^ «Числовой возраст D: Mir GLAS быстрее, чем OpenBLAS и Eigen» . Проверено 4 января 2018 г.
- ^ «О Тиликсе и D: Интервью с Джеральдом Нанном» . 11 августа 2017 года . Проверено 4 января 2018 г.
- ^ «Изюминка проекта: DlangUI» . 7 октября 2016 г. Проверено 4 января 2018 г.
- ^ «Изюминка проекта: Фанкверк» . 28 июля 2017 года . Проверено 4 января 2018 г.
- ^ «Нетфликс/векторный поток» . GitHub.com . Netflix, Inc. 5 мая 2020 г. . Проверено 7 мая 2020 г.
- ^ «Хакеры Lazarus распространяют новое вредоносное ПО RAT, используя ошибку Log4j двухлетней давности» . 11 декабря 2023 г. Проверено 11 декабря 2023 г.
- ^ «Отплыл корабль с серебром» . Проверено 6 мая 2024 г.
- ^ «Язык программирования OpenD» . Проверено 14 мая 2024 г.
Дальнейшее чтение [ править ]
- Александреску, Андрей (4 января 2010 г.). Язык программирования D (1-е изд.). Аддисон-Уэсли Профессионал. ISBN 978-0-321-63536-5 .
- Александреску, Андрей (15 июня 2009 г.). «Дело Д» . Журнал доктора Добба.
- Брайт, Уолтер (8 апреля 2014 г.). «Как я пришел к написанию D» . Журнал доктора Добба.
- Чехрели, Али (1 февраля 2012 г.). «Программирование на D» . (распространяется по лицензии CC-BY-NC-SA). Эта книга обучает программированию новичков, но также охватывает многие сложные темы D.
- Мец, Кейд (7 июля 2014 г.). «Следующий большой язык программирования, о котором вы никогда не слышали» . Проводной .
- Руппе, Адам (май 2014 г.). D Поваренная книга (1-е изд.). ПАКТ Издательство. ISBN 978-1-783-28721-5 .
Внешние ссылки [ править ]
- Языки программирования
- Семейство языков программирования C
- Языки программирования на основе классов
- Кроссплатформенное программное обеспечение
- Бесплатные компиляторы и интерпретаторы
- Языки программирования высокого уровня
- Мультипарадигмальные языки программирования
- Объектно-ориентированные языки программирования
- Процедурные языки программирования
- Языки программирования, созданные в 2001 году.
- Статически типизированные языки программирования
- Языки системного программирования
- программное обеспечение 2001 года
- Программное обеспечение, использующее лицензию Boost