2016-07-22 2 views
1

Я учу себя «D», и у меня было, что может показаться основным для некоторых, вопрос о шаблонах. Например, в статье я в настоящее время чтения (см в нижней части этого поста) содержит следующий код:Понимание шаблонов в D

int foo(int x) 
{ 
    return x; 
} 

string foo(string x) 
{ 
    return x; 
} 

void main() 
{ 
    assert(foo(12345) == 12345); 
    assert(foo("hello") == "hello"); 
} 

Очевидно, что этот конкретный фрагмент кода меньше, чем элегантный и шаблон позволит устранить повторение:

foo(T)(T x) 
{ 
    return x; 
} 

void main() 
{ 
    assert(foo!(int)(12345) == 12345); 
    assert(foo!(string)("hello") == "hello"); 
} 

Второй пример довольно простой, поскольку мы просто возвращаем переданное значение. Моя путаница возникает из-за того, что функция, однако шаблонная, все же появляется, чтобы быть ограничена одним типом значения, так как я не могу легко представить строку и целочисленное значение, имеющее много общего. Поэтому программист должен проверить тип передаваемой переменной и затем написать код для обработки случаев строки или целого числа отдельно? Является ли создание большого функционального органа действительно более эффективным? Я понимаю, что моя незнакомость с шаблонами очевидна. Поэтому мой вопрос :)

http://nomad.so/2013/07/templates-in-d-explained/

+3

В https://github.com/PhilippeSigaud/D-templates-tutorial вы можете найти целую книгу (бесплатно) о шаблонах D. Это отличное чтение. – DejanLekic

ответ

4

Буквальное определение «шаблон» является «то, что служит образцом для других, чтобы скопировать» и это то, что делает компилятор. Для каждого типа (строка и int в вашем случае) он копирует функцию шаблона и создает специальную функцию во время компиляции.

Нет необходимости в шаблоне во время выполнения, чтобы его можно было выбросить после компиляции. В скомпилированном двоичном коде есть два функции foo!(int) и foo!(string).

Является ли программист ожидающим проверки типа передаваемой переменной и затем писать код для обработки случаев строки или целого числа отдельно?

Это зависит. Иногда вы хотите это сделать. Например, для оптимизации производительности. Иногда вам не нужно это делать и писать общие функции.

Является ли создание тела большой функции действительно более эффективным?

Иногда. Если нет, то не делайте этого. Например, вы можете написать один generic find функция, которая работает на массивах, связанных списках и подобных материалах.

1

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

Возьмите произвольный контейнер в качестве примера, который содержит элементы T. Даже если строка и int не имеют много общего, вы сможете создать контейнер для каждого из них.

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

Смежные вопросы