diff options
-rw-r--r-- | CONTRIBUTING.markdown | 8 | ||||
-rw-r--r-- | clojure.html.markdown | 3 | ||||
-rw-r--r-- | de-de/nix-de.html.markdown | 22 | ||||
-rw-r--r-- | lsf/lambda-calculus-lsf.html.markdown | 91 | ||||
-rw-r--r-- | lsf/latex-lsf.html.markdown | 146 | ||||
-rw-r--r-- | pt-br/clojure-pt.html.markdown | 3 | ||||
-rw-r--r-- | pt-br/markdown-pt.html.markdown | 17 | ||||
-rw-r--r-- | pt-br/python3-pt.html.markdown | 36 | ||||
-rw-r--r-- | python3.html.markdown | 10 | ||||
-rw-r--r-- | ru-ru/rust-ru.html.markdown | 6 | ||||
-rw-r--r-- | swift.html.markdown | 56 | ||||
-rw-r--r-- | th-th/typescript.th.html.markdown | 2 | ||||
-rw-r--r-- | typescript.html.markdown | 4 | ||||
-rw-r--r-- | uk-ua/cypher-ua.html.markdown | 254 | ||||
-rw-r--r-- | uk-ua/kotlin-ua.html.markdown | 464 |
15 files changed, 1041 insertions, 81 deletions
diff --git a/CONTRIBUTING.markdown b/CONTRIBUTING.markdown index 79d6838a..18a5a5d7 100644 --- a/CONTRIBUTING.markdown +++ b/CONTRIBUTING.markdown @@ -103,11 +103,3 @@ You can buid the site locally to test your changes. Follow the steps below. these commands at `learnxinyminutes-site/`). * Build - `bundle exec middleman build` * Dev server - `bundle exec middleman --force-polling --verbose` - -## Building the site locally, for Nix users - -You can buid the site locally to test your changes too: - -* Clone or zip download the [learnxinyminutes-site](https://github.com/adambard/learnxinyminutes-site) repo. -* Get the source in place following the instructions above -* Install all site dependencies and start a dev server by running `nix-shell` at the `learnxinyminutes-site/` root directory. diff --git a/clojure.html.markdown b/clojure.html.markdown index c94625d6..16771e25 100644 --- a/clojure.html.markdown +++ b/clojure.html.markdown @@ -416,3 +416,6 @@ Clojuredocs.org has documentation with examples for most core functions: Clojure-doc.org (yes, really) has a number of getting started articles: [http://clojure-doc.org/](http://clojure-doc.org/) + +Clojure for the Brave and True has a great introduction to Clojure and a free online version: +[https://www.braveclojure.com/clojure-for-the-brave-and-true/](https://www.braveclojure.com/clojure-for-the-brave-and-true/) diff --git a/de-de/nix-de.html.markdown b/de-de/nix-de.html.markdown index 79b60d20..ea02e81d 100644 --- a/de-de/nix-de.html.markdown +++ b/de-de/nix-de.html.markdown @@ -8,11 +8,11 @@ translators: lang: de-de --- -Nix ist eine simple funktionale Programmiersprache, die für den +Nix ist eine simple funktionale Programmiersprache, die für den [Nix package manager](https://nixos.org/nix/) und [NixOS](https://nixos.org/) entwickelt wurde. -Du kannst Nix Ausdrücke evaluieren mithilfe von +Du kannst Nix Ausdrücke evaluieren mithilfe von [nix-instantiate](https://nixos.org/nix/manual/#sec-nix-instantiate) oder [`nix-repl`](https://github.com/edolstra/nix-repl). @@ -24,7 +24,7 @@ with builtins; [ # Inline Kommentare sehen so aus. - /* Multizeilen Kommentare + /* Multizeilen Kommentare sehen so aus. */ @@ -61,7 +61,7 @@ with builtins; [ "String Literale sind in Anführungszeichen." " - String Literale können mehrere + String Literale können mehrere Zeilen umspannen. " @@ -95,7 +95,7 @@ with builtins; [ tutorials/learn.nix #=> /the-base-path/tutorials/learn.nix - # Ein Pfad muss mindestens einen Schrägstrich enthalten. Ein Pfad für eine + # Ein Pfad muss mindestens einen Schrägstrich enthalten. Ein Pfad für eine # Datei im selben Verzeichnis benötigt ein ./ Präfix. ./learn.nix #=> /the-base-path/learn.nix @@ -238,7 +238,7 @@ with builtins; [ #=> { d = 2; e = 3; } # Die Nachkommen eines Attributs können in diesem Feld nicht zugeordnet werden, wenn - # das Attribut selbst nicht zugewiesen wurde. + # das Attribut selbst nicht zugewiesen wurde. { a = { b = 1; }; a.c = 2; @@ -261,9 +261,9 @@ with builtins; [ #=> 7 # Die erste Linie diese Tutorials startet mit "with builtins;", - # weil builtins ein Set mit allen eingebauten + # weil builtins ein Set mit allen eingebauten # Funktionen (length, head, tail, filter, etc.) umfasst. - # Das erspart uns beispielsweise "builtins.length" zu schreiben, + # Das erspart uns beispielsweise "builtins.length" zu schreiben, # anstatt nur "length". @@ -305,7 +305,7 @@ with builtins; [ (tryEval (abort "foo")) #=> error: evaluation aborted with the following error message: ‘foo’ - # `assert` evaluiert zu dem gegebenen Wert, wenn die Bedingung wahr ist, sonst + # `assert` evaluiert zu dem gegebenen Wert, wenn die Bedingung wahr ist, sonst # löst es eine abfangbare Exception aus. (assert 1 < 2; 42) #=> 42 @@ -319,7 +319,7 @@ with builtins; [ #========================================= # Da die Wiederholbarkeit von Builds für den Nix Packetmanager entscheidend ist, - # werden in der Nix Sprache reine funktionale Elemente betont. Es gibt aber ein paar + # werden in der Nix Sprache reine funktionale Elemente betont. Es gibt aber ein paar # unreine Elemente. # Du kannst auf Umgebungsvariablen verweisen. (getEnv "HOME") @@ -355,4 +355,4 @@ with builtins; [ (https://medium.com/@MrJamesFisher/nix-by-example-a0063a1a4c55) * [Susan Potter - Nix Cookbook - Nix By Example] - (http://funops.co/nix-cookbook/nix-by-example/) + (https://ops.functionalalgebra.com/nix-by-example/) diff --git a/lsf/lambda-calculus-lsf.html.markdown b/lsf/lambda-calculus-lsf.html.markdown new file mode 100644 index 00000000..88bb638f --- /dev/null +++ b/lsf/lambda-calculus-lsf.html.markdown @@ -0,0 +1,91 @@ +--- +category: Algorithms & Data Structures +name: Lambda Calculus +contributors: + - ["Max Sun", "http://github.com/maxsun"] +translators: + - ["Victore Leve", "https://github.com/AcProIL"] +lang: lsf +--- + +# Calculo λ + +Calculo lambda, creato principto per Alonzo Church, es lingua de programmatura +computatro maximo parvo. Quamquam non habe numero, serie de charactere vel ullo +typo de data non functionale, id pote repraesenta omne machina de Turing. + +Tres elemento compone calculo lambda: **quantitate variabile** (q.v.), +**functione** et **applicatione**. + +| Elemento | Syntaxe | Exemplo | +|----------------------|-----------------------------------|-----------| +| Quantitate variabile | `<nomine>` | `x` | +| Functione | `λ<parametro>.<corpore>` | `λx.x` | +| Applicatione | `<functione><q.v. aut functione>` | `(λx.x)a` | + +Functione fundamentale es identitate: `λx.x` cum argumento primo `x` et cum +corpore secundo `x`. In mathematica, nos scribe `id: x↦x`. + +## Quantitate variabile libero et ligato + +* In functione praecedente, `x` es q.v. ligato nam id es et in copore et + argumento. +* In `λx.y`, `y` es q.v. libero nam non es declarato ante. + +## Valutatione + +Valutatione es facto per reductione beta (reductione β) que es essentialiter +substitutione lexicale. + +Dum valutatione de formula `(λx.x)a`, nos substitue omne evento de `x` in +corpore de functione pro `a`. + +* `(λx.x)a` vale `a` +* `(λx.y)a` vale `y` + +Pote etiam crea functione de ordine supero: `(λx.(λy.x))a` vale `λy.a`. + +Etsi calculo lambda solo tracta functione de uno parametro, nos pote crea +functione cum plure argumento utente methodo de Curry: `λx.(λy.(λz.xyz))` +es scriptura informatica de formula mathematico `f: x, y, z ↦ x(y(z)))`. + +Ergo, interdum, nos ute `λxy.<corpore>` pro `λx.λy.<corpore>`. + +## Arithmetica + +### Logica de Boole + +Es nec numero nec booleano in calculo lambda. + +* «vero» es `v = λx.λy.x` +* «falso» es `f = λx.λy.y` + +Primo, nos pote defini functione «si t tunc a alio b» per `si = λtab.tab`. +Si `t` es vero, valutatione da `(λxy.x) a b` id es `a`. Similiter si `t` es +falso, nos obtine `b`. + +Secundo, nos pote defini operatore de logica: + +* «a et b» es `et = λa.λb.si a b f` +* «a vel b» es `vel = λa.λb.si a t b` +* «non a» es `non = λa.si a f t` + +### Numeros + +Nos pone: + +* `0 = λf.λx.x` (`0: f↦id`) +* `1 = λf.λx.f x` (`1: f↦f`) +* `2 = λf.λx.f(f x)` (`2: f↦f⚬f`) + +Cum mente generale, successore de numero `n` es `S n = λf.λx.f((n f) x)` +(`n+1: f↦f⚬fⁿ`). Id es **`n` est functione que da `fⁿ` ex functione `f`**. + +Postremo additione es `λab.(a S)b` + +## Ut progrede + +### In lingua anglo + +1. [A Tutorial Introduction to the Lambda Calculus](http://www.inf.fu-berlin.de/lehre/WS03/alpi/lambda.pdf) per Raúl Roja +2. [The Lambda Calculus](http://www.cs.cornell.edu/courses/cs3110/2008fa/recitations/rec26.html), CS 312 Recitation 26 diff --git a/lsf/latex-lsf.html.markdown b/lsf/latex-lsf.html.markdown new file mode 100644 index 00000000..18c2e62b --- /dev/null +++ b/lsf/latex-lsf.html.markdown @@ -0,0 +1,146 @@ +--- +language: latex +lang: lsf +contributors: + - ["Chaitanya Krishna Ande", "http://icymist.github.io"] + - ["Colton Kohnke", "http://github.com/voltnor"] + - ["Sricharan Chiruvolu", "http://sricharan.xyz"] +translators: + - ["Victore Leve", "https://github.com/AcProIL"] +filename: learn-latex-lsf.tex +--- + +```tex +% Solo existe commentario monolinea, illo incipe cum charactere % + +% LaTeX non es sicut MS Word aut OpenOffice: que scribe non es que obtine. +% Primo, scribe imperio (que semper incipe cum \) et secundo programma crea +% lima. + +% Nos defini typo de document (id es articulo aut libro aut libello etc.). +% Optione muta quomodo programma age, per exemplo altore de littera. +\documentclass[12pt]{article} + +% Deinde nos lista paccettos que nos vol ute. Es classe de imperio que alio +% utatore e scribe. Pote muta funda, geometria de pagina, etc. vel adde +% functionnalitate. +\usepackage{euler} +\usepackage{graphicx} + +% Ultimo statione ante scribe documento es metadata id es titulo, auctore et +% tempore. Charactere ~ es spatio que non pote es secato. +\title{Disce LaTeX in~Y Minutos!} +\author{Chaitanya Krishna Ande, Colton Kohnke \& Sricharan Chiruvolu} +\date{\today} + +% Principio de documento +\begin{document} + \maketitle % Nos vol adfige metadata. + + % Saepe nos adde breviario us describe texto. + \begin{abstract} + Hic es exmplo de documento sibre cum lingua de LaTeX. + \end{abstract} + + % \section crea sectione cum titulo dato sicut sperato + \section{Introductione} + + Traductione de hic cursu es importante. + + \subsection{Methodo} + Iste parte non es utile. + + \subsubsection{Methodo peculiare} + % \label da nomine ad parte ut post ute imperio de referentia \ref. + \label{subsec:metpec} + + % Cum asteritco nos indice que nos non vol numero ante titulo de sectione. + \section*{Me non aestima numero…} + + …sed de Peano aut de Church. + + \section{Listas} + + Que me debe scribe: + + \begin{enumerate} % `enumerate` designa lista cum numeros contra `itemize`. + \item articulo, + \item libro, + \item cursu. + \end{enumerate} + + \section{Mathematica} + + Methematicas ute multo programma LaTeX ut communica suo decooperito. + Illo necessita symbolo multo instar de logica vel sagitta vel littera cum + accento. + + % Fornula es in linea si nos scribe inter \( et \) (aut duo $) sed magno si + % nos ute \[ et \]. + \(\forall n\in N_0\) % pro omne n in classe N₀ + \[^{3}/_{4} = \frac{3}{4} < 1\] % ¾ < 1 + + Alphabeta graeco contine littera $\alpha$. + + % Ut scribe equatione cum numero et nomine, existe circumiecto `equation`. + \begin{equation} + c^2 = a^2 + b^2 + \label{eq:pythagoras} + \end{equation} + + \begin{equation} + % Summa ab 1 ad n de numeros dimidio de n(n+1) + \sum_{i=1}^n i = \frac{n(n+1)}{2} + \end{equation} + + \section{Figura} + + % Nos adde imagine `right-triangle.png` cum latitudo de quinque centimetro, + % horizontaliter in centro et cum capite «Triangulo recto». + \begin{figure} + \centering + \includegraphics[width=5cm]{right-triangle.png} + \caption{Triangulo recto} + \label{fig:right-triangle} + \end{figure} + + \subsection{Tabula} + + \begin{table} + \caption{Título para la tabla.} + % Argumento de `tabular` es lineamente de columna. + % c: centro, l: sinistra, r: destra, | linea verticale + \begin{tabular}{c|cc} + Numero & B & C \\ + \hline % linea horizontale + 1 & et & aut \\ + 2 & atque & vel + \end{tabular} + \end{table} + + \section{Stylo} + + Texto pote es \textbf{crasso} et \textit{italico}! + + \section{Texto puro} + + % Circumiecto `verbatim` ignora imperio, nos saepe ute id pro monstra + % programma. + \begin{verbatim} +from math import tau, e +print(e ** tau) + \end{verbatim} + + \section{Et plus!} + LaTeX habe facultate crea bibliographia, paritura, scaccarip… cum paccetto + dedicato. +\end{document} +``` + +Imperio ut conge documento es `pdflatex documento` in terminale. + +## Ut progrede + +### In lingua anglo + +* [LaTeX tutorial](http://www.latex-tutorial.com/) per Claudio Vellage diff --git a/pt-br/clojure-pt.html.markdown b/pt-br/clojure-pt.html.markdown index b88d4eec..409394f2 100644 --- a/pt-br/clojure-pt.html.markdown +++ b/pt-br/clojure-pt.html.markdown @@ -382,3 +382,6 @@ Clojuredocs.org tem documentação com exemplos para quase todas as funções pr Clojure-doc.org tem um bom número de artigos para iniciantes: [http://clojure-doc.org/](http://clojure-doc.org/) + +Clojure for the Brave and True é um livro de introdução ao Clojure e possui uma versão gratuita online: +[https://www.braveclojure.com/clojure-for-the-brave-and-true/](https://www.braveclojure.com/clojure-for-the-brave-and-true/) diff --git a/pt-br/markdown-pt.html.markdown b/pt-br/markdown-pt.html.markdown index c2aa515d..1a26e406 100644 --- a/pt-br/markdown-pt.html.markdown +++ b/pt-br/markdown-pt.html.markdown @@ -4,6 +4,7 @@ contributors: - ["Dan Turkel", "http://danturkel.com/"] translators: - ["Miguel Araújo", "https://github.com/miguelarauj1o"] + - ["Monique Baptista", "https://github.com/bfmonique"] lang: pt-br filename: learnmarkdown-pt.md --- @@ -15,19 +16,19 @@ Dê-me feedback tanto quanto você quiser! / Sinta-se livre para a garfar (fork) puxar o projeto (pull request) ```md -<!-- Markdown é um superconjunto do HTML, de modo que qualquer arvquivo HTML é -um arquivo Markdown válido, isso significa que nós podemos usar elementos HTML +<!-- Markdown é um superconjunto do HTML, de modo que qualquer arquivo HTML é +um arquivo Markdown válido. Isso significa que nós podemos usar elementos HTML em Markdown, como o elemento de comentário, e eles não serão afetados pelo analisador de remarcação. No entanto, se você criar um elemento HTML em seu arquivo Markdown, você -não pode usar sintaxe remarcação dentro desse conteúdo do elemento.--> +não pode usar sintaxe de remarcação dentro desse conteúdo do elemento.--> -<!--Markdown também varia de implementação de um analisador para uma próxima. +<!--A maneira como o Markdown é analisado varia de software para software. Este guia vai tentar esclarecer quando as características são universais, ou quando eles são -específico para um determinado parser --> +específico para um determinado interpretador --> <!-- Cabeçalhos --> <!-- Você pode criar elementos HTML <h1> até <h6> facilmente antecedendo o texto -que deseja estar nesse elemento por um número de hashes (#) --> +que deseja estar nesse elemento por um número de cerquilhas (#) --> # Isto é um cabeçalho <h1> ## Isto é um cabeçalho <h2> ### Isto é um cabeçalho <h3> @@ -65,7 +66,7 @@ uma ou múltiplas linhas em branco. --> Este é um parágrafo. Eu estou digitando em um parágrafo, não é legal? -Agora, eu estou no parágrado 2. +Agora, eu estou no parágrafo 2. ... Ainda continuo no parágrafo 2! :) Eu estou no parágrafo três. @@ -111,7 +112,7 @@ ou 1. Item um 2. Item dois -3. Tem três +3. Item três <!-- Você não tem poder para rotular os itens corretamente e a remarcação será ainda tornar os números em ordem, mas isso pode não ser uma boa idéia --> diff --git a/pt-br/python3-pt.html.markdown b/pt-br/python3-pt.html.markdown index b72c732a..bc5f801c 100644 --- a/pt-br/python3-pt.html.markdown +++ b/pt-br/python3-pt.html.markdown @@ -7,15 +7,16 @@ contributors: - ["Zachary Ferguson", "http://github.com/zfergus2"] translators: - ["Paulo Henrique Rodrigues Pinheiro", "http://www.sysincloud.it"] + - ["Monique Baptista", "https://github.com/bfmonique"] lang: pt-br filename: learnpython3-pt.py --- -Python foi criado por Guido Van Rossum nos anos 1990. Ele é atualmente uma -das mais populares linguagens em existência. Eu fiquei morrendo de amor -pelo Python por sua clareza sintática. É praticamente pseudocódigo executável. +Python foi criada por Guido Van Rossum nos anos 1990. Ela é atualmente uma +das linguagens mais populares existentes. Eu me apaixonei por +Python por sua clareza sintática. É praticamente pseudocódigo executável. -Suas opiniões são grandemente apreciadas. Você pode encontrar-me em +Opniões são muito bem vindas. Você pode encontrar-me em [@louiedinh](http://twitter.com/louiedinh) ou louiedinh [em] [serviço de e-mail do google]. @@ -44,7 +45,7 @@ aprender o velho Python 2.7. 8 - 1 # => 7 10 * 2 # => 20 -# Números inteiros por padrão, exceto na divisão, que retorna número +# Números são inteiros por padrão, exceto na divisão, que retorna número # de ponto flutuante (float). 35 / 5 # => 7.0 @@ -64,7 +65,7 @@ aprender o velho Python 2.7. # Exponenciação (x**y, x elevado à potência y) 2**4 # => 16 -# Determine a precedência usando parêntesis +# Determine a precedência usando parênteses (1 + 3) * 2 # => 8 # Valores lógicos são primitivos (Atenção à primeira letra maiúscula) @@ -105,9 +106,8 @@ False or True # => True 1 < 2 < 3 # => True 2 < 3 < 2 # => False -# (operador 'is' e operador '==') is verifica se duas variáveis -# referenciam um mesmo objeto, mas == verifica se as variáveis -# apontam para o mesmo valor. +# 'is' verifica se duas variáveis representam o mesmo endereço +# na memória; '==' verifica se duas variáveis têm o mesmo valor a = [1, 2, 3, 4] # Referência a uma nova lista, [1, 2, 3, 4] b = a # b referencia o que está referenciado por a b is a # => True, a e b referenciam o mesmo objeto @@ -174,7 +174,7 @@ input_string_var = input("Digite alguma coisa: ") # Retorna o que foi digitado e # Observação: Em versões antigas do Python, o método input() era chamado raw_input() # Não é necessário declarar variáveis antes de iniciá-las -# È uma convenção usar letras_minúsculas_com_sublinhados +# É uma convenção usar letras_minúsculas_com_sublinhados alguma_variavel = 5 alguma_variavel # => 5 @@ -182,31 +182,31 @@ alguma_variavel # => 5 # Veja Controle de Fluxo para aprender mais sobre tratamento de exceções. alguma_variavel_nao_inicializada # Gera a exceção NameError -# Listas armazenam sequencias +# Listas armazenam sequências li = [] -# Você pode iniciar com uma lista com alguns valores +# Você pode iniciar uma lista com valores outra_li = [4, 5, 6] -# Adicionar conteúdo ao fim da lista com append +# Adicione conteúdo ao fim da lista com append li.append(1) # li agora é [1] li.append(2) # li agora é [1, 2] li.append(4) # li agora é [1, 2, 4] li.append(3) # li agora é [1, 2, 4, 3] -# Remover do final da lista com pop +# Remova do final da lista com pop li.pop() # => 3 e agora li é [1, 2, 4] # Vamos colocá-lo lá novamente! li.append(3) # li agora é [1, 2, 4, 3] novamente. -# Acessar uma lista da mesma forma que você faz com um array +# Acesse uma lista da mesma forma que você faz com um array li[0] # => 1 -# Acessa o último elemento +# Acessando o último elemento li[-1] # => 3 -# Acessando além dos limites gera um IndexError +# Acessar além dos limites gera um IndexError li[4] # Gera o IndexError # Você pode acessar vários elementos com a sintaxe de limites -# (É um limite fechado, aberto pra você que gosta de matemática.) +# Inclusivo para o primeiro termo, exclusivo para o segundo li[1:3] # => [2, 4] # Omitindo o final li[2:] # => [4, 3] diff --git a/python3.html.markdown b/python3.html.markdown index 430927a9..61c53408 100644 --- a/python3.html.markdown +++ b/python3.html.markdown @@ -550,8 +550,14 @@ next(our_iterator) # => "three" # After the iterator has returned all of its data, it raises a StopIteration exception next(our_iterator) # Raises StopIteration -# You can grab all the elements of an iterator by calling list() on it. -list(filled_dict.keys()) # => Returns ["one", "two", "three"] +# We can also loop over it, in fact, "for" does this implicitly! +our_iterator = iter(our_iterable) +for i in our_iterator: + print(i) # Prints one, two, three + +# You can grab all the elements of an iterable or iterator by calling list() on it. +list(our_iterable) # => Returns ["one", "two", "three"] +list(our_iterator) # => Returns [] because state is saved #################################################### diff --git a/ru-ru/rust-ru.html.markdown b/ru-ru/rust-ru.html.markdown index 7bd2809a..16b635f0 100644 --- a/ru-ru/rust-ru.html.markdown +++ b/ru-ru/rust-ru.html.markdown @@ -130,7 +130,7 @@ fn main() { // 2. Типы // ////////////// - // Struct + // Структура struct Point { x: i32, y: i32, @@ -175,7 +175,7 @@ fn main() { // Методы // impl<T> Foo<T> { - fn get_bar(self) -> T { + fn get_bar(self) -> T { self.bar } } @@ -233,7 +233,7 @@ fn main() { println!("{}", i); } - // Отрезки + // Диапазоны for i in 0u32..10 { print!("{} ", i); } diff --git a/swift.html.markdown b/swift.html.markdown index c2fb3471..1f9fe897 100644 --- a/swift.html.markdown +++ b/swift.html.markdown @@ -91,7 +91,7 @@ let multiLineString = """ This is a multi-line string. It's called that because it takes up multiple lines (wow!) Any indentation beyond the closing quotation marks is kept, the rest is discarded. - You can include " or "" in multi-line strings because the delimeter is three "s. + You can include " or "" in multi-line strings because the delimiter is three "s. """ // Arrays @@ -159,12 +159,12 @@ let `class` = "keyword" or contains nil (no value) to indicate that a value is missing. Nil is roughly equivalent to `null` in other languages. A question mark (?) after the type marks the value as optional of that type. - + If a type is not optional, it is guaranteed to have a value. - + Because Swift requires every property to have a type, even nil must be explicitly stored as an Optional value. - + Optional<T> is an enum, with the cases .none (nil) and .some(T) (the value) */ @@ -178,7 +178,7 @@ let someOptionalString4 = String?.none //nil To access the value of an optional that has a value, use the postfix operator !, which force-unwraps it. Force-unwrapping is like saying, "I know that this optional definitely has a value, please give it to me." - + Trying to use ! to access a non-existent optional value triggers a runtime error. Always make sure that an optional contains a non-nil value before using ! to force-unwrap its value. @@ -194,7 +194,7 @@ if someOptionalString != nil { // Swift supports "optional chaining," which means that you can call functions // or get properties of optional values and they are optionals of the appropriate type. // You can even do this multiple times, hence the name "chaining." - + let empty = someOptionalString?.isEmpty // Bool? // if-let structure - @@ -370,7 +370,7 @@ func say(_ message: String) { } say("Hello") -// Default parameters can be ommitted when calling the function. +// Default parameters can be omitted when calling the function. func printParameters(requiredParameter r: Int, optionalParameter o: Int = 10) { print("The required parameter was \(r) and the optional parameter was \(o)") } @@ -443,7 +443,7 @@ func testGuard() { return // guard statements MUST exit the scope that they are in. // They generally use `return` or `throw`. } - + print("number is \(aNumber)") } testGuard() @@ -564,7 +564,7 @@ enum Furniture { case desk(height: Int) // Associate with String and Int case chair(String, Int) - + func description() -> String { //either placement of let is acceptable switch self { @@ -591,15 +591,15 @@ print(chair.description()) // "Chair of Foo with 40 cm" - Define initializers to set up their initial state - Be extended to expand their functionality beyond a default implementation - Conform to protocols to provide standard functionality of a certain kind - + Classes have additional capabilities that structures don't have: - Inheritance enables one class to inherit the characteristics of another. - Type casting enables you to check and interpret the type of a class instance at runtime. - Deinitializers enable an instance of a class to free up any resources it has assigned. - Reference counting allows more than one reference to a class instance. - + Unless you need to use a class for one of these reasons, use a struct. - + Structures are value types, while classes are reference types. */ @@ -607,7 +607,7 @@ print(chair.description()) // "Chair of Foo with 40 cm" struct NamesTable { let names: [String] - + // Custom subscript subscript(index: Int) -> String { return names[index] @@ -629,7 +629,7 @@ class Shape { class Rect: Shape { var sideLength: Int = 1 - + // Custom getter and setter property var perimeter: Int { get { @@ -640,16 +640,16 @@ class Rect: Shape { sideLength = newValue / 4 } } - + // Computed properties must be declared as `var`, you know, cause' they can change var smallestSideLength: Int { return self.sideLength - 1 } - + // Lazily load a property // subShape remains nil (uninitialized) until getter called lazy var subShape = Rect(sideLength: 4) - + // If you don't need a custom getter and setter, // but still want to run code before and after getting or setting // a property, you can use `willSet` and `didSet` @@ -659,19 +659,19 @@ class Rect: Shape { print(someIdentifier) } } - + init(sideLength: Int) { self.sideLength = sideLength // always super.init last when init custom properties super.init() } - + func shrink() { if sideLength > 0 { sideLength -= 1 } } - + override func getArea() -> Int { return sideLength * sideLength } @@ -703,13 +703,13 @@ class Circle: Shape { override func getArea() -> Int { return 3 * radius * radius } - + // Place a question mark postfix after `init` is an optional init // which can return nil init?(radius: Int) { self.radius = radius super.init() - + if radius <= 0 { return nil } @@ -813,7 +813,7 @@ for _ in 0..<10 { - Internal: Accessible and subclassible in the module it is declared in. - Fileprivate: Accessible and subclassible in the file it is declared in. - Private: Accessible and subclassible in the enclosing declaration (think inner classes/structs/enums) - + See more here: https://docs.swift.org/swift-book/LanguageGuide/AccessControl.html */ @@ -878,11 +878,11 @@ extension Int { var doubled: Int { return self * 2 } - + func multipliedBy(num: Int) -> Int { return num * self } - + mutating func multiplyBy(num: Int) { self *= num } @@ -965,18 +965,18 @@ func fakeFetch(value: Int) throws -> String { guard 7 == value else { throw MyError.reallyBadValue(msg: "Some really bad value") } - + return "test" } func testTryStuff() { // assumes there will be no error thrown, otherwise a runtime exception is raised let _ = try! fakeFetch(value: 7) - + // if an error is thrown, then it proceeds, but if the value is nil // it also wraps every return value in an optional, even if its already optional let _ = try? fakeFetch(value: 7) - + do { // normal try operation that provides error handling via `catch` block try fakeFetch(value: 1) diff --git a/th-th/typescript.th.html.markdown b/th-th/typescript.th.html.markdown index fc2a823b..5395c2a7 100644 --- a/th-th/typescript.th.html.markdown +++ b/th-th/typescript.th.html.markdown @@ -190,7 +190,7 @@ interface Person { } var p1: Person = { name: "Tyrone", age: 42 }; -p1.age = 25; // Error แน่นอน เพราะ p1.x ถูกกำหนดเป็น read-only +p1.age = 25; // Error แน่นอน เพราะ p1.age ถูกกำหนดเป็น read-only var p2 = { name: "John", age: 60 }; // สังเกตว่า p2 ไม่ได้กำหนดเป็น Person var p3: Person = p2; // ทำได้ เป็น read-only alias ของ p2 และกำหนดเป็น Person diff --git a/typescript.html.markdown b/typescript.html.markdown index cf2111d5..00f0cbc5 100644 --- a/typescript.html.markdown +++ b/typescript.html.markdown @@ -16,7 +16,7 @@ This article will focus only on TypeScript extra syntax, as opposed to [JavaScript](/docs/javascript). To test TypeScript's compiler, head to the -[Playground] (http://www.typescriptlang.org/Playground) where you will be able +[Playground](https://www.typescriptlang.org/play) where you will be able to type code, have auto completion and directly see the emitted JavaScript. ```ts @@ -199,7 +199,7 @@ interface Person { } var p1: Person = { name: "Tyrone", age: 42 }; -p1.age = 25; // Error, p1.x is read-only +p1.age = 25; // Error, p1.age is read-only var p2 = { name: "John", age: 60 }; var p3: Person = p2; // Ok, read-only alias for p2 diff --git a/uk-ua/cypher-ua.html.markdown b/uk-ua/cypher-ua.html.markdown new file mode 100644 index 00000000..e1eef5a2 --- /dev/null +++ b/uk-ua/cypher-ua.html.markdown @@ -0,0 +1,254 @@ +--- +language: cypher +filename: LearnCypher.cql +contributors: + - ["Théo Gauchoux", "https://github.com/TheoGauchoux"] +translators: + - ["AstiaSun", "https://github.com/AstiaSun"] +lang: uk-ua +--- + +Cypher - це мова запитів Neo4j для спрощення роботи з графами. Вона повторює синтаксис SQL та перемішує його з таким собі ascii стилем для відображення структури графа. +Цей навчальний матеріал передбачає, що ви вже знайомі із концепцією графів, зобрема що таке вершини та зв'язки між ними. + +[Деталі тут](https://neo4j.com/developer/cypher-query-language/) + + +Вершини +--- + +**Відображує запис у графі.** + +`()` +Таким чином у запиті позначається пуста *вершина*. Використовується зазвичай для того, щоб позначити, що вона є, проте це не так вже й важливо для запиту. + +`(n)` +Це вершина, яка має назву **n**, до неї можна повторно звертатись у запиті. Звернення до вершини **n** починається з нижнього підкреслення та використовує camelCase (верблюжий регіст). + +`(p:Person)` +Можна також додати *ярлик* до вершини, в данному випадку - **Person**. Це як тип / клас / категорія. Назва *ярлика* починається з великої літери та використовує верблюжу нотацію. + +`(p:Person:Manager)` +Вершина може мати кілька *ярликів*. + +`(p:Person {name : 'Théo Gauchoux', age : 22})` +Вершина також може мати різні *властивості*, в данному випадку - **name** та **age**. Також мають починатися з великої літери та використовувати верблюжу нотацію. + +Наступні типи дозволяється використовувати у властивостях: + + - Чиселиний + - Булевий + - Рядок + - Списки попередніх примітивних типів + +*Увага! В Cypher не існує типу, що відображає час. Замість нього можна використовувати рядок із визначеним шаблоном або чисельне відображення певної дати.* + +`p.name` +За допомогою крапки можна звернутись до властивості вершини. + + +Зв'язки (або ребра) +--- + +**Сполучають дві вершини** + +`[:KNOWS]` +Це *зв'язок* з *ярликом* **KNOWS**. Це такий же самий *ярлик* як і у вершини. Починається з великої літери та використовує ВЕРХНІЙ\_РЕГІСТР\_ІЗ\_ЗМІЇНОЮ\_НОТАЦІЄЮ. + +`[k:KNOWS]` +Це той же самий *зв'язок*, до якого можна звертатись через змінну **k**. Можна подалі використовувати у запиті, хоч це і не обов'язково. + +`[k:KNOWS {since:2017}]` +Той же *зв'язок*, але вже із *властивостями* (як у *вершини*), в данному випадку властивість - це **since**. + +`[k:KNOWS*..4]` +Це структурна інформація, яку використовують *шляхи*, які розглянуті нижче. В данному випадку, **\*..4** говорить: "Сумістити шаблон із зв'язком **k**, що повторюватиметься від одного до чотирьох разів." + + +Шляхи +--- + +**Спосіб поєднувати вершини та зв'язки.** + +`(a:Person)-[:KNOWS]-(b:Person)` +Шлях описує, що вершини **a** та **b** знають (knows) один одного. + +`(a:Person)-[:MANAGES]->(b:Person)` +Шлях може бути направленим. Цей описує, що **а** є менеджером **b**. + +`(a:Person)-[:KNOWS]-(b:Person)-[:KNOWS]-(c:Person)` +Можна створювати ланцюги зі зв'язків. Цей шлях описує друга друга (**a** знає **b**, який в свою чергу знає **c**). + +`(a:Person)-[:MANAGES]->(b:Person)-[:MANAGES]->(c:Person)` +Ланцюг, аналогічно, також може бути направленим. Шлях описує, що **a** - бос **b** і супер бос для **c**. + +Шаблони, які часто використовуються (з документації Neo4j): + +``` +// Друг-мого-друга +(user)-[:KNOWS]-(friend)-[:KNOWS]-(foaf) + +// Найкоротший шлях +path = shortestPath( (user)-[:KNOWS*..5]-(other) ) + +// Спільна фільтрація +(user)-[:PURCHASED]->(product)<-[:PURCHASED]-()-[:PURCHASED]->(otherProduct) + +// Навігація по дереву +(root)<-[:PARENT*]-(leaf:Category)-[:ITEM]->(data:Product) + +``` + + +Запити на створення +--- + +Створити нову вершину: +``` +CREATE (a:Person {name:"Théo Gauchoux"}) +RETURN a +``` +*`RETURN` дозволяє повернути результат після виконання запиту. Можна повертати кілька значень, наприклад, `RETURN a, b`.* + +Створити новий зв'язок (із двома вершинами): +``` +CREATE (a:Person)-[k:KNOWS]-(b:Person) +RETURN a,k,b +``` + +Запити на знаходження +--- + +Знайти всі вершини: +``` +MATCH (n) +RETURN n +``` + +Знайти вершини за ярликом: +``` +MATCH (a:Person) +RETURN a +``` + +Знайти вершини за ярликом та властивістю: +``` +MATCH (a:Person {name:"Théo Gauchoux"}) +RETURN a +``` + +Знайти вершини відповідно до зв'язків (ненаправлених): +``` +MATCH (a)-[:KNOWS]-(b) +RETURN a,b +``` + +Знайти вершини відповідно до зв'язків (направлених): +``` +MATCH (a)-[:MANAGES]->(b) +RETURN a,b +``` + +Знайти вершини за допомогою `WHERE`: +``` +MATCH (p:Person {name:"Théo Gauchoux"})-[s:LIVES_IN]->(city:City) +WHERE s.since = 2015 +RETURN p,state +``` + +Можна використовувати вираз `MATCH WHERE` разом із операцією `CREATE`: +``` +MATCH (a), (b) +WHERE a.name = "Jacquie" AND b.name = "Michel" +CREATE (a)-[:KNOWS]-(b) +``` + + +Запити на оновлення +--- + +Оновити окрему властивість вершини: +``` +MATCH (p:Person) +WHERE p.name = "Théo Gauchoux" +SET p.age = 23 +``` + +Оновити всі властивості вершини: +``` +MATCH (p:Person) +WHERE p.name = "Théo Gauchoux" +SET p = {name: "Michel", age: 23} +``` + +Додати нову властивіcть до вершини: +``` +MATCH (p:Person) +WHERE p.name = "Théo Gauchoux" +SET p + = {studies: "IT Engineering"} +``` + +Повісити ярлик на вершину: +``` +MATCH (p:Person) +WHERE p.name = "Théo Gauchoux" +SET p:Internship +``` + + +Запити на видалення +--- + +Видалити окрему вершину (пов'язані ребра повинні бути видалені перед цим): +``` +MATCH (p:Person)-[relationship]-() +WHERE p.name = "Théo Gauchoux" +DELETE relationship, p +``` + +Видалити властивість певної вершини: +``` +MATCH (p:Person) +WHERE p.name = "Théo Gauchoux" +REMOVE p.age +``` + +*Зверніть увагу, що ключове слово `REMOVE` це не те саме, що й `DELETE`!* + +Видалити ярлик певної вершини: +``` +MATCH (p:Person) +WHERE p.name = "Théo Gauchoux" +DELETE p:Person +``` + +Видалити всю базу даних: +``` +MATCH (n) +OPTIONAL MATCH (n)-[r]-() +DELETE n, r +``` + +*Так, це `rm -rf /` на мові Cypher !* + + +Інші корисні запити +--- + +`PROFILE` +Перед виконанням, показати план виконання запитів. + +`COUNT(e)` +Порахувати елементи (вершини та зв'язки), що відповідають **e**. + +`LIMIT x` +Обмежити результат до x перших результатів. + + +Особливі підказки +--- + +- У мові Cypher існують лише однорядкові коментарі, що позначаються двійним слешем : // Коментар +- Можна виконати скрипт Cypher, збережений у файлі **.cql** прямо в Neo4j (прямо як імпорт). Проте, не можна мати мати кілька виразів в цьому файлі (розділених **;**). +- Використовуйте командний рядок Neo4j для написання запитів Cypher, це легко і швидко. +- Cypher планує бути стандартною мовою запитів для всіх графових баз даних (більш відома як **OpenCypher**). diff --git a/uk-ua/kotlin-ua.html.markdown b/uk-ua/kotlin-ua.html.markdown new file mode 100644 index 00000000..5e79cc48 --- /dev/null +++ b/uk-ua/kotlin-ua.html.markdown @@ -0,0 +1,464 @@ +--- +language: kotlin +filename: LearnKotlin-uk.kt +lang: uk-ua +contributors: + - ["S Webber", "https://github.com/s-webber"] +translators: + - ["AstiaSun", "https://github.com/AstiaSun"] +--- + +Kotlin - це мова програмування зі статичною типізацією для JVM, Android та браузера. +Вона має 100% сумісність із Java. + +[Детальніше](https://kotlinlang.org/) + +```kotlin +// Однорядкові коментарі починаються з // +/* +Такий вигляд мають багаторядкові коментарі +*/ + +// Ключове слово package працює так само, як і в Java. +package com.learnxinyminutes.kotlin + +/* +Точкою входу для програм на Kotlin є функція під назвою main. +Вона приймає масив із аргументів, що були передані через командний рядок. +Починаючи з Kotlin 1.3, функція main може бути оголошена без параметрів взагалі. +*/ +fun main(args: Array<String>) { + /* + Оголошення змінних відбувається за допомогою ключових слів var або val. + Відмінність між ними полягає в тому, що значення змінних, оголошених через + val, не можна змінювати. Водночас, змінній "var" можна переприсвоїти нове + значення в подальшому. + */ + val fooVal = 10 // більше ми не можемо змінити значення fooVal на інше + var fooVar = 10 + fooVar = 20 // fooVar може змінювати значення + + /* + В більшості випадків Kotlin може визначати, якого типу змінна, тому не + потрібно щоразу точно вказувати її тип. + Тип змінної вказується наступним чином: + */ + val foo: Int = 7 + + /* + Рядки мають аналогічне з Java представлення. Спеціальні символи + позначаються за допомогою зворотнього слеша. + */ + val fooString = "My String Is Here!" + val barString = "Printing on a new line?\nNo Problem!" + val bazString = "Do you want to add a tab?\tNo Problem!" + println(fooString) + println(barString) + println(bazString) + + /* + Необроблений рядок розмежовується за допомогою потрійних лапок ("""). + Необроблені рядки можуть містити переніс рядка (не спеціальний символ \n) та + будь-які інші символи. + */ + val fooRawString = """ +fun helloWorld(val name : String) { + println("Hello, world!") +} +""" + println(fooRawString) + + /* + Рядки можуть містити шаблонні вирази. + Шаблонний вираз починається із символа доллара "$". + */ + val fooTemplateString = "$fooString has ${fooString.length} characters" + println(fooTemplateString) // => My String Is Here! has 18 characters + + /* + Щоб змінна могла мати значення null, потрібно це додатково вказати. + Для цього після оголошеного типу змінної додається спеціальний символ "?". + Отримати значення такої змінної можна використавши оператор "?.". + Оператор "?:" застосовується, щоб оголосити альтернативне значення змінної + у випадку, якщо вона буде рівна null. + */ + var fooNullable: String? = "abc" + println(fooNullable?.length) // => 3 + println(fooNullable?.length ?: -1) // => 3 + fooNullable = null + println(fooNullable?.length) // => null + println(fooNullable?.length ?: -1) // => -1 + + /* + Функції оголошуються з використанням ключового слова fun. + Аргументи функції перелічуються у круглих дужках після назви функції. + Аргументи можуть мати значення за замовчуванням. Тип значення, що повертатиметься + функцією, вказується після оголошення аргументів за необхідністю. + */ + fun hello(name: String = "world"): String { + return "Hello, $name!" + } + println(hello("foo")) // => Hello, foo! + println(hello(name = "bar")) // => Hello, bar! + println(hello()) // => Hello, world! + + /* + Аргументи функції можуть бути помічені ключовим словом vararg. Це дозволяє + приймати довільну кількість аргументів функції зазначеного типу. + */ + fun varargExample(vararg names: Int) { + println("Argument has ${names.size} elements") + } + varargExample() // => Argument has 0 elements + varargExample(1) // => Argument has 1 elements + varargExample(1, 2, 3) // => Argument has 3 elements + + /* + Коли функція складається з одного виразу, фігурні дужки не є обов'язковими. + Тіло функції вказується після оператора "=". + */ + fun odd(x: Int): Boolean = x % 2 == 1 + println(odd(6)) // => false + println(odd(7)) // => true + + // Якщо тип значення, що повертається функцією, може бути однозначно визначено, + // його непотрібно вказувати. + fun even(x: Int) = x % 2 == 0 + println(even(6)) // => true + println(even(7)) // => false + + // Функції можуть приймати інші функції як аргументи, а також повертати інші функції. + fun not(f: (Int) -> Boolean): (Int) -> Boolean { + return {n -> !f.invoke(n)} + } + // Іменовані функції можуть бути вказані як аргументи за допомогою оператора "::". + val notOdd = not(::odd) + val notEven = not(::even) + // Лямбда-вирази також можуть бути аргументами функції. + val notZero = not {n -> n == 0} + /* + Якщо лямбда-вираз приймає лише один параметр, його оголошення може бути пропущене + (разом із ->). Всередині виразу до цього параметра можна звернутись через + змінну "it". + */ + val notPositive = not {it > 0} + for (i in 0..4) { + println("${notOdd(i)} ${notEven(i)} ${notZero(i)} ${notPositive(i)}") + } + + // Ключове слово class використовується для оголошення класів. + class ExampleClass(val x: Int) { + fun memberFunction(y: Int): Int { + return x + y + } + + infix fun infixMemberFunction(y: Int): Int { + return x * y + } + } + /* + Щоб створити новий об'єкт, потрібно викликати конструктор класу. + Зазначте, що в Kotlin немає ключового слова new. + */ + val fooExampleClass = ExampleClass(7) + // Методи класу викликаються через крапку. + println(fooExampleClass.memberFunction(4)) // => 11 + /* + Якщо функція була позначена ключовим словом infix, тоді її можна викликати через + інфіксну нотацію. + */ + println(fooExampleClass infixMemberFunction 4) // => 28 + + /* + Класи даних - це лаконічний спосіб створювати класи, що містимуть тільки дані. + Методи "hashCode"/"equals" та "toString" автоматично генеруються. + */ + data class DataClassExample (val x: Int, val y: Int, val z: Int) + val fooData = DataClassExample(1, 2, 4) + println(fooData) // => DataClassExample(x=1, y=2, z=4) + + // Класи даних також мають функцію "copy". + val fooCopy = fooData.copy(y = 100) + println(fooCopy) // => DataClassExample(x=1, y=100, z=4) + + // Об'єкти можуть бути деструктурувані кількома способами. + val (a, b, c) = fooCopy + println("$a $b $c") // => 1 100 4 + + // деструктурування у циклі for + for ((a, b, c) in listOf(fooData)) { + println("$a $b $c") // => 1 100 4 + } + + val mapData = mapOf("a" to 1, "b" to 2) + // Map.Entry також деструктурувуються + for ((key, value) in mapData) { + println("$key -> $value") + } + + // Функція із "with" працює майже так само як це ж твердження у JavaScript. + data class MutableDataClassExample (var x: Int, var y: Int, var z: Int) + val fooMutableData = MutableDataClassExample(7, 4, 9) + with (fooMutableData) { + x -= 2 + y += 2 + z-- + } + println(fooMutableData) // => MutableDataClassExample(x=5, y=6, z=8) + + /* + Список можна створити використовуючи функцію listOf. + Список буде незмінним, тобто елементи не можна буде додавати або видаляти. + */ + val fooList = listOf("a", "b", "c") + println(fooList.size) // => 3 + println(fooList.first()) // => a + println(fooList.last()) // => c + // доступ до елементів здійснюється через їхні порядковий номер. + println(fooList[1]) // => b + + // Змінні списки можна створити використовуючи функцію mutableListOf. + val fooMutableList = mutableListOf("a", "b", "c") + fooMutableList.add("d") + println(fooMutableList.last()) // => d + println(fooMutableList.size) // => 4 + + // Функція setOf створює об'єкт типу множина. + val fooSet = setOf("a", "b", "c") + println(fooSet.contains("a")) // => true + println(fooSet.contains("z")) // => false + + // mapOf створює асоціативний масив. + val fooMap = mapOf("a" to 8, "b" to 7, "c" to 9) + // Доступ до значень в асоціативних масивах здійснюється через їхні ключі. + println(fooMap["a"]) // => 8 + + /* + Послідовності представлені як колекції лінивих обчислень. Функція generateSequence + створює послідовність. + */ + val fooSequence = generateSequence(1, { it + 1 }) + val x = fooSequence.take(10).toList() + println(x) // => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + + // Приклад використання послідовностей, генерація чисел Фібоначчі: + fun fibonacciSequence(): Sequence<Long> { + var a = 0L + var b = 1L + + fun next(): Long { + val result = a + b + a = b + b = result + return a + } + + return generateSequence(::next) + } + val y = fibonacciSequence().take(10).toList() + println(y) // => [1, 1, 2, 3, 5, 8, 13, 21, 34, 55] + + // Kotlin має функції вищого порядку для роботи з колекціями. + val z = (1..9).map {it * 3} + .filter {it < 20} + .groupBy {it % 2 == 0} + .mapKeys {if (it.key) "even" else "odd"} + println(z) // => {odd=[3, 9, 15], even=[6, 12, 18]} + + // Цикл for може використовуватись з будь-чим, що має ітератор. + for (c in "hello") { + println(c) + } + + // Принцип роботи циклів "while" не відрізняється від інших мов програмування. + var ctr = 0 + while (ctr < 5) { + println(ctr) + ctr++ + } + do { + println(ctr) + ctr++ + } while (ctr < 10) + + /* + if може бути використаний як вираз, що повертає значення. Тому тернарний + оператор ?: не потрібний в Kotlin. + */ + val num = 5 + val message = if (num % 2 == 0) "even" else "odd" + println("$num is $message") // => 5 is odd + + // "when" використовується як альтернатива ланцюгам "if-else if". + val i = 10 + when { + i < 7 -> println("first block") + fooString.startsWith("hello") -> println("second block") + else -> println("else block") + } + + // "when" може приймати аргумент. + when (i) { + 0, 21 -> println("0 or 21") + in 1..20 -> println("in the range 1 to 20") + else -> println("none of the above") + } + + // "when" також може використовуватись як функція, що повертає значення. + var result = when (i) { + 0, 21 -> "0 or 21" + in 1..20 -> "in the range 1 to 20" + else -> "none of the above" + } + println(result) + + /* + Тип об'єкта можна перевірити використавши оператор is. Якщо перевірка проходить + успішно, тоді можна використовувати об'єкт як данний тип не приводячи до нього + додатково. + */ + fun smartCastExample(x: Any) : Boolean { + if (x is Boolean) { + // x тепер має тип Boolean + return x + } else if (x is Int) { + // x тепер має тип Int + return x > 0 + } else if (x is String) { + // x тепер має тип String + return x.isNotEmpty() + } else { + return false + } + } + println(smartCastExample("Hello, world!")) // => true + println(smartCastExample("")) // => false + println(smartCastExample(5)) // => true + println(smartCastExample(0)) // => false + println(smartCastExample(true)) // => true + + // Smartcast (розумне приведення) також працює з блоком when + fun smartCastWhenExample(x: Any) = when (x) { + is Boolean -> x + is Int -> x > 0 + is String -> x.isNotEmpty() + else -> false + } + + /* + Розширення - це ще один спосіб розширити функціонал класу. + Подібні методи розширення реалізовані у С#. + */ + fun String.remove(c: Char): String { + return this.filter {it != c} + } + println("Hello, world!".remove('l')) // => Heo, word! +} + +// Класи перелічення також подібні до тих типів, що і в Java. +enum class EnumExample { + A, B, C // Константи перелічення розділені комами. +} +fun printEnum() = println(EnumExample.A) // => A + +// Оскільки кожне перелічення - це об'єкт класу enum, воно може бути +// проініціалізоване наступним чином: +enum class EnumExample(val value: Int) { + A(value = 1), + B(value = 2), + C(value = 3) +} +fun printProperty() = println(EnumExample.A.value) // => 1 + +// Кожне перелічення має властивості, які дозволяють отримати його ім'я +// та порядок (позицію) в класі enum: +fun printName() = println(EnumExample.A.name) // => A +fun printPosition() = println(EnumExample.A.ordinal) // => 0 + +/* +Ключове слово object можна використати для створення об'єкту сінглтону. Об'єкт не +можна інстанціювати, проте на його унікальний екземпляр можна посилатись за іменем. +Подібна можливість є в сінглтон об'єктах у Scala. +*/ +object ObjectExample { + fun hello(): String { + return "hello" + } + + override fun toString(): String { + return "Hello, it's me, ${ObjectExample::class.simpleName}" + } +} + + +fun useSingletonObject() { + println(ObjectExample.hello()) // => hello + // В Kotlin, "Any" - це корінь ієрархії класів, так само, як і "Object" у Java. + val someRef: Any = ObjectExample + println(someRef) // => Hello, it's me, ObjectExample +} + + +/* +Оператор перевірки на те, що об'єкт не рівний null, (!!) перетворює будь-яке значення в ненульовий тип і кидає виняток, якщо значення рівне null. +*/ +var b: String? = "abc" +val l = b!!.length + +// Далі - приклади перевизначення методів класу Any в класі-насліднику +data class Counter(var value: Int) { + // перевизначити Counter += Int + operator fun plusAssign(increment: Int) { + this.value += increment + } + + // перевизначити Counter++ та ++Counter + operator fun inc() = Counter(value + 1) + + // перевизначити Counter + Counter + operator fun plus(other: Counter) = Counter(this.value + other.value) + + // перевизначити Counter * Counter + operator fun times(other: Counter) = Counter(this.value * other.value) + + // перевизначити Counter * Int + operator fun times(value: Int) = Counter(this.value * value) + + // перевизначити Counter in Counter + operator fun contains(other: Counter) = other.value == this.value + + // перевизначити Counter[Int] = Int + operator fun set(index: Int, value: Int) { + this.value = index + value + } + + // перевизначити виклик екземпляру Counter + operator fun invoke() = println("The value of the counter is $value") + +} +// Можна також перевизначити оператори через методи розширення. +// перевизначити -Counter +operator fun Counter.unaryMinus() = Counter(-this.value) + +fun operatorOverloadingDemo() { + var counter1 = Counter(0) + var counter2 = Counter(5) + counter1 += 7 + println(counter1) // => Counter(value=7) + println(counter1 + counter2) // => Counter(value=12) + println(counter1 * counter2) // => Counter(value=35) + println(counter2 * 2) // => Counter(value=10) + println(counter1 in Counter(5)) // => false + println(counter1 in Counter(7)) // => true + counter1[26] = 10 + println(counter1) // => Counter(value=36) + counter1() // => The value of the counter is 36 + println(-counter2) // => Counter(value=-5) +} +``` + +### Подальше вивчення + +* [Уроки Kotlin](https://kotlinlang.org/docs/tutorials/) +* [Спробувати попрацювати з Kotlin в браузері](https://play.kotlinlang.org/) +* [Список корисних посилань](http://kotlin.link/) |