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)
|
||||
- [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
|
||||
```
|
||||
|
|
Loading…
Reference in a new issue