Jump to content

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

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

язык программирования D
Парадигма Мультипарадигмальность : функциональная , императивная , объектно-ориентированная.
Разработано Уолтер Брайт , Андрей Александреску (с 2007 г.)
Разработчик Языковой фонд D
Впервые появился 8 декабря 2001 г .; 22 года назад ( 08.12.2001 ) [1]
Стабильная версия
2.109.1 [2]  Отредактируйте это в Викиданных / 1 июля 2024 г .; 32 дня назад ( 1 июля 2024 г. )
Дисциплина набора текста Предполагаемый , статичный , сильный
ТЫ FreeBSD , Linux , MacOS , Windows
Лицензия Способствовать росту [3] [4] [5]
Расширения имен файлов [6] [7]
Веб-сайт дланг .org
Основные реализации
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]

с открытым исходным кодом Существуют 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]

Этот пример программы печатает аргументы командной строки. 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.

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

См. также

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

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

[ редактировать ]
[ редактировать ]
Arc.Ask3.Ru: конец переведенного документа.
Arc.Ask3.Ru
Номер скриншота №: 0b5e047a49fe044c2c81d400cd1974c5__1721757420
URL1:https://arc.ask3.ru/arc/aa/0b/c5/0b5e047a49fe044c2c81d400cd1974c5.html
Заголовок, (Title) документа по адресу, URL1:
D (programming language) - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть. Любые претензии, иски не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, вы не можете использовать данный сайт и информация размещенную на нем (сайте/странице), немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, Денежную единицу (имеющую самостоятельную стоимость) можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)