D (язык программирования)
Эта статья содержит контент, написанный как реклама . ( январь 2024 г. ) |
Парадигма | Мультипарадигмальность : функциональная , императивная , объектно-ориентированная. |
---|---|
Разработано | Уолтер Брайт , Андрей Александреску (с 2007 г.) |
Разработчик | Языковой фонд D |
Впервые появился | 8 декабря 2001 г [1] |
Стабильная версия | 2.109.1 [2]
/ 1 июля 2024 г |
Дисциплина набора текста | Предполагаемый , статичный , сильный |
ТЫ | FreeBSD , Linux , MacOS , Windows |
Лицензия | Способствовать росту [3] [4] [5] |
Расширения имен файлов | .д [6] [7] |
Веб-сайт | дланг |
Основные реализации | |
DMD ( эталонная реализация ), GCC ,
ГДК , НРС , СЗК | |
Под влиянием | |
БАЗОВЫЙ , [8] C , C++ , C# , Эйфель , [9] Ява , Питон | |
Под влиянием | |
Джинн , МиниД, Коре , Свифт , [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
конструкция цикла, позволяющая выполнять цикл по коллекции, и вложенные функции , которые объявляются внутри других функций и могут обращаться к локальным переменным включающей функции .
import std.stdio;
void main() {
int multiplier = 10;
int scaled(int x) { return x * multiplier; }
foreach (i; 0 .. 10) {
writefln("Hello, world %d! scaled = %d", i, scaled(i));
}
}
Объектно-ориентированный
[ редактировать ]Объектно-ориентированное программирование в D основано на единой иерархии наследования, все классы которой являются производными от класса Object. D не поддерживает множественное наследование; в стиле Java вместо этого он использует интерфейсы , которые сравнимы с чистыми абстрактными классами C++, и миксины , которые отделяют общую функциональность от иерархии наследования. D также позволяет определять статические и финальные (не виртуальные) методы в интерфейсах.
Интерфейсы и наследование в D поддерживают ковариантные типы для возвращаемых типов переопределенных методов.
D поддерживает пересылку типов, а также дополнительную пользовательскую динамическую отправку .
Классы (и интерфейсы) в D могут содержать инварианты , которые автоматически проверяются до и после доступа к общедоступным методам в соответствии с методологией проектирования по контракту .
Многие аспекты классов (и структур) могут автоматически анализироваться во время компиляции (форма отражения с использованием type traits
) и во время выполнения (RTTI/ TypeInfo
), чтобы облегчить общий код или автоматическую генерацию кода (обычно с использованием методов времени компиляции).
Функциональный
[ редактировать ]D поддерживает такие функции функционального программирования, как функциональные литералы , замыкания , рекурсивно-неизменяемые объекты и использование функций высшего порядка . Существует два синтаксиса анонимных функций, включая форму с несколькими операторами и «сокращенную» нотацию с одним выражением: [14]
int function(int) g;
g = (x) { return x * x; }; // longhand
g = (x) => x * x; // shorthand
Существует два встроенных типа функциональных литералов: function
, который является просто указателем на функцию, выделенную в стеке, и delegate
, который также включает указатель на соответствующий кадр стека , окружающую «среду», содержащую текущие локальные переменные. Вывод типа может использоваться с анонимной функцией, и в этом случае компилятор создает delegate
если только он не сможет доказать, что указатель среды не нужен. Аналогично, чтобы реализовать замыкание, компилятор помещает вложенные локальные переменные в кучу только в случае необходимости (например, если замыкание возвращается другой функцией и выходит из области действия этой функции). При использовании вывода типа компилятор также добавит такие атрибуты, как pure
и nothrow
к типу функции, если можно доказать их применимость.
Другие функциональные возможности, такие как каррирование и общие функции высшего порядка, такие как карта , фильтр и сокращение, доступны через модули стандартной библиотеки. std.functional
и std.algorithm
.
import std.stdio, std.algorithm, std.range;
void main()
{
int[] a1 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
int[] a2 = [6, 7, 8, 9];
// must be immutable to allow access from inside a pure function
immutable pivot = 5;
int mySum(int a, int b) pure nothrow // pure function
{
if (b <= pivot) // ref to enclosing-scope
return a + b;
else
return a;
}
// passing a delegate (closure)
auto result = reduce!mySum(chain(a1, a2));
writeln("Result: ", result); // Result: 15
// passing a delegate literal
result = reduce!((a, b) => (b <= pivot) ? a + b : a)(chain(a1, a2));
writeln("Result: ", result); // Result: 15
}
Альтернативно, приведенные выше композиции функций могут быть выражены с использованием унифицированного синтаксиса вызова функций (UFCS) для более естественного чтения слева направо:
auto result = a1.chain(a2).reduce!mySum();
writeln("Result: ", result);
result = a1.chain(a2).reduce!((a, b) => (b <= pivot) ? a + b : a)();
writeln("Result: ", result);
Параллелизм
[ редактировать ]Концепции параллельного программирования реализованы в библиотеке и не требуют дополнительной поддержки со стороны компилятора. Однако система и компилятор типа D гарантируют, что совместное использование данных может быть обнаружено и прозрачно управляемо.
import std.stdio : writeln;
import std.range : iota;
import std.parallelism : parallel;
void main()
{
foreach (i; iota(11).parallel) {
// The body of the foreach loop is executed in parallel for each i
writeln("processing ", i);
}
}
iota(11).parallel
эквивалентно std.parallelism.parallel(iota(11))
с помощью UFCS.
Этот же модуль также поддерживает taskPool
который можно использовать для динамического создания параллельных задач, а также операций отображения-фильтрации-уменьшения и свертывания стилей над диапазонами (и массивами), что полезно в сочетании с функциональными операциями. std.algorithm.map
возвращает лениво вычисляемый диапазон, а не массив. Таким образом, элементы автоматически вычисляются каждой рабочей задачей параллельно.
import std.stdio : writeln;
import std.algorithm : map;
import std.range : iota;
import std.parallelism : taskPool;
/* On Intel i7-3930X and gdc 9.3.0:
* 5140ms using std.algorithm.reduce
* 888ms using std.parallelism.taskPool.reduce
*
* On AMD Threadripper 2950X, and gdc 9.3.0:
* 2864ms using std.algorithm.reduce
* 95ms using std.parallelism.taskPool.reduce
*/
void main()
{
auto nums = iota(1.0, 1_000_000_000.0);
auto x = taskPool.reduce!"a + b"(
0.0, map!"1.0 / (a * a)"(nums)
);
writeln("Sum: ", x);
}
Параллелизм
[ редактировать ]Параллелизм полностью реализован в библиотеке и не требует поддержки со стороны компилятора. Возможны альтернативные реализации и методологии написания параллельного кода. Использование системы типизации D действительно помогает обеспечить безопасность памяти.
import std.stdio, std.concurrency, std.variant;
void foo()
{
bool cont = true;
while (cont)
{
receive( // Delegates are used to match the message type.
(int msg) => writeln("int received: ", msg),
(Tid sender) { cont = false; sender.send(-1); },
(Variant v) => writeln("huh?") // Variant matches any type
);
}
}
void main()
{
auto tid = spawn(&foo); // spawn a new thread running foo()
foreach (i; 0 .. 10)
tid.send(i); // send some integers
tid.send(1.0f); // send a float
tid.send("hello"); // send a string
tid.send(thisTid); // send a struct (Tid)
receive((int x) => writeln("Main thread received message: ", x));
}
Metaprogramming
[ редактировать ]Метапрограммирование поддерживается посредством шаблонов, выполнения функций во время компиляции, кортежей и строковых миксинов. Следующие примеры демонстрируют некоторые возможности D во время компиляции.
Шаблоны в D могут быть написаны в более императивном стиле по сравнению с функциональным стилем шаблонов C++. Это обычная функция, которая вычисляет факториал числа:
ulong factorial(ulong n) {
if (n < 2)
return 1;
else
return n * factorial(n-1);
}
Здесь использование static if
, условная конструкция D во время компиляции, демонстрируется для создания шаблона, который выполняет те же вычисления с использованием кода, аналогичного коду функции выше:
template Factorial(ulong n) {
static if (n < 2)
enum Factorial = 1;
else
enum Factorial = n * Factorial!(n-1);
}
В следующих двух примерах шаблон и функция, определенные выше, используются для вычисления факториалов. Типы констант не обязательно указывать явно, поскольку компилятор определяет их типы из правых частей присваивания:
enum fact_7 = Factorial!(7);
Это пример выполнения функции во время компиляции (CTFE). Обычные функции могут использоваться в константных выражениях времени компиляции при условии, что они соответствуют определенным критериям:
enum fact_9 = factorial(9);
The std.string.format
функция выполняет printf
-подобное форматированию данных (также во время компиляции, через CTFE), а прагма «msg» отображает результат во время компиляции:
import std.string : format;
pragma(msg, format("7! = %s", fact_7));
pragma(msg, format("9! = %s", fact_9));
Строковые миксины в сочетании с выполнением функций во время компиляции позволяют генерировать D-код с использованием строковых операций во время компиляции. Это можно использовать для анализа предметно-ориентированных языков , которые будут скомпилированы как часть программы:
import FooToD; // hypothetical module which contains a function that parses Foo source code
// and returns equivalent D code
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* rad; // #2
rad = &tmp; // If the order of the declarations of #1 and #2 is reversed, this fails.
{
int bad = 45; // The lifetime of "bad" only extends to the scope in which it is defined.
*rad = bad; // This is valid.
rad = &bad; // The lifetime of rad is longer than bad, hence this is not valid.
}
}
Аннотации времени жизни параметров функции в коде @safe
[ редактировать ]При применении к параметру функции, который имеет тип указателя или ссылку, ключевые слова return и область действия ограничивают время существования и использование этого параметра.
Стандарт языка диктует следующее поведение: [26]
Класс хранилища | Поведение (и ограничения) параметра с классом хранения |
---|---|
объем | Ссылки в параметре не могут быть экранированы. Игнорируется для параметров без ссылок |
возвращаться | Параметр может быть возвращен или скопирован в первый параметр, но в противном случае он не выходит из функции. Такие копии должны не пережить аргумент(ы), из которых они были получены. Игнорируется для параметров без ссылок |
Аннотированный пример приведен ниже.
@safe:
int* gp;
void thorin(scope int*);
void gloin(int*);
int* balin(return scope int* p, scope int* q, int* r)
{
gp = p; // Error, p escapes to global variable gp.
gp = q; // Error, q escapes to global variable gp.
gp = r; // OK.
thorin(p); // OK, p does not escape thorin().
thorin(q); // OK.
thorin(r); // OK.
gloin(p); // Error, p escapes gloin().
gloin(q); // Error, q escapes gloin().
gloin(r); // OK that r escapes gloin().
return p; // OK.
return q; // Error, cannot return 'scope' q.
return r; // OK.
}
Взаимодействие с другими системами
[ редактировать ]библиотекам и C. Поддерживается двоичный интерфейс приложений C (ABI), а также все фундаментальные и производные типы 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 , [27] Два [28] [29] и других языках, часто использующих генерацию кода во время компиляции и методы отражения типов во время компиляции.
Взаимодействие с кодом C++
[ редактировать ]Для кода D, отмеченного как extern(C++)
, указаны следующие особенности:
- Соглашения об изменении имен должны соответствовать соглашениям C++ в целевой системе.
- Для вызовов функций ABI должен быть эквивалентным.
- Виртуальная таблица должна соответствовать одиночному наследованию (единственному уровню, поддерживаемому спецификацией языка D).
Пространства имен C++ используются через синтаксис extern(C++, namespace)
где пространство имен — это имя пространства имен C++.
Пример взаимодействия C++
[ редактировать ]Сторона C++
#include <iostream>
using namespace std;
class Base
{
public:
virtual void print3i(int a, int b, int c) = 0;
};
class Derived : 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 factor);
};
int Derived::mul(int factor)
{
return field * factor;
}
Derived *createInstance(int i)
{
return new Derived(i);
}
void deleteInstance(Derived *&d)
{
delete d;
d = 0;
}
Сторона D
extern(C++)
{
abstract class Base
{
void print3i(int a, int b, int c);
}
class Derived : Base
{
int field;
@disable this();
override void print3i(int a, int b, int c);
final int mul(int factor);
}
Derived createInstance(int i);
void deleteInstance(ref Derived d);
}
void main()
{
import std.stdio;
auto d1 = createInstance(5);
writeln(d1.field);
writeln(d1.mul(4));
Base b1 = d1;
b1.print3i(1, 2, 3);
deleteInstance(d1);
assert(d1 is null);
auto d2 = createInstance(42);
writeln(d2.field);
deleteInstance(d2);
assert(d2 is null);
}
Лучше С
[ редактировать ]Язык программирования D имеет официальное подмножество, известное как Better C. [30] Это подмножество запрещает доступ к функциям D, требующим использования библиотек времени выполнения, отличных от библиотеки C.
Включенный с помощью флагов компилятора «-betterC» в DMD и LDC и «-fno-druntime» в GDC, Better C может вызывать только код D, скомпилированный под тем же флагом (и связанный код, отличный от D), но код, скомпилированный без Лучшая опция 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)[]
.
import std.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
, который содержит разные слова в каждой строке и печатает все слова, являющиеся анаграммами других слов.
import std.stdio, std.algorithm, std.range, std.string;
void main() {
dstring[] [dstring] signature2words;
foreach (dchar[] w; lines(File("words.txt"))) {
w = w.chomp().toLower();
immutable signature = w.dup.sort().release().idup;
signature2words[signature] ~= w.idup;
}
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 года.
См. также
[ редактировать ]Ссылки
[ редактировать ]- ^ Jump up to: а б «Журнал изменений D на 7 ноября 2005 г.» . D Язык программирования 1.0 . Цифровой Марс . Проверено 1 декабря 2011 г.
- ^ «2.109.1» . Проверено 7 июля 2024 г.
- ^ Jump up to: а б с «Внешний интерфейс dmd теперь переключен на лицензию Boost» . Проверено 9 сентября 2014 г.
- ^ Jump up to: а б с «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 г.
- ^ Jump up to: а б «Иди своим путем (Часть первая: Стек)» . Блог 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-компилятор как библиотека Амори Сеше . Ютуб . Проверено 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