Готовый перевод "D"iving Into the D Programming Language / Погружение в язык Ди: 1.4.1 Building a Vocabulary

Внимание! Этот перевод, возможно, ещё не готов, так как модераторы установили для него статус «идёт перевод»

Например, давайте напишем простую программу по такому условию:

Считать текст состоящий из слов разделенных пробелами, и присвоить уникальный номер каждому отдельному слову. Вывести строки в таком виде: ID слово.

Этот маленький скрипт будет полезен если тебе необходимо произвести некоторые операции над текстом; создав словарь один раз, тебе нужно будет манипулировать только номерами, а не целыми словами.

Возможный подход к созданию такого словаря - накапливать уже пройденные (просмотренные) слова в такую разновидность словаря соотносящего слова целым числам.

При добавлении нового соответствия нам только необходимо убедиться в том, что целое число уникально ( надежный выбор - использовать текущую длину словаря равную ID 0, 1, 2, ...).

Давайте посмотрим как это можно сделать на D.

import std.stdio, std.string;
void main() {
uint[string] dictionary;
foreach (line; stdin.byLine()) {
// Разбиваем предложение на слова
// Добавляем каждое слово из предложения в словарь
foreach (word; splitter(strip(line))) {
if (word in dictionary) continue; // Nothing to do
auto newlD = dictionary.length;
dictionary[word] = newlD;
writeln(newlD, word);
}
}
}

В D, тип ассоциативного массива (хэш-таблицы), который соотносит значения типа K со значениями типа V, обозначается как V [K] .

Так что словарь типа uint [ string ] соотносящий строки с беззнаковыми целыми числами - как раз то что нам нужно для хранения связей слово-ID.

Выражение "word in dictionary" будет ненулевым, если ключ из word будет найден в словаре dictionary. И наконец, вставка в словарь делается при помощи "dictionary[word] = newlD".

Хотя это не сделано явно в программе выше, тип string на самом деле массив символов. Вообще, массивы с изменяемой длиной обозначаются как T[] и инициализируются несколькими способами:

int[] a = new int[20]; // Целочисленный массив заполненный 20 нулями.
int[] b = [ 1, 2, 3 ]; // Массив содержит 1, 2 и 3

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

Доступ к массиву всегда сопровождается проверкой выхода за пределы. Код, который не боится риска выйти за границы массива, может получить указатель этого массива (через свойство arr.ptr) и затем использовать адресную арифметику без каких-либо проверок со стороны "D".

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

Вот так можно перебрать элементы массива, используя новую форму уже знакомого оператора foreach:

int[] arr = new int[20];
foreach (elem; arr) {
/* ... elem - это элемент массива для использования в коде */
}

Цикл выше связывает переменную elem с каждым элементом массива. Однако, присвоение elem нового значения не изменяет сам элемент массива - для этого нужно объявить elem с ключевым словом ref:

// Обнулить все элементы arr
foreach (ref elem; arr) {
elem = 0; // теперь значение попадёт напрямую в массив
}

Иногда нужно иметь не только элемент массива, но и его индекс - foreach может и это:

int[] months = new int[12];
foreach (i, ref e; months) { // здесь 'i' - индекс элемента 'e'
e = i + 1;
}

Код выше создаёт массив чисел 1, 2, ..., 12. Этот цикл эквивалентен слегка более развёрнутому коду ниже:

foreach (i; 0 .. months.length) {
months[i] = i + 1;
}

В D можно создавать и массивы фиксированной длины (статические массивы): например, int[5] - массив из 5 целых и неизменяемой длиной.

Массивы обладают семантикой "поверхностной копии", т.е. присвоение переменной одного массива другой, не создаёт отдельной копии - теперь просто два имени ссылаются на один и тот же участок памяти. Если всё же нужна копия, нужно воспользоваться свойством массива dup:

int[] a = new int[100];
int[] b = a; // теперь 'a' и 'b' ссылаются на один и тот же массив
// ++x увеличивает на 1 значение x
++b[10]; // b[10] теперь равно 1, равно как и a[10]
b = a.dup; // А вот теперь b - независимая копия 'a'
++b[10]; // b[10] теперь стало 2, а a[10] осталось равным 1

Внимание! Этот перевод, возможно, ещё не готов.
Его статус: идёт перевод

Переведено на Нотабеноиде
http://notabenoid.org/book/42515/164384

Переводчики: thornik, Born2frag86

Настройки

Готово:

100.00% КП = 1.0