summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--c++.html.markdown2
-rw-r--r--cs-cz/sass.html.markdown439
-rw-r--r--elm.html.markdown68
-rw-r--r--ru-ru/d-ru.html.markdown753
4 files changed, 1232 insertions, 30 deletions
diff --git a/c++.html.markdown b/c++.html.markdown
index 6b452b1b..f4aa2f5a 100644
--- a/c++.html.markdown
+++ b/c++.html.markdown
@@ -149,7 +149,7 @@ namespace First {
namespace Second {
void foo()
{
- printf("This is Second::foo\n")
+ printf("This is Second::foo\n");
}
}
diff --git a/cs-cz/sass.html.markdown b/cs-cz/sass.html.markdown
new file mode 100644
index 00000000..0d2fca64
--- /dev/null
+++ b/cs-cz/sass.html.markdown
@@ -0,0 +1,439 @@
+---
+language: sass
+filename: learnsass-cz.scss
+contributors:
+ - ["Laura Kyle", "https://github.com/LauraNK"]
+ - ["Sean Corrales", "https://github.com/droidenator"]
+translators:
+ - ["Michal Martinek", "https://github.com/MichalMartinek"]
+lang: cs-cz
+---
+
+Sass je rozšíření jazyka CSS, který přidává nové vlastnosti jako proměnné, zanořování, mixiny a další.
+Sass (a další preprocesory, jako [Less](http://lesscss.org/)) pomáhají vývojářům psát udržovatelný a neopakující (DRY) kód.
+
+Sass nabízí dvě možnosti syntaxe. SCSS, které je stejná jako CSS, akorát obsahuje nové vlastnosti Sassu. Nebo Sass, který používá odsazení místo složených závorek a středníků.
+Tento tutoriál bude používat syntaxi CSS.
+
+
+Pokud jste již obeznámeni s CSS3, budete schopni používat Sass relativně rychle. Nezprostředkovává nějaké úplně nové stylové možnosti, spíše nátroje, jak psát Vás CSS kód více efektivně, udržitelně a jednoduše.
+
+```scss
+
+
+//Jednořádkové komentáře jsou ze Sassu při kompilaci vymazány
+
+/*Víceřádkové komentáře jsou naopak zachovány */
+
+
+
+/*Proměnné
+==============================*/
+
+
+
+/* Můžete uložit CSS hodnotu (jako třeba barvu) do proměnné.
+Použijte symbol '$' k jejímu vytvoření. */
+
+$hlavni-barva: #A3A4FF;
+$sekundarni-barva: #51527F;
+$body-font: 'Roboto', sans-serif;
+
+/* Můžete používat proměnné napříč vaším souborem.
+Teď, když chcete změnit barvu, stačí ji změnit pouze jednou.*/
+
+body {
+ background-color: $hlavni-barva;
+ color: $sekundarni-barva;
+ font-family: $body-font;
+}
+
+/* Toto se zkompiluje do: */
+body {
+ background-color: #A3A4FF;
+ color: #51527F;
+ font-family: 'Roboto', sans-serif;
+}
+
+
+/* Toto je o hodně více praktické, než měnit každý výskyt barvy. */
+
+
+
+/*Mixiny
+==============================*/
+
+
+
+/* Pokud zjistíte, že píšete kód pro více než jeden element, můžete jej uložit do mixinu.
+
+Použijte '@mixin' direktivu, plus jméno vašeho mixinu.*/
+
+@mixin na-stred {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+ left: 0;
+ right: 0;
+}
+
+/* Mixin vložíte pomocí '@include' a jména mixinu */
+
+div {
+ @include na-stred;
+ background-color: $hlavni-barva;
+}
+
+/*Což se zkompiluje do: */
+div {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+ left: 0;
+ right: 0;
+ background-color: #A3A4FF;
+}
+
+
+/* Můžete využít mixiny i třeba pro takovéto ušetření práce: */
+
+@mixin velikost($sirka, $vyska) {
+ width: $sirka;
+ height: $vyska;
+}
+
+/*Stačí vložit argumenty: */
+
+.obdelnik {
+ @include velikost(100px, 60px);
+}
+
+.ctverec {
+ @include velikost(40px, 40px);
+}
+
+/* Toto se zkompiluje do: */
+.obdelnik {
+ width: 100px;
+ height: 60px;
+}
+
+.ctverec {
+ width: 40px;
+ height: 40px;
+}
+
+
+
+/*Funkce
+==============================*/
+
+
+
+/* Sass obsahuje funkce, které vám pomůžou splnit různé úkoly. */
+
+/* Funkce se spouštějí pomocí jejich jména, které následuje seznam argumentů uzavřený v kulatých závorkách. */
+body {
+ width: round(10.25px);
+}
+
+.footer {
+ background-color: fade_out(#000000, 0.25)
+}
+
+/* Se zkompiluje do: */
+
+body {
+ width: 10px;
+}
+
+.footer {
+ background-color: rgba(0, 0, 0, 0.75);
+}
+
+/* Můžete také definovat vlastní funkce. Funkce jsou velmi podobné mixinům.
+ Když se snažíte vybrat mezi funkcí a mixinem, mějte na paměti, že mixiny
+ jsou lepší pro generování CSS kódu, zatímco funkce jsou lepší pro logiku.
+ Příklady ze sekce Matematické operátory jsou skvělí kandidáti na
+ znovupoužitelné funkce. */
+
+/* Tato funkce vrací poměr k velikosti rodiče v procentech.
+@function vypocitat-pomer($velikost, $velikost-rodice) {
+ @return $velikost / $velikost-rodice * 100%;
+}
+
+$hlavni obsah: vypocitat-pomer(600px, 960px);
+
+.hlavni-obsah {
+ width: $hlavni-obsah;
+}
+
+.sloupec {
+ width: vypocitat-pomer(300px, 960px);
+}
+
+/* Zkompiluje do: */
+
+.hlavni-obsah {
+ width: 62.5%;
+}
+
+.sloupec {
+ width: 31.25%;
+}
+
+
+
+/*Dědění
+==============================*/
+
+
+
+/*Dědění je způsob jak používat vlastnosti pro jeden selektor ve druhém. */
+
+.oznameni {
+ @include velikost(5em, 5em);
+ border: 5px solid $sekundarni-barva;
+}
+
+.oznameni-uspech {
+ @extend .oznameni;
+ border-color: #22df56;
+}
+
+/* Zkompiluje do: */
+.oznameni, .oznameni-uspech {
+ width: 5em;
+ height: 5em;
+ border: 5px solid #51527F;
+}
+
+.oznameni-uspech {
+ border-color: #22df56;
+}
+
+
+/* Dědění CSS výrazů je preferováno před vytvořením mixinu kvůli způsobu,
+ jakým způsobem Sass dává dohromady třídy, které sdílejí stejný kód.
+ Kdyby to bylo udělané pomocí mixinu, tak výška, šířka, rámeček by byl v
+ každém výrazu, který by volal mixin. I když tohle neovlivní vaše workflow,
+ přidá to kód navíc do souborů. */
+
+
+/*Zanořování
+==============================*/
+
+
+
+/*Sass vám umožňuje zanořovat selektory do selektorů */
+
+ul {
+ list-style-type: none;
+ margin-top: 2em;
+
+ li {
+ background-color: #FF0000;
+ }
+}
+
+/* '&' nahradí rodičovský element. */
+/* Můžete také zanořovat pseudo třídy. */
+/* Pamatujte, že moc velké zanoření do hloubky snižuje čitelnost.
+ Doporučuje se používat maximálně trojité zanoření.
+ Na příklad: */
+
+ul {
+ list-style-type: none;
+ margin-top: 2em;
+
+ li {
+ background-color: red;
+
+ &:hover {
+ background-color: blue;
+ }
+
+ a {
+ color: white;
+ }
+ }
+}
+
+/* Zkompiluje do: */
+
+ul {
+ list-style-type: none;
+ margin-top: 2em;
+}
+
+ul li {
+ background-color: red;
+}
+
+ul li:hover {
+ background-color: blue;
+}
+
+ul li a {
+ color: white;
+}
+
+
+
+/*Částečné soubory a importy
+==============================*/
+
+
+
+/* Sass umožňuje vytvářet částečné soubory. Tyto soubory pomahájí udržovat váš
+ kód modulární. Tyto soubory by měli začínat vždy '_', např. _reset.css.
+ Částečné soubory se nepřevádí do CSS. */
+
+/* Toto je kód, který si uložíme do souboru _reset.css */
+
+html,
+body,
+ul,
+ol {
+ margin: 0;
+ padding: 0;
+}
+
+/* Sass obsahuje @import, které může být použit pro import částečných souborů.
+ Toto se liší od klasického CSS @import, který dělá HTTP požadavek na stáhnutí
+ souboru. Sass vezme importovaný soubor a vloží ho do kompilovaného kódu. */
+
+@import 'reset';
+
+body {
+ font-size: 16px;
+ font-family: Helvetica, Arial, Sans-serif;
+}
+
+/* Zkompiluje do: */
+
+html, body, ul, ol {
+ margin: 0;
+ padding: 0;
+}
+
+body {
+ font-size: 16px;
+ font-family: Helvetica, Arial, Sans-serif;
+}
+
+
+
+/*Zástupné selektory
+==============================*/
+
+
+
+/* Zástupné selektory jsou užitečné, když vytváříte CSS výraz, ze kterého
+ chcete později dědit. Když chcete vytvořit výraz, ze kterého je možné pouze
+ dědit pomocí @extend, vytvořte zástupný selektor s CSS výrazem. Ten začíná
+ symbolem '%' místo '.' nebo '#'. Tyto výrazy se neobjeví ve výsledném CSS */
+
+%okno-obsahu {
+ font-size: 14px;
+ padding: 10px;
+ color: #000;
+ border-radius: 4px;
+}
+
+.okno-zpravy {
+ @extend %okno-obsahu;
+ background-color: #0000ff;
+}
+
+/* Zkompiluje do: */
+
+.okno-zpravy {
+ font-size: 14px;
+ padding: 10px;
+ color: #000;
+ border-radius: 4px;
+}
+
+.okno-zpravy {
+ background-color: #0000ff;
+}
+
+
+
+/*Matematické operace
+==============================*/
+
+
+
+/* Sass obsahuje následující operátory: +, -, *, /, and %. Tyto operátory
+ můžou být velmi užitečné pro počítání hodnot přímo ve vašem souboru Sass.
+ Níže je příklad, jak udělat jednoduchý dvousloupcový layout. */
+
+$oblast-obsahu: 960px;
+$hlavni-obsah: 600px;
+$vedlejsi-sloupec: 300px;
+
+$obsah-velikost: $hlavni-obsah / $oblast-obsahu * 100%;
+$vedlejsi-sloupec-velikost: $vedlejsi-sloupec / $oblast-obsahu * 100%;
+$zbytek-velikost: 100% - ($main-size + $vedlejsi-sloupec-size);
+
+body {
+ width: 100%;
+}
+
+.hlavni-obsah {
+ width: $obsah-velikost;
+}
+
+.vedlejsi-sloupec {
+ width: $vedlejsi-sloupec-velikost;
+}
+
+.zbytek {
+ width: $zbytek-velikost;
+}
+
+/* Zkompiluje do: */
+
+body {
+ width: 100%;
+}
+
+.hlavni-obsah {
+ width: 62.5%;
+}
+
+.vedlejsi-sloupec {
+ width: 31.25%;
+}
+
+.gutter {
+ width: 6.25%;
+}
+
+
+```
+
+
+
+## SASS nebo Sass?
+Divili jste se někdy, jestli je Sass zkratka nebo ne? Pravděpodobně ne, ale řeknu vám to stejně. Jméno tohoto jazyka je slovo, "Sass", a ne zkratka.
+Protože to lidé konstatně píší jako "SASS", nazval ho autor jazyka jako "Syntactically Awesome StyleSheets" (Syntaktický úžasně styly).
+
+
+## Procvičování Sassu
+Pokud si chcete hrát se Sassem ve vašem prohlížeči, navštivte [SassMeister](http://sassmeister.com/).
+Můžete používát oba dva způsoby zápisu, stačí si vybrat v nastavení SCSS nebo SASS.
+
+
+## Kompatibilita
+
+Sass může být použit v jakémkoliv projektu, jakmile máte program, pomocí kterého ho zkompilujete do CSS. Pokud si chcete ověřit, že CSS, které Sass produkuje je kompatibilní s prohlížeči:
+
+[QuirksMode CSS](http://www.quirksmode.org/css/) a [CanIUse](http://caniuse.com) jsou skvělé stránky pro kontrolu kompatibility.
+
+
+## Kam dál?
+* [Oficiální dokumentace](http://sass-lang.com/documentation/file.SASS_REFERENCE.html)
+* [The Sass Way](http://thesassway.com/) obsahuje tutoriál a řadu skvělých článků
diff --git a/elm.html.markdown b/elm.html.markdown
index f8564c4b..f395e85b 100644
--- a/elm.html.markdown
+++ b/elm.html.markdown
@@ -38,11 +38,10 @@ not False -- True
1 < 10 -- True
-- Strings and characters
-"This is a string."
-'a' -- character
-'You cant use single quotes for strings.' -- error!
+"This is a string because it uses double quotes."
+'a' -- characters in single quotes
--- Strings can be appended
+-- Strings can be appended.
"Hello " ++ "world!" -- "Hello world!"
{-- Lists, Tuples, and Records --}
@@ -53,10 +52,10 @@ not False -- True
-- The second example can also be written with two dots.
[1..5]
--- Append lists just like strings
+-- Append lists just like strings.
[1..5] ++ [6..10] == [1..10] -- True
--- To add one item, use "cons"
+-- To add one item, use "cons".
0 :: [1..5] -- [0, 1, 2, 3, 4, 5]
-- The head and tail of a list are returned as a Maybe. Instead of checking
@@ -64,6 +63,7 @@ not False -- True
List.head [1..5] -- Just 1
List.tail [1..5] -- Just [2, 3, 4, 5]
List.head [] -- Nothing
+-- List.functionName means the function lives in the List module.
-- Every element in a tuple can be a different type, but a tuple has a
-- fixed length.
@@ -74,23 +74,24 @@ List.head [] -- Nothing
fst ("elm", 42) -- "elm"
snd ("elm", 42) -- 42
--- Records are like tuples but the fields have names.
--- Notice that equals signs, not colons, are used.
+-- Records are like tuples but the fields have names. The order of fields
+-- doesn't matter. Notice that record values use equals signs, not colons.
{ x = 3, y = 7 }
-- Access a field with a dot and the field name.
{ x = 3, y = 7 }.x -- 3
--- Or with an accessor fuction, a dot and then the field name.
+-- Or with an accessor fuction, which is a dot and the field name on its own.
.y { x = 3, y = 7 } -- 7
-- Update the fields of a record. (It must have the fields already.)
{ person |
name = "George" }
-{ physics |
- position = physics.position + physics.velocity,
- velocity = physics.velocity + physics.acceleration }
+-- Update multiple fields at once, using the current values.
+{ particle |
+ position = particle.position + particle.velocity,
+ velocity = particle.velocity + particle.acceleration }
{-- Control Flow --}
@@ -111,11 +112,15 @@ else
-- Use case statements to pattern match on different possibilities.
case aList of
[] -> "matches the empty list"
+ [x]-> "matches a list of exactly one item, " ++ toString x
x::xs -> "matches a list of at least one item whose head is " ++ toString x
+-- Pattern matches go in order. If we put [x] last, it would never match because
+-- x::xs also matches (xs would be the empty list). Matches do not "fall through".
+-- Pattern match on a Maybe.
case List.head aList of
Just x -> "The head is " ++ toString x
- Nothing -> "The list was empty"
+ Nothing -> "The list was empty."
{-- Functions --}
@@ -151,8 +156,8 @@ area (width, height) =
area (6, 7) -- 42
--- Use curly brackets to pattern match record field names
--- Use let to define intermediate values
+-- Use curly brackets to pattern match record field names.
+-- Use let to define intermediate values.
volume {width, height, depth} =
let
area = width * height
@@ -161,7 +166,7 @@ volume {width, height, depth} =
volume { width = 3, height = 2, depth = 7 } -- 42
--- Functions can be recursive
+-- Functions can be recursive.
fib n =
if n < 2 then
1
@@ -170,12 +175,13 @@ fib n =
List.map fib [0..8] -- [1, 1, 2, 3, 5, 8, 13, 21, 34]
+-- Another recursive function (use List.length in real code).
listLength aList =
case aList of
[] -> 0
x::xs -> 1 + listLength xs
--- Function application happens before any infix operation
+-- Function calls happen before any infix operator. Parens indicate precedence.
cos (degrees 30) ^ 2 + sin (degrees 30) ^ 2 -- 1
-- First degrees is applied to 30, then the result is passed to the trig
-- functions, which is then squared, and the addition happens last.
@@ -191,7 +197,7 @@ cos (degrees 30) ^ 2 + sin (degrees 30) ^ 2 -- 1
True : Bool
-- Functions have types too. Read -> as "goes to". Think of the rightmost type
--- as the type of the return value.
+-- as the type of the return value, and the others as arguments.
not : Bool -> Bool
round : Float -> Int
@@ -226,7 +232,7 @@ type alias Point3D = { x : Float, y : Float, z : Float }
otherOrigin : Point3D
otherOrigin = Point3D 0 0 0
--- But it's still the same type, you can equate them
+-- But it's still the same type, so you can equate them.
origin == otherOrigin -- True
-- By contrast, defining a union type creates a type that didn't exist before.
@@ -236,14 +242,15 @@ type Direction = North | South | East | West
-- Tags can carry other values of known type. This can work recursively.
type IntTree = Leaf | Node Int IntTree IntTree
-
-- "Leaf" and "Node" are the tags. Everything following a tag is a type.
+
-- Tags can be used as values or functions.
root : IntTree
root = Node 7 Leaf Leaf
-- Union types (and type aliases) can use type variables.
type Tree a = Leaf | Node a (Tree a) (Tree a)
+-- "The type tree of a is a leaf, or a node of a, tree of a, and tree of a."
-- You can pattern match union tags. The uppercase tags must be matched exactly.
-- The lowercase variables will match anything. Underscore also matches
@@ -260,21 +267,20 @@ leftmostElement tree =
{-- Modules and Imports --}
--- The core libraries are organized into modulues, as are any third-party
--- libraries you may use. For large projects, you can define your own modulues.
+-- The core libraries are organized into modules, as are any third-party
+-- libraries you may use. For large projects, you can define your own modules.
-- Put this at the top of the file. If omitted, you're in Main.
module Name where
--- By default, everything is exported.
--- Limit what values and types are exported
-module Name (Type, value) where
+-- By default, everything is exported. You can specify exports explicity.
+module Name (MyType, myValue) where
-- One common pattern is to export a union type but not its tags. This is known
-- as an "opaque type", and is frequently used in libraries.
--- Import code from other modules to use it in this one
--- Places Dict in scope, so you can call Dict.insert
+-- Import code from other modules to use it in this one.
+-- Places Dict in scope, so you can call Dict.insert.
import Dict
-- Imports the Dict module and the Dict type, so your annotations don't have to
@@ -318,6 +324,8 @@ $ elm repl
-- Install a new package, and record it in elm-package.json.
$ elm package install evancz/elm-html
+-- See what changed between versions of a package.
+$ elm package diff evancz/elm-html 3.0.0 4.0.2
-- Elm's package manager enforces semantic versioning, so minor version bumps
-- will never break your build!
```
@@ -335,12 +343,14 @@ Here are some useful resources.
* Documentation for [Elm's core libraries](http://package.elm-lang.org/packages/elm-lang/core/latest/). Take note of:
* [Basics](http://package.elm-lang.org/packages/elm-lang/core/latest/Basics), which is imported by default
- * Data structures like [Array](http://package.elm-lang.org/packages/elm-lang/core/latest/Array), [Dict](http://package.elm-lang.org/packages/elm-lang/core/latest/Dict), and [Set](http://package.elm-lang.org/packages/elm-lang/core/latest/Set)
+ * [Maybe](http://package.elm-lang.org/packages/elm-lang/core/latest/Maybe) and its cousin [Result](http://package.elm-lang.org/packages/elm-lang/core/latest/Result), commonly used for missing values or error handling
+ * Data structures like [List](http://package.elm-lang.org/packages/elm-lang/core/latest/List), [Array](http://package.elm-lang.org/packages/elm-lang/core/latest/Array), [Dict](http://package.elm-lang.org/packages/elm-lang/core/latest/Dict), and [Set](http://package.elm-lang.org/packages/elm-lang/core/latest/Set)
* JSON [encoding](http://package.elm-lang.org/packages/elm-lang/core/latest/Json-Encode) and [decoding](http://package.elm-lang.org/packages/elm-lang/core/latest/Json-Decode)
-* [The Elm Architecture](https://github.com/evancz/elm-architecture-tutorial#the-elm-architecture). An essay with examples on how to organize code into components.
+* [The Elm Architecture](https://github.com/evancz/elm-architecture-tutorial#the-elm-architecture). An essay by Elm's creator with examples on how to organize code into components.
* The [Elm mailing list](https://groups.google.com/forum/#!forum/elm-discuss). Everyone is friendly and helpful.
+* [Scope in Elm](https://github.com/elm-guides/elm-for-js/blob/master/Scope.md#scope-in-elm) and [How to Read a Type Annotation](https://github.com/elm-guides/elm-for-js/blob/master/How%20to%20Read%20a%20Type%20Annotation.md#how-to-read-a-type-annotation). More community guides on the basics of Elm, written for JavaScript developers.
Go out and write some Elm!
diff --git a/ru-ru/d-ru.html.markdown b/ru-ru/d-ru.html.markdown
new file mode 100644
index 00000000..8f4233fd
--- /dev/null
+++ b/ru-ru/d-ru.html.markdown
@@ -0,0 +1,753 @@
+---
+language: d
+filename: learnd-ru.d
+contributors:
+ - ["Anton Pastukhov", "http://dprogramming.ru/"]
+ - ["Robert Brights-Gray", "http://lhs-blog.info/"]
+ - ["Andre Polykanine", "http://oire.me/"]
+lang: ru-ru
+---
+D - современный компилируемый язык общего назначения с Си-подобным синтаксисом,
+который сочетает удобство, продуманный дизайн и высокую производительность.
+D - это С++, сделанный правильно.
+
+```d
+// Welcome to D! Это однострочный комментарий
+
+/* многострочный
+ комментарий */
+
+/+
+ // вложенные комментарии
+
+ /* еще вложенные
+ комментарии */
+
+ /+
+ // мало уровней вложенности? Их может быть сколько угодно.
+ +/
++/
+
+/*
+ Имя модуля. Каждый файл с исходным кодом на D — модуль.
+ Если имя не указано явно, то предполагается, что оно совпадает с именем
+ файла. Например, для файла "test.d" имя модуля будет "test", если явно
+ не указать другое
+ */
+module app;
+
+// импорт модуля. Std — пространство имен стандартной библиотеки (Phobos)
+import std.stdio;
+
+// можно импортировать только нужные части, не обязательно модуль целиком
+import std.exception : enforce;
+
+// точка входа в программу — функция main, аналогично C/C++
+void main()
+{
+ writeln("Hello, world!");
+}
+
+
+
+/*** типы и переменные ***/
+
+int a; // объявление переменной типа int (32 бита)
+float b = 12.34; // тип с плавающей точкой
+double c = 56.78; // тип с плавающей точкой (64 бита)
+
+/*
+ Численные типы в D, за исключением типов с плавающей точкой и типов
+ комплексных чисел, могут быть беззнаковыми.
+ В этом случае название типа начинается с префикса "u"
+*/
+uint d = 10; ulong e = 11;
+bool b = true; // логический тип
+char d = 'd'; // UTF-символ, 8 бит. D поддерживает UTF "из коробки"
+wchar e = 'é'; // символ UTF-16
+dchar f; // и даже UTF-32, если он вам зачем-то понадобится
+
+string s = "для строк есть отдельный тип, это не просто массив char-ов из Си";
+wstring ws = "поскольку у нас есть wchar, должен быть и wstring";
+dstring ds = "...и dstring, конечно";
+
+string кириллица = "Имена переменных должны быть в Unicode, но не обязательно на латинице.";
+
+typeof(a) b = 6; // typeof возвращает тип своего выражения.
+ // В результате, b имеет такой же тип, как и a
+
+// Тип переменной, помеченной ключевым словом auto,
+// присваивается компилятором исходя из значения этой переменной
+auto x = 1; // Например, тип этой переменной будет int.
+auto y = 1.1; // этой — double
+auto z = "Zed is dead!"; // а этой — string
+
+int[3] arr = [1, 2, 3]; // простой одномерный массив с фиксированным размером
+int[] arr2 = [1, 2, 3, 4]; // динамический массив
+int[string] aa = ["key1": 5, "key2": 6]; // ассоциативный массив
+
+/*
+ Строки и массивы в D — встроенные типы. Для их использования не нужно
+ подключать ни внешние, ни даже стандартную библиотеку, хотя в последней
+ есть множество дополнительных инструментов для работы с ними.
+ */
+immutable int ia = 10; // неизменяемый тип,
+ // обозначается ключевым словом immutable
+ia += 1; // — вызовет ошибку на этапе компиляции
+
+// перечислимый (enumerable) тип,
+// более правильный способ работы с константами в D
+enum myConsts = { Const1, Const2, Const3 };
+
+// свойства типов
+writeln("Имя типа : ", int.stringof); // int
+writeln("Размер в байтах : ", int.sizeof); // 4
+writeln("Минимальное значение : ", int.min); // -2147483648
+writeln("Максимальное значение : ", int.max); // 2147483647
+writeln("Начальное значение : ", int.init); // 0. Это значение,
+ // присвоенное по умолчанию
+
+// На самом деле типов в D больше, но все мы здесь описывать не будем,
+// иначе не уложимся в Y минут.
+
+
+
+/*** Приведение типов ***/
+
+// to!(имя типа)(выражение) - для большинства конверсий
+import std.conv : to; // функция "to" - часть стандартной библиотеки, а не языка
+double d = -1.75;
+short s = to!short(d); // s = -1
+
+/*
+ cast - если вы знаете, что делаете. Кроме того, это единственный способ
+ преобразования типов-указателей в "обычные" и наоборот
+*/
+void* v;
+int* p = cast(int*)v;
+
+// Для собственного удобства можно создавать псевдонимы
+// для различных встроенных объектов
+alias int newInt; // теперь можно обращаться к newInt так, как будто бы это int
+newInt a = 5;
+
+alias newInt = int; // так тоже допустимо
+alias uint[2] pair; // дать псевдоним можно даже сложным структурам данных
+
+
+
+/*** Операторы ***/
+
+int x = 10; // присваивание
+x = x + 1; // 11
+x -= 2; // 9
+x++; // 10
+++x; // 11
+x *= 2; // 22
+x /= 2; // 11
+x = x ^^ 2; // 121 (возведение в степень)
+x ^^= 2; // 1331 (то же самое)
+
+string str1 = "Hello";
+string str2 = ", world!";
+string hw = str1 ~ str2; // Конкатенация строк
+
+int[] arr = [1, 2, 3];
+arr ~= 4; // [1, 2, 3, 4] - добавление элемента в конец массива
+
+
+
+/*** Логика и сравнения ***/
+
+int x = 0; int y = 1;
+
+x == y; // false
+x > y; // false
+x < y; // true
+x >= y; // false
+x != y; // true. ! — логическое "не"
+x > 0 || x < 1; // true. || — логическое "или"
+x > 0 && x < 1; // false && — логическое "и"
+x ^ y // true; ^ - xor (исключающее "или")
+
+// Тернарный оператор
+auto y = (x > 10) ? 1 : 0; // если x больше 10, то y равен 1,
+ // в противном случае y равен нулю
+
+
+/*** Управляющие конструкции ***/
+
+// if - абсолютно привычен
+if (a == 1) {
+ // ..
+} else if (a == 2) {
+ // ..
+} else {
+ // ..
+}
+
+// switch
+switch (a) {
+ case 1:
+ // делаем что-нибудь
+ break;
+ case 2:
+ // делаем что-нибудь другое
+ break;
+ case 3:
+ // делаем что-нибудь еще
+ break;
+ default:
+ // default обязателен, без него будет ошибка компиляции
+ break;
+}
+
+// в D есть констукция "final switch". Она не может содержать секцию "defaul"
+// и применяется, когда все перечисляемые в switch варианты должны быть
+// обработаны явным образом
+
+int dieValue = 1;
+final switch (dieValue) {
+ case 1:
+ writeln("You won");
+ break;
+
+ case 2, 3, 4, 5:
+ writeln("It's a draw");
+ break;
+
+ case 6:
+ writeln("I won");
+ break;
+}
+
+// while
+while (a > 10) {
+ // ..
+ if (number == 42) {
+ break;
+ }
+}
+
+while (true) {
+ // бесконечный цикл
+}
+
+// do-while
+do {
+ // ..
+} while (a == 10);
+
+// for
+for (int number = 1; number < 11; ++number) {
+ writeln(number); // все абсолютно стандартно
+}
+
+for ( ; ; ) {
+ // секции могут быть пустыми. Это бесконечный цикл в стиле Си
+}
+
+// foreach - универсальный и самый "правильный" цикл в D
+foreach (element; array) {
+ writeln(element); // для простых массивов
+}
+
+foreach (key, val; aa) {
+ writeln(key, ": ", val); // для ассоциативных массивов
+}
+
+foreach (c; "hello") {
+ writeln(c); // hello. Поскольку строки - это вариант массива,
+ // foreach применим и к ним
+}
+
+foreach (number; 10..15) {
+ writeln(number); // численные интервалы можно указывать явным образом
+ // этот цикл выведет значения с 10 по 14, но не 15,
+ // поскольку диапазон не включает в себя верхнюю границу
+}
+
+// foreach_reverse - в обратную сторону
+auto container = [1, 2, 3];
+foreach_reverse (element; container) {
+ writefln("%s ", element); // 3, 2, 1
+}
+
+// foreach в массивах и им подобных структурах не меняет сами структуры
+int[] a = [1, 2 ,3 ,4 ,5];
+foreach (elem; array) {
+ elem *= 2; // сам массив останется неизменным
+}
+
+writeln(a); // вывод: [1, 2, 3, 4, 5] Т.е изменений нет
+
+// добавление ref приведет к тому, что массив будет изменяться
+foreach (ref elem; array) {
+ elem *= 2;
+}
+
+writeln(a); // [2, 4, 6, 8, 10]
+
+// foreach умеет рассчитывать индексы элементов
+int[] a = [1, 2, 3, 4, 5];
+foreach (ind, elem; array) {
+ writeln(ind, " ", elem); // через ind - доступен индекс элемента,
+ // а через elem - сам элемент
+}
+
+
+
+/*** Функции ***/
+
+test(42); // Что, вот так сразу? Разве мы где-то уже объявили эту функцию?
+
+// Нет, вот она. Это не Си, здесь объявление функции не обязательно должно быть
+// до первого вызова
+int test(int argument) {
+ return argument * 2;
+}
+
+
+// В D используется единый синтаксис вызова функций
+// (UFCS, Uniform Function Call Syntax), поэтому так тоже можно:
+int var = 42.test();
+
+// и даже так, если у функции нет аргументов:
+int var2 = 42.test;
+
+// можно выстраивать цепочки:
+int var3 = 42.test.test;
+
+/*
+ Аргументы в функцию передаются по значению (т.е. функция работает не с
+ оригинальными значениями, переданными ей, а с их локальными копиями.
+ Исключение составляют объекты классов, которые передаются по ссылке.
+ Кроме того, любой параметр можно передать в функцию по ссылке с помощью
+ ключевого слова "ref"
+*/
+int var = 10;
+
+void fn1(int arg) {
+ arg += 1;
+}
+
+void fn2(ref int arg) {
+ arg += 1;
+}
+
+fn1(var); // var все еще = 10
+fn2(var); // теперь var = 11
+
+// Возвращаемое значение тоже может быть auto,
+// если его можно "угадать" из контекста
+auto add(int x, int y) {
+ return x + y;
+}
+
+auto z = add(x, y); // тип int - компилятор вывел его автоматически
+
+// Значения аргументов по умолчанию
+float linearFunction(float k, float x, float b = 1)
+{
+ return k * x + b;
+}
+
+auto linear1 = linearFunction(0.5, 2, 3); // все аргументы используются
+auto linear2 = linearFunction(0.5, 2); // один аргумент пропущен, но в функции
+ // он все равно использован и равен 1
+
+// допускается описание вложенных функций
+float quarter(float x) {
+ float doubled(float y) {
+ return y * y;
+ }
+
+ return doubled(doubled(x));
+}
+
+// функции с переменным числом аргументов
+int sum(int[] a...)
+{
+ int s = 0;
+ foreach (elem; a) {
+ s += elem;
+ }
+ return s;
+}
+
+auto sum1 = sum(1);
+auto sum2 = sum(1,2,3,4);
+
+/*
+ модификатор "in" перед аргументами функций говорит о том, что функция имеет
+ право их только просматривать. При попытке модификации такого аргумента
+ внутри функции - получите ошибку
+*/
+float printFloat(in float a)
+{
+ writeln(a);
+}
+printFloat(a); // использование таких функций - самое обычное
+
+// модификатор "out" позволяет вернуть из функции несколько результатов
+// без посредства глобальных переменных или массивов
+uint remMod(uint a, uint b, out uint modulus)
+{
+ uint remainder = a / b;
+ modulus = a % b;
+ return remainder;
+}
+
+uint modulus; // пока в этой переменной ноль
+uint rem = remMod(5, 2, modulus); // наша "хитрая" функция, и теперь
+ // в modulus - остаток от деления
+writeln(rem, " ", modulus); // вывод: 2 1
+
+
+
+/*** Структуры, классы, базовое ООП ***/
+
+// Объявление структуры. Структуры почти как в Си
+struct MyStruct {
+ int a;
+ float b;
+
+ void multiply() {
+ return a * b;
+ }
+}
+
+MyStruct str1; // Объявление переменной с типом MyStruct
+str1.a = 10; // Обращение к полю
+str1.b = 20;
+auto result = str1.multiply();
+MyStruct str2 = {4, 8} // Объявление + инициализация в стиле Си
+auto str3 = MyStruct(5, 10); // Объявление + инициализация в стиле D
+
+
+// области видимости полей и методов - 3 способа задания
+struct MyStruct2 {
+ public int a;
+
+ private:
+ float b;
+ bool c;
+
+ protected {
+ float multiply() {
+ return a * b;
+ }
+ }
+ /*
+ в дополнение к знакомым public, private и protected, в D есть еще
+ область видимости "package". Поля и методы с этим атрибутом будут
+ доступны изо всех модулей, включенных в "пакет" (package), но не
+ за его пределами. package - это "папка", в которой может храниться
+ несколько модулей. Например, в "import.std.stdio", "std" - это
+ package, в котором есть модуль stdio (и еще множество других)
+ */
+ package:
+ string d;
+
+ /* помимо этого, имеется еще один модификатор - export, который позволяет
+ использовать объявленный с ним идентификатор даже вне самой программы !
+ */
+ export:
+ string description;
+}
+
+// Конструкторы и деструкторы
+struct MyStruct3 {
+ this() { // конструктор. Для структур его не обязательно указывать явно,
+ // в этом случае пустой конструктор добавляется компилятором
+ writeln("Hello, world!");
+ }
+
+
+ // а вот это конструкция - одна из интересных идиом и представляет собой
+ // конструктор копирования, т.е конструктор, возвращающий копию структуры.
+ // Работает только в структурах.
+ this(this)
+ {
+ return this;
+ }
+
+ ~this() { // деструктор, также необязателен
+ writeln("Awww!");
+ }
+}
+
+// Объявление простейшего класса
+class MyClass {
+ int a; // в D по умолчанию данные-члены являются public
+ float b;
+}
+
+auto mc = new MyClass(); // ...и создание его экземпляра
+auto mc2 = new MyClass; // ... тоже сработает
+
+// Конструктор
+class MyClass2 {
+ int a;
+ float b;
+
+ this(int a, float b) {
+ this.a = a; // ключевое слово "this" - ссылка на объект класса
+ this.b = b;
+ }
+}
+
+auto mc2 = new MyClass2(1, 2.3);
+
+// Классы могут быть вложенными
+class Outer
+{
+ int m;
+
+ class Inner
+ {
+ int foo()
+ {
+ return m; // можно обращаться к полям "внешнего" класса
+ }
+ }
+}
+
+// наследование
+class Base {
+ int a = 1;
+ float b = 2.34;
+
+
+ // это статический метод, т.е метод который можно вызывать, обращаясь
+ // к классу напрямую, а не через создание экземпляра объекта
+ static void multiply(int x, int y)
+ {
+ writeln(x * y);
+ }
+}
+
+Base.multiply(2, 5); // используем статический метод. Результат: 10
+
+class Derived : Base {
+ string c = "Поле класса - наследника";
+
+
+ // override означает то, что наследник предоставит свою реализацию метода,
+ // переопределив метод базового класса
+ override static void multiply(int x, int y)
+ {
+ super.multiply(x, y); // super - это ссылка на класс-предок, или базовый класс
+ writeln(x * y * 2);
+ }
+}
+
+auto mc3 = new Derived();
+writeln(mc3.a); // 1
+writeln(mc3.b); // 2.34
+writeln(mc3.c); // Поле класса - наследника
+
+// Финальный класс, наследовать от него нельзя
+// кроме того, модификатор final работает не только для классов, но и для методов
+// и даже для модулей !
+final class FC {
+ int a;
+}
+
+class Derived : FC { // это вызовет ошибку
+ float b;
+}
+
+// Абстрактный класс не может быть истанциирован, но может иметь наследников
+abstract class AC {
+ int a;
+}
+
+auto ac = new AC(); // это вызовет ошибку
+
+class Implementation : AC {
+ float b;
+
+ // final перед методом нефинального класса означает запрет возможности
+ // переопределения метода
+ final void test()
+ {
+ writeln("test passed !");
+ }
+}
+
+auto impl = new Implementation(); // ОК
+
+
+
+/*** Примеси (mixins) ***/
+
+// В D можно вставлять код как строку, если эта строка известна на этапе
+// компиляции. Например:
+void main() {
+ mixin(`writeln("Hello World!");`);
+}
+
+// еще пример
+string print(string s) {
+ return `writeln("` ~ s ~ `");`;
+}
+
+void main() {
+ mixin (print("str1"));
+ mixin (print("str2"));
+}
+
+
+
+/*** Шаблоны ***/
+
+/*
+ Шаблон функции. Эта функция принимает аргументы разных типов, которые
+ подставляются вместо T на этапе компиляции. "T" - это не специальный
+ символ, а просто буква. Вместо "T" может быть любое слово, кроме ключевого.
+ */
+void print(T)(T value) {
+ writefln("%s", value);
+}
+
+void main() {
+ print(42); // В одну и ту же функцию передается: целое
+ print(1.2); // ...число с плавающей точкой,
+ print("test"); // ...строка
+}
+
+// "Шаблонных" параметров может быть сколько угодно
+void print(T1, T2)(T1 value1, T2 value2) {
+ writefln(" %s %s", value1, value2);
+}
+
+void main() {
+ print(42, "Test");
+ print(1.2, 33);
+}
+
+// Шаблон класса
+class Stack(T)
+{
+ private:
+ T[] elements;
+
+ public:
+ void push(T element) {
+ elements ~= element;
+ }
+
+ void pop() {
+ --elements.length;
+ }
+
+ T top() const @property {
+ return elements[$ - 1];
+ }
+
+ size_t length() const @property {
+ return elements.length;
+ }
+}
+
+void main() {
+ /*
+ восклицательный знак - признак шаблона. В данном случае мы создаем
+ класс и указываем, что "шаблонное" поле будет иметь тип string
+ */
+ auto stack = new Stack!string;
+
+ stack.push("Test1");
+ stack.push("Test2");
+
+ writeln(stack.top);
+ writeln(stack.length);
+
+ stack.pop;
+ writeln(stack.top);
+ writeln(stack.length);
+}
+
+
+
+/*** Диапазоны (ranges) ***/
+
+/*
+ Диапазоны - это абстракция, которая позволяет легко использовать разные
+ алгоритмы с разными структурами данных. Вместо того, чтобы определять свои
+ уникальные алгоритмы для каждой структуры, мы можем просто указать для нее
+ несколько единообразных функций, определяющих, _как_ мы получаем доступ
+ к элементам контейнера, вместо того, чтобы описывать внутреннее устройство
+ этого контейнера. Сложно? На самом деле не очень.
+
+ Простейший вид диапазона - Input Range. Для того, чтобы превратить любой
+ контейнер в Input Range, достаточно реализовать для него 3 метода:
+ - empty - проверяет, пуст ли контейнер
+ - front - дает доступ к первому элементу контейнера
+ - popFront - удаляет из контейнера первый элемент
+*/
+struct Student
+{
+ string name;
+ int number;
+ string toString() {
+ return format("%s(%s)", name, number);
+ }
+}
+
+struct School
+{
+ Student[] students;
+}
+
+struct StudentRange
+{
+ Student[] students;
+
+ this(School school) {
+ this.students = school.students;
+ }
+
+ bool empty() {
+ return students.length == 0;
+ }
+
+ Student front() {
+ return students[0];
+ }
+
+ void popFront() {
+ students = students[1 .. $];
+ }
+}
+
+void main(){
+ auto school = School([
+ Student("Mike", 1),
+ Student("John", 2) ,
+ Student("Dan", 3)
+ ]);
+ auto range = StudentRange(school);
+ writeln(range); // [Mike(1), John(2), Dan(3)]
+ writeln(school.students.length); // 3
+ writeln(range.front()); // Mike(1)
+ range.popFront();
+ writeln(range.empty()); // false
+ writeln(range); // [John(2), Dan(3)]
+}
+/*
+ Смысл в том, что нам не так уж важно внутреннее устройство контейнера, если
+ у нас есть унифицированные методы доступа к его элементам.
+ Кроме Input Range в D есть и другие типы диапазонов, которые требуют
+ реализации большего числа методов, зато дают больше контроля. Это большая
+ тема и мы не будем в подробностях освещать ее здесь.
+
+ Диапазоны - это важная часть D, они используются в нем повсеместно.
+*/
+```
+## Что дальше?
+
+- [Официальный сайт](http://dlang.org/)
+- [Онлайн-книга](http://ddili.org/ders/d.en/)
+- [Официальная вики](http://wiki.dlang.org/)