diff --git a/hands-on_dlang.md b/hands-on_dlang.md index c06632c..2cab56d 100644 --- a/hands-on_dlang.md +++ b/hands-on_dlang.md @@ -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 +```