add section about templates
This commit is contained in:
parent
63444ed552
commit
b291db0e97
1 changed files with 209 additions and 0 deletions
|
@ -1,5 +1,73 @@
|
||||||
# Hands-On DLang
|
# 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
|
## Setup
|
||||||
|
|
||||||
### Installing DMD and DUB
|
### Installing DMD and DUB
|
||||||
|
@ -794,3 +862,144 @@ if (c == null) // error
|
||||||
if (c is null) // ok
|
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
|
||||||
|
```
|
||||||
|
|
Loading…
Reference in a new issue