add section about templates

This commit is contained in:
Johannes Loher 2018-04-14 00:35:00 +02:00
parent 63444ed552
commit b291db0e97

View file

@ -1,5 +1,73 @@
# Hands-On DLang
- [Hands-On DLang](#hands-on-dlang)
- [Setup](#setup)
- [Installing DMD and DUB](#installing-dmd-and-dub)
- [OS X](#os-x)
- [Installing with Homebrew (recommended)](#installing-with-homebrew-recommended)
- [Installing locally using the install script](#installing-locally-using-the-install-script)
- [Installing using the installer](#installing-using-the-installer)
- [Windows](#windows)
- [Recommended editor setup](#recommended-editor-setup)
- [Installation of Visual Studio Code](#installation-of-visual-studio-code)
- [Extension setup](#extension-setup)
- [Basics](#basics)
- [Hello World](#hello-world)
- [Imports and modules](#imports-and-modules)
- [Selective imports](#selective-imports)
- [Scoped imports](#scoped-imports)
- [Imports match files and directories](#imports-match-files-and-directories)
- [Basic Types](#basic-types)
- [Type conversion](#type-conversion)
- [Type properties](#type-properties)
- [Indexing](#indexing)
- [Variable declarations](#variable-declarations)
- [Mutability](#mutability)
- [`immutable`](#immutable)
- [`const`](#const)
- [Functions](#functions)
- [Return type deduction](#return-type-deduction)
- [Default arguments](#default-arguments)
- [Local functions](#local-functions)
- [Memory and pointers](#memory-and-pointers)
- [Memory safety](#memory-safety)
- [Structs](#structs)
- [Member functions](#member-functions)
- [`const` member functions](#const-member-functions)
- [`static` member functions](#static-member-functions)
- [Arrays](#arrays)
- [Static arrays](#static-arrays)
- [Dynamic arrays](#dynamic-arrays)
- [Array operations and properties](#array-operations-and-properties)
- [Slices](#slices)
- [Alias and `string`s](#alias-and-strings)
- [Control flow](#control-flow)
- [if…else](#if%E2%80%A6else)
- [switch…case](#switch%E2%80%A6case)
- [Old fashioned loops](#old-fashioned-loops)
- [Breaking out of outer loops](#breaking-out-of-outer-loops)
- [`foreach` loops](#foreach-loops)
- [Element iteration](#element-iteration)
- [Access by reference](#access-by-reference)
- [Iterate `n` times](#iterate-n-times)
- [Iteration with index counter](#iteration-with-index-counter)
- [Ranges](#ranges)
- [Laziness](#laziness)
- [Copying ranges](#copying-ranges)
- [`RandomAccessRange`s](#randomaccessranges)
- [Lazy range algorithms](#lazy-range-algorithms)
- [Associative arrays](#associative-arrays)
- [Classes](#classes)
- [Inheritance](#inheritance)
- [Final and abstract member functions](#final-and-abstract-member-functions)
- [Checking for identity](#checking-for-identity)
- [Interfaces](#interfaces)
- [Templates](#templates)
- [Template functions](#template-functions)
- [Other templates](#other-templates)
- [Template value parameters](#template-value-parameters)
- [Other template parameters](#other-template-parameters)
## Setup
### Installing DMD and DUB
@ -794,3 +862,144 @@ if (c == null) // error
if (c is null) // ok
/* … */
```
### Interfaces
`interface`s work basically the same as in Java:
```D
interface Animal {
void makeNoise();
}
class Dog : Animal {
override void makeNoise() {
writeln('woof!');
}
}
auto dog = new Dog;
Animal animal = dog; // implicit cast to interface
animal.makeNoise();
```
### Templates
#### Template functions
Template functions in D are very similar to C++ template functions:
```D
auto add(T)(T lhs, T rhs) {
return lhs + rhs;
}
add!int(5,10);
add!float(5.0f, 10.0f);
add!Animal(dog, cat); // error, Animal does not implement +
```
In the explicit template notation, the `add` template function would look like
this:
```D
template add(T) {
auto add(T lhs, T rhs) {
return lhs + rhs;
}
}
```
D also allows implicit function template instanciation:
```D
add(5, 10); // same as add!int(5,10)
```
Templates can have more than one template parameter:
```D
void print(S, T)(S x, T y) {
writeln(x);
writeln(y);
}
print!(int, string)(42, "is the best number");
```
#### Other templates
Of course, `struct`s, `class`es and `interface`s can also be templated:
```D
struct S(T) {
/* … */
}
auto s = S!int;
```
It is also possible to have variable templates:
```D
ubyte[T.sizeof * 8] buffer8(T) = 42;
auto myBuffer = buffer!(int, 8); // create a buffer with space for 8 ints and initialize its elements to 42
static assert(is(typeof(myBuffer) == ubyte[32]));
assert(myBuffer[0] == 42);
```
This gets lowered to the following explicit template syntax:
```D
template buffer8(T) {
ubyte[T.sizeof * 8] buffer8 = 42;
}
```
#### Template value parameters
So far we have only seen templateF type parameters. It is also possible to have
template value parameters:
```D
struct Animal(string noise) {
void makeNoise() {
writeln(noise);
}
}
auto dog = Animal!"woof!"();
dog.makeNoise(); // woof!
```
#### Other template parameters
There are some other types of template parameters: template alias parameters
and template sequence parameters. Template alias parameters can be any D symbol
(which means basically anything except for basic types):
```D
void print(alias var)() {
writeln(var);
}
struct S {}
auto x = 42;
print!x();
print!4.2f();
print!"foo"();
print!S(); // error, would be actually legal, but cant pass types to writeln
```
Template sequence parameters take a variadic number of template arguments:
```D
void print(Args...)(Args args) {
foreach (arg; args) { // yes, we can iterate over them (loop unrolling)
writeln(arg);
}
}
print(42, 3.5f, "foo");
print(); // also valid, prints nothing
```