mirror of
https://github.com/adambard/learnxinyminutes-docs.git
synced 2025-04-27 07:33:57 +00:00
commit
92fe4d2579
@ -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:
|
Clojure-doc.org (yes, really) has a number of getting started articles:
|
||||||
[http://clojure-doc.org/](http://clojure-doc.org/)
|
[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/)
|
||||||
|
@ -8,11 +8,11 @@ translators:
|
|||||||
lang: de-de
|
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
|
[Nix package manager](https://nixos.org/nix/) und
|
||||||
[NixOS](https://nixos.org/) entwickelt wurde.
|
[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)
|
[nix-instantiate](https://nixos.org/nix/manual/#sec-nix-instantiate)
|
||||||
oder [`nix-repl`](https://github.com/edolstra/nix-repl).
|
oder [`nix-repl`](https://github.com/edolstra/nix-repl).
|
||||||
|
|
||||||
@ -24,7 +24,7 @@ with builtins; [
|
|||||||
|
|
||||||
# Inline Kommentare sehen so aus.
|
# Inline Kommentare sehen so aus.
|
||||||
|
|
||||||
/* Multizeilen Kommentare
|
/* Multizeilen Kommentare
|
||||||
sehen so aus. */
|
sehen so aus. */
|
||||||
|
|
||||||
|
|
||||||
@ -61,7 +61,7 @@ with builtins; [
|
|||||||
"String Literale sind in Anführungszeichen."
|
"String Literale sind in Anführungszeichen."
|
||||||
|
|
||||||
"
|
"
|
||||||
String Literale können mehrere
|
String Literale können mehrere
|
||||||
Zeilen umspannen.
|
Zeilen umspannen.
|
||||||
"
|
"
|
||||||
|
|
||||||
@ -95,7 +95,7 @@ with builtins; [
|
|||||||
tutorials/learn.nix
|
tutorials/learn.nix
|
||||||
#=> /the-base-path/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.
|
# Datei im selben Verzeichnis benötigt ein ./ Präfix.
|
||||||
./learn.nix
|
./learn.nix
|
||||||
#=> /the-base-path/learn.nix
|
#=> /the-base-path/learn.nix
|
||||||
@ -238,7 +238,7 @@ with builtins; [
|
|||||||
#=> { d = 2; e = 3; }
|
#=> { d = 2; e = 3; }
|
||||||
|
|
||||||
# Die Nachkommen eines Attributs können in diesem Feld nicht zugeordnet werden, wenn
|
# 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 = { b = 1; };
|
||||||
a.c = 2;
|
a.c = 2;
|
||||||
@ -261,9 +261,9 @@ with builtins; [
|
|||||||
#=> 7
|
#=> 7
|
||||||
|
|
||||||
# Die erste Linie diese Tutorials startet mit "with builtins;",
|
# 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.
|
# 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".
|
# anstatt nur "length".
|
||||||
|
|
||||||
|
|
||||||
@ -305,7 +305,7 @@ with builtins; [
|
|||||||
(tryEval (abort "foo"))
|
(tryEval (abort "foo"))
|
||||||
#=> error: evaluation aborted with the following error message: ‘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.
|
# löst es eine abfangbare Exception aus.
|
||||||
(assert 1 < 2; 42)
|
(assert 1 < 2; 42)
|
||||||
#=> 42
|
#=> 42
|
||||||
@ -319,7 +319,7 @@ with builtins; [
|
|||||||
#=========================================
|
#=========================================
|
||||||
|
|
||||||
# Da die Wiederholbarkeit von Builds für den Nix Packetmanager entscheidend ist,
|
# 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.
|
# unreine Elemente.
|
||||||
# Du kannst auf Umgebungsvariablen verweisen.
|
# Du kannst auf Umgebungsvariablen verweisen.
|
||||||
(getEnv "HOME")
|
(getEnv "HOME")
|
||||||
@ -355,4 +355,4 @@ with builtins; [
|
|||||||
(https://medium.com/@MrJamesFisher/nix-by-example-a0063a1a4c55)
|
(https://medium.com/@MrJamesFisher/nix-by-example-a0063a1a4c55)
|
||||||
|
|
||||||
* [Susan Potter - Nix Cookbook - Nix By Example]
|
* [Susan Potter - Nix Cookbook - Nix By Example]
|
||||||
(http://funops.co/nix-cookbook/nix-by-example/)
|
(https://ops.functionalalgebra.com/nix-by-example/)
|
||||||
|
@ -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:
|
Clojure-doc.org tem um bom número de artigos para iniciantes:
|
||||||
[http://clojure-doc.org/](http://clojure-doc.org/)
|
[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/)
|
||||||
|
@ -4,6 +4,7 @@ contributors:
|
|||||||
- ["Dan Turkel", "http://danturkel.com/"]
|
- ["Dan Turkel", "http://danturkel.com/"]
|
||||||
translators:
|
translators:
|
||||||
- ["Miguel Araújo", "https://github.com/miguelarauj1o"]
|
- ["Miguel Araújo", "https://github.com/miguelarauj1o"]
|
||||||
|
- ["Monique Baptista", "https://github.com/bfmonique"]
|
||||||
lang: pt-br
|
lang: pt-br
|
||||||
filename: learnmarkdown-pt.md
|
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)
|
puxar o projeto (pull request)
|
||||||
|
|
||||||
```md
|
```md
|
||||||
<!-- Markdown é um superconjunto do HTML, de modo que qualquer arvquivo 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
|
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
|
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ê
|
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
|
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 -->
|
<!-- Cabeçalhos -->
|
||||||
<!-- Você pode criar elementos HTML <h1> até <h6> facilmente antecedendo o texto
|
<!-- 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 <h1>
|
||||||
## Isto é um cabeçalho <h2>
|
## Isto é um cabeçalho <h2>
|
||||||
### Isto é um cabeçalho <h3>
|
### 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?
|
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! :)
|
... Ainda continuo no parágrafo 2! :)
|
||||||
|
|
||||||
Eu estou no parágrafo três.
|
Eu estou no parágrafo três.
|
||||||
@ -111,7 +112,7 @@ ou
|
|||||||
|
|
||||||
1. Item um
|
1. Item um
|
||||||
2. Item dois
|
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
|
<!-- 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 -->
|
tornar os números em ordem, mas isso pode não ser uma boa idéia -->
|
||||||
|
@ -7,15 +7,16 @@ contributors:
|
|||||||
- ["Zachary Ferguson", "http://github.com/zfergus2"]
|
- ["Zachary Ferguson", "http://github.com/zfergus2"]
|
||||||
translators:
|
translators:
|
||||||
- ["Paulo Henrique Rodrigues Pinheiro", "http://www.sysincloud.it"]
|
- ["Paulo Henrique Rodrigues Pinheiro", "http://www.sysincloud.it"]
|
||||||
|
- ["Monique Baptista", "https://github.com/bfmonique"]
|
||||||
lang: pt-br
|
lang: pt-br
|
||||||
filename: learnpython3-pt.py
|
filename: learnpython3-pt.py
|
||||||
---
|
---
|
||||||
|
|
||||||
Python foi criado por Guido Van Rossum nos anos 1990. Ele é atualmente uma
|
Python foi criada por Guido Van Rossum nos anos 1990. Ela é atualmente uma
|
||||||
das mais populares linguagens em existência. Eu fiquei morrendo de amor
|
das linguagens mais populares existentes. Eu me apaixonei por
|
||||||
pelo Python por sua clareza sintática. É praticamente pseudocódigo executável.
|
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]
|
[@louiedinh](http://twitter.com/louiedinh) ou louiedinh [em]
|
||||||
[serviço de e-mail do google].
|
[serviço de e-mail do google].
|
||||||
|
|
||||||
@ -44,7 +45,7 @@ aprender o velho Python 2.7.
|
|||||||
8 - 1 # => 7
|
8 - 1 # => 7
|
||||||
10 * 2 # => 20
|
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).
|
# de ponto flutuante (float).
|
||||||
35 / 5 # => 7.0
|
35 / 5 # => 7.0
|
||||||
|
|
||||||
@ -64,7 +65,7 @@ aprender o velho Python 2.7.
|
|||||||
# Exponenciação (x**y, x elevado à potência y)
|
# Exponenciação (x**y, x elevado à potência y)
|
||||||
2**4 # => 16
|
2**4 # => 16
|
||||||
|
|
||||||
# Determine a precedência usando parêntesis
|
# Determine a precedência usando parênteses
|
||||||
(1 + 3) * 2 # => 8
|
(1 + 3) * 2 # => 8
|
||||||
|
|
||||||
# Valores lógicos são primitivos (Atenção à primeira letra maiúscula)
|
# Valores lógicos são primitivos (Atenção à primeira letra maiúscula)
|
||||||
@ -105,9 +106,8 @@ False or True # => True
|
|||||||
1 < 2 < 3 # => True
|
1 < 2 < 3 # => True
|
||||||
2 < 3 < 2 # => False
|
2 < 3 < 2 # => False
|
||||||
|
|
||||||
# (operador 'is' e operador '==') is verifica se duas variáveis
|
# 'is' verifica se duas variáveis representam o mesmo endereço
|
||||||
# referenciam um mesmo objeto, mas == verifica se as variáveis
|
# na memória; '==' verifica se duas variáveis têm o mesmo valor
|
||||||
# apontam para o mesmo valor.
|
|
||||||
a = [1, 2, 3, 4] # Referência a uma nova lista, [1, 2, 3, 4]
|
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 = a # b referencia o que está referenciado por a
|
||||||
b is a # => True, a e b referenciam o mesmo objeto
|
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()
|
# 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
|
# 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
|
||||||
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.
|
# Veja Controle de Fluxo para aprender mais sobre tratamento de exceções.
|
||||||
alguma_variavel_nao_inicializada # Gera a exceção NameError
|
alguma_variavel_nao_inicializada # Gera a exceção NameError
|
||||||
|
|
||||||
# Listas armazenam sequencias
|
# Listas armazenam sequências
|
||||||
li = []
|
li = []
|
||||||
# Você pode iniciar com uma lista com alguns valores
|
# Você pode iniciar uma lista com valores
|
||||||
outra_li = [4, 5, 6]
|
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(1) # li agora é [1]
|
||||||
li.append(2) # li agora é [1, 2]
|
li.append(2) # li agora é [1, 2]
|
||||||
li.append(4) # li agora é [1, 2, 4]
|
li.append(4) # li agora é [1, 2, 4]
|
||||||
li.append(3) # li agora é [1, 2, 4, 3]
|
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]
|
li.pop() # => 3 e agora li é [1, 2, 4]
|
||||||
# Vamos colocá-lo lá novamente!
|
# Vamos colocá-lo lá novamente!
|
||||||
li.append(3) # li agora é [1, 2, 4, 3] 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
|
li[0] # => 1
|
||||||
# Acessa o último elemento
|
# Acessando o último elemento
|
||||||
li[-1] # => 3
|
li[-1] # => 3
|
||||||
|
|
||||||
# Acessando além dos limites gera um IndexError
|
# Acessar além dos limites gera um IndexError
|
||||||
li[4] # Gera o IndexError
|
li[4] # Gera o IndexError
|
||||||
|
|
||||||
# Você pode acessar vários elementos com a sintaxe de limites
|
# 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]
|
li[1:3] # => [2, 4]
|
||||||
# Omitindo o final
|
# Omitindo o final
|
||||||
li[2:] # => [4, 3]
|
li[2:] # => [4, 3]
|
||||||
|
@ -550,8 +550,14 @@ next(our_iterator) # => "three"
|
|||||||
# After the iterator has returned all of its data, it raises a StopIteration exception
|
# After the iterator has returned all of its data, it raises a StopIteration exception
|
||||||
next(our_iterator) # Raises StopIteration
|
next(our_iterator) # Raises StopIteration
|
||||||
|
|
||||||
# You can grab all the elements of an iterator by calling list() on it.
|
# We can also loop over it, in fact, "for" does this implicitly!
|
||||||
list(filled_dict.keys()) # => Returns ["one", "two", "three"]
|
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
|
||||||
|
|
||||||
|
|
||||||
####################################################
|
####################################################
|
||||||
|
@ -91,7 +91,7 @@ let multiLineString = """
|
|||||||
This is a multi-line string.
|
This is a multi-line string.
|
||||||
It's called that because it takes up multiple lines (wow!)
|
It's called that because it takes up multiple lines (wow!)
|
||||||
Any indentation beyond the closing quotation marks is kept, the rest is discarded.
|
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
|
// Arrays
|
||||||
@ -159,12 +159,12 @@ let `class` = "keyword"
|
|||||||
or contains nil (no value) to indicate that a value is missing.
|
or contains nil (no value) to indicate that a value is missing.
|
||||||
Nil is roughly equivalent to `null` in other languages.
|
Nil is roughly equivalent to `null` in other languages.
|
||||||
A question mark (?) after the type marks the value as optional of that type.
|
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.
|
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
|
Because Swift requires every property to have a type, even nil must be
|
||||||
explicitly stored as an Optional value.
|
explicitly stored as an Optional value.
|
||||||
|
|
||||||
Optional<T> is an enum, with the cases .none (nil) and .some(T) (the 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
|
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
|
operator !, which force-unwraps it. Force-unwrapping is like saying, "I
|
||||||
know that this optional definitely has a value, please give it to me."
|
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
|
Trying to use ! to access a non-existent optional value triggers a
|
||||||
runtime error. Always make sure that an optional contains a non-nil
|
runtime error. Always make sure that an optional contains a non-nil
|
||||||
value before using ! to force-unwrap its value.
|
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
|
// 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.
|
// 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."
|
// You can even do this multiple times, hence the name "chaining."
|
||||||
|
|
||||||
let empty = someOptionalString?.isEmpty // Bool?
|
let empty = someOptionalString?.isEmpty // Bool?
|
||||||
|
|
||||||
// if-let structure -
|
// if-let structure -
|
||||||
@ -370,7 +370,7 @@ func say(_ message: String) {
|
|||||||
}
|
}
|
||||||
say("Hello")
|
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) {
|
func printParameters(requiredParameter r: Int, optionalParameter o: Int = 10) {
|
||||||
print("The required parameter was \(r) and the optional parameter was \(o)")
|
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.
|
return // guard statements MUST exit the scope that they are in.
|
||||||
// They generally use `return` or `throw`.
|
// They generally use `return` or `throw`.
|
||||||
}
|
}
|
||||||
|
|
||||||
print("number is \(aNumber)")
|
print("number is \(aNumber)")
|
||||||
}
|
}
|
||||||
testGuard()
|
testGuard()
|
||||||
@ -564,7 +564,7 @@ enum Furniture {
|
|||||||
case desk(height: Int)
|
case desk(height: Int)
|
||||||
// Associate with String and Int
|
// Associate with String and Int
|
||||||
case chair(String, Int)
|
case chair(String, Int)
|
||||||
|
|
||||||
func description() -> String {
|
func description() -> String {
|
||||||
//either placement of let is acceptable
|
//either placement of let is acceptable
|
||||||
switch self {
|
switch self {
|
||||||
@ -591,15 +591,15 @@ print(chair.description()) // "Chair of Foo with 40 cm"
|
|||||||
- Define initializers to set up their initial state
|
- Define initializers to set up their initial state
|
||||||
- Be extended to expand their functionality beyond a default implementation
|
- Be extended to expand their functionality beyond a default implementation
|
||||||
- Conform to protocols to provide standard functionality of a certain kind
|
- Conform to protocols to provide standard functionality of a certain kind
|
||||||
|
|
||||||
Classes have additional capabilities that structures don't have:
|
Classes have additional capabilities that structures don't have:
|
||||||
- Inheritance enables one class to inherit the characteristics of another.
|
- 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.
|
- 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.
|
- 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.
|
- 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.
|
Unless you need to use a class for one of these reasons, use a struct.
|
||||||
|
|
||||||
Structures are value types, while classes are reference types.
|
Structures are value types, while classes are reference types.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -607,7 +607,7 @@ print(chair.description()) // "Chair of Foo with 40 cm"
|
|||||||
|
|
||||||
struct NamesTable {
|
struct NamesTable {
|
||||||
let names: [String]
|
let names: [String]
|
||||||
|
|
||||||
// Custom subscript
|
// Custom subscript
|
||||||
subscript(index: Int) -> String {
|
subscript(index: Int) -> String {
|
||||||
return names[index]
|
return names[index]
|
||||||
@ -629,7 +629,7 @@ class Shape {
|
|||||||
|
|
||||||
class Rect: Shape {
|
class Rect: Shape {
|
||||||
var sideLength: Int = 1
|
var sideLength: Int = 1
|
||||||
|
|
||||||
// Custom getter and setter property
|
// Custom getter and setter property
|
||||||
var perimeter: Int {
|
var perimeter: Int {
|
||||||
get {
|
get {
|
||||||
@ -640,16 +640,16 @@ class Rect: Shape {
|
|||||||
sideLength = newValue / 4
|
sideLength = newValue / 4
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Computed properties must be declared as `var`, you know, cause' they can change
|
// Computed properties must be declared as `var`, you know, cause' they can change
|
||||||
var smallestSideLength: Int {
|
var smallestSideLength: Int {
|
||||||
return self.sideLength - 1
|
return self.sideLength - 1
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lazily load a property
|
// Lazily load a property
|
||||||
// subShape remains nil (uninitialized) until getter called
|
// subShape remains nil (uninitialized) until getter called
|
||||||
lazy var subShape = Rect(sideLength: 4)
|
lazy var subShape = Rect(sideLength: 4)
|
||||||
|
|
||||||
// If you don't need a custom getter and setter,
|
// If you don't need a custom getter and setter,
|
||||||
// but still want to run code before and after getting or setting
|
// but still want to run code before and after getting or setting
|
||||||
// a property, you can use `willSet` and `didSet`
|
// a property, you can use `willSet` and `didSet`
|
||||||
@ -659,19 +659,19 @@ class Rect: Shape {
|
|||||||
print(someIdentifier)
|
print(someIdentifier)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
init(sideLength: Int) {
|
init(sideLength: Int) {
|
||||||
self.sideLength = sideLength
|
self.sideLength = sideLength
|
||||||
// always super.init last when init custom properties
|
// always super.init last when init custom properties
|
||||||
super.init()
|
super.init()
|
||||||
}
|
}
|
||||||
|
|
||||||
func shrink() {
|
func shrink() {
|
||||||
if sideLength > 0 {
|
if sideLength > 0 {
|
||||||
sideLength -= 1
|
sideLength -= 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override func getArea() -> Int {
|
override func getArea() -> Int {
|
||||||
return sideLength * sideLength
|
return sideLength * sideLength
|
||||||
}
|
}
|
||||||
@ -703,13 +703,13 @@ class Circle: Shape {
|
|||||||
override func getArea() -> Int {
|
override func getArea() -> Int {
|
||||||
return 3 * radius * radius
|
return 3 * radius * radius
|
||||||
}
|
}
|
||||||
|
|
||||||
// Place a question mark postfix after `init` is an optional init
|
// Place a question mark postfix after `init` is an optional init
|
||||||
// which can return nil
|
// which can return nil
|
||||||
init?(radius: Int) {
|
init?(radius: Int) {
|
||||||
self.radius = radius
|
self.radius = radius
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
if radius <= 0 {
|
if radius <= 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -813,7 +813,7 @@ for _ in 0..<10 {
|
|||||||
- Internal: Accessible and subclassible in the module it is declared in.
|
- Internal: Accessible and subclassible in the module it is declared in.
|
||||||
- Fileprivate: Accessible and subclassible in the file 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)
|
- 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
|
See more here: https://docs.swift.org/swift-book/LanguageGuide/AccessControl.html
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -878,11 +878,11 @@ extension Int {
|
|||||||
var doubled: Int {
|
var doubled: Int {
|
||||||
return self * 2
|
return self * 2
|
||||||
}
|
}
|
||||||
|
|
||||||
func multipliedBy(num: Int) -> Int {
|
func multipliedBy(num: Int) -> Int {
|
||||||
return num * self
|
return num * self
|
||||||
}
|
}
|
||||||
|
|
||||||
mutating func multiplyBy(num: Int) {
|
mutating func multiplyBy(num: Int) {
|
||||||
self *= num
|
self *= num
|
||||||
}
|
}
|
||||||
@ -965,18 +965,18 @@ func fakeFetch(value: Int) throws -> String {
|
|||||||
guard 7 == value else {
|
guard 7 == value else {
|
||||||
throw MyError.reallyBadValue(msg: "Some really bad value")
|
throw MyError.reallyBadValue(msg: "Some really bad value")
|
||||||
}
|
}
|
||||||
|
|
||||||
return "test"
|
return "test"
|
||||||
}
|
}
|
||||||
|
|
||||||
func testTryStuff() {
|
func testTryStuff() {
|
||||||
// assumes there will be no error thrown, otherwise a runtime exception is raised
|
// assumes there will be no error thrown, otherwise a runtime exception is raised
|
||||||
let _ = try! fakeFetch(value: 7)
|
let _ = try! fakeFetch(value: 7)
|
||||||
|
|
||||||
// if an error is thrown, then it proceeds, but if the value is nil
|
// 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
|
// it also wraps every return value in an optional, even if its already optional
|
||||||
let _ = try? fakeFetch(value: 7)
|
let _ = try? fakeFetch(value: 7)
|
||||||
|
|
||||||
do {
|
do {
|
||||||
// normal try operation that provides error handling via `catch` block
|
// normal try operation that provides error handling via `catch` block
|
||||||
try fakeFetch(value: 1)
|
try fakeFetch(value: 1)
|
||||||
|
@ -190,7 +190,7 @@ interface Person {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var p1: Person = { name: "Tyrone", age: 42 };
|
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 p2 = { name: "John", age: 60 }; // สังเกตว่า p2 ไม่ได้กำหนดเป็น Person
|
||||||
var p3: Person = p2; // ทำได้ เป็น read-only alias ของ p2 และกำหนดเป็น Person
|
var p3: Person = p2; // ทำได้ เป็น read-only alias ของ p2 และกำหนดเป็น Person
|
||||||
|
@ -199,7 +199,7 @@ interface Person {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var p1: Person = { name: "Tyrone", age: 42 };
|
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 p2 = { name: "John", age: 60 };
|
||||||
var p3: Person = p2; // Ok, read-only alias for p2
|
var p3: Person = p2; // Ok, read-only alias for p2
|
||||||
|
254
uk-ua/cypher-ua.html.markdown
Normal file
254
uk-ua/cypher-ua.html.markdown
Normal file
@ -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**).
|
464
uk-ua/kotlin-ua.html.markdown
Normal file
464
uk-ua/kotlin-ua.html.markdown
Normal file
@ -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/)
|
Loading…
Reference in New Issue
Block a user