mirror of
https://github.com/adambard/learnxinyminutes-docs.git
synced 2024-12-23 15:24:09 +03:00
Merge branch 'master' of https://github.com/adambard/learnxinyminutes-docs
This commit is contained in:
commit
6f2003a31f
@ -161,7 +161,7 @@ function arithmetic_functions(a, b, c, d) {
|
||||
# Most AWK implementations have some standard trig functions
|
||||
localvar = sin(a)
|
||||
localvar = cos(a)
|
||||
localvar = atan2(a, b) # arc tangent of b / a
|
||||
localvar = atan2(b, a) # arc tangent of b / a
|
||||
|
||||
# And logarithmic stuff
|
||||
localvar = exp(a)
|
||||
|
@ -74,7 +74,7 @@ echo ${Variable/Some/A} # => A string
|
||||
|
||||
# Substring from a variable
|
||||
Length=7
|
||||
echo ${Variable:0:Length} # => Some st
|
||||
echo ${Variable:0:$Length} # => Some st
|
||||
# This will return only the first 7 characters of the value
|
||||
|
||||
# Default value for variable
|
||||
|
@ -100,7 +100,7 @@ writeln(varCmdLineArg, ", ", constCmdLineArg, ", ", paramCmdLineArg);
|
||||
// be made to alias a variable other than the variable it is initialized with.
|
||||
// Here, refToActual refers to actual.
|
||||
var actual = 10;
|
||||
ref refToActual = actual;
|
||||
ref refToActual = actual;
|
||||
writeln(actual, " == ", refToActual); // prints the same value
|
||||
actual = -123; // modify actual (which refToActual refers to)
|
||||
writeln(actual, " == ", refToActual); // prints the same value
|
||||
@ -444,7 +444,7 @@ arrayFromLoop = [value in arrayFromLoop] value + 1;
|
||||
|
||||
// Procedures
|
||||
|
||||
// Chapel procedures have similar syntax functions in other languages.
|
||||
// Chapel procedures have similar syntax functions in other languages.
|
||||
proc fibonacci(n : int) : int {
|
||||
if n <= 1 then return n;
|
||||
return fibonacci(n-1) + fibonacci(n-2);
|
||||
@ -893,7 +893,6 @@ foo();
|
||||
// We can declare a main procedure, but all the code above main still gets
|
||||
// executed.
|
||||
proc main() {
|
||||
writeln("PARALLELISM START");
|
||||
|
||||
// A begin statement will spin the body of that statement off
|
||||
// into one new task.
|
||||
@ -1141,11 +1140,13 @@ to see if more topics have been added or more tutorials created.
|
||||
Your input, questions, and discoveries are important to the developers!
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
The Chapel language is still in-development (version 1.16.0), so there are
|
||||
The Chapel language is still in active development, so there are
|
||||
occasional hiccups with performance and language features. The more information
|
||||
you give the Chapel development team about issues you encounter or features you
|
||||
would like to see, the better the language becomes. Feel free to email the team
|
||||
and other developers through the [sourceforge email lists](https://sourceforge.net/p/chapel/mailman).
|
||||
would like to see, the better the language becomes.
|
||||
There are several ways to interact with the developers:
|
||||
+ [Gitter chat](https://gitter.im/chapel-lang/chapel)
|
||||
+ [sourceforge email lists](https://sourceforge.net/p/chapel/mailman)
|
||||
|
||||
If you're really interested in the development of the compiler or contributing
|
||||
to the project, [check out the master GitHub repository](https://github.com/chapel-lang/chapel).
|
||||
@ -1154,12 +1155,14 @@ It is under the [Apache 2.0 License](http://www.apache.org/licenses/LICENSE-2.0)
|
||||
Installing the Compiler
|
||||
-----------------------
|
||||
|
||||
[The Official Chapel documentation details how to download and compile the Chapel compiler.](https://chapel-lang.org/docs/usingchapel/QUICKSTART.html)
|
||||
|
||||
Chapel can be built and installed on your average 'nix machine (and cygwin).
|
||||
[Download the latest release version](https://github.com/chapel-lang/chapel/releases/)
|
||||
and it's as easy as
|
||||
|
||||
1. `tar -xvf chapel-1.16.0.tar.gz`
|
||||
2. `cd chapel-1.16.0`
|
||||
1. `tar -xvf chapel-<VERSION>.tar.gz`
|
||||
2. `cd chapel-<VERSION>`
|
||||
3. `source util/setchplenv.bash # or .sh or .csh or .fish`
|
||||
4. `make`
|
||||
5. `make check # optional`
|
||||
|
@ -166,7 +166,7 @@ function arithmetic_functions(a, b, c, localvar) {
|
||||
# trigonométricas estándar
|
||||
localvar = sin(a)
|
||||
localvar = cos(a)
|
||||
localvar = atan2(a, b) # arcotangente de b / a
|
||||
localvar = atan2(b, a) # arcotangente de b / a
|
||||
|
||||
# Y cosas logarítmicas
|
||||
localvar = exp(a)
|
||||
|
@ -306,7 +306,7 @@ module DataTypeExamples =
|
||||
|
||||
// ------------------------------------
|
||||
// Union types (aka variants) have a set of choices
|
||||
// Only case can be valid at a time.
|
||||
// Only one case can be valid at a time.
|
||||
// ------------------------------------
|
||||
|
||||
// Use "type" with bar/pipe to define a union type
|
||||
|
@ -3,13 +3,14 @@ language: Julia
|
||||
contributors:
|
||||
- ["Leah Hanson", "http://leahhanson.us"]
|
||||
- ["Pranit Bauva", "http://github.com/pranitbauva1997"]
|
||||
- ["Daniel YC Lin", "http://github.com/dlintw"]
|
||||
filename: learnjulia.jl
|
||||
---
|
||||
|
||||
Julia is a new homoiconic functional language focused on technical computing.
|
||||
While having the full power of homoiconic macros, first-class functions, and low-level control, Julia is as easy to learn and use as Python.
|
||||
|
||||
This is based on Julia 0.4.
|
||||
This is based on Julia 0.6.4
|
||||
|
||||
```ruby
|
||||
|
||||
@ -49,7 +50,7 @@ div(5, 2) # => 2 # for a truncated result, use div
|
||||
~2 # => -3 # bitwise not
|
||||
3 & 5 # => 1 # bitwise and
|
||||
2 | 4 # => 6 # bitwise or
|
||||
2 $ 4 # => 6 # bitwise xor
|
||||
xor(2, 4) # => 6 # bitwise xor
|
||||
2 >>> 1 # => 1 # logical shift right
|
||||
2 >> 1 # => 1 # arithmetic shift right
|
||||
2 << 1 # => 4 # logical/arithmetic shift left
|
||||
@ -80,25 +81,33 @@ false
|
||||
2 < 3 < 2 # => false
|
||||
|
||||
# Strings are created with "
|
||||
try
|
||||
"This is a string."
|
||||
catch ; end
|
||||
|
||||
# Julia has several types of strings, including ASCIIString and UTF8String.
|
||||
# More on this in the Types section.
|
||||
|
||||
# Character literals are written with '
|
||||
try
|
||||
'a'
|
||||
catch ; end
|
||||
|
||||
# Some strings can be indexed like an array of characters
|
||||
try
|
||||
"This is a string"[1] # => 'T' # Julia indexes from 1
|
||||
catch ; end
|
||||
# However, this is will not work well for UTF8 strings,
|
||||
# so iterating over strings is recommended (map, for loops, etc).
|
||||
|
||||
# $ can be used for string interpolation:
|
||||
try
|
||||
"2 + 2 = $(2 + 2)" # => "2 + 2 = 4"
|
||||
catch ; end
|
||||
# You can put any Julia expression inside the parentheses.
|
||||
|
||||
# Another way to format strings is the printf macro.
|
||||
@printf "%d is less than %f" 4.5 5.3 # 4.5 is less than 5.300000
|
||||
@printf "%d is less than %f" 4.5 5.3 # 4 is less than 5.300000
|
||||
|
||||
# Printing is easy
|
||||
println("I'm Julia. Nice to meet you!")
|
||||
@ -405,8 +414,8 @@ f_add(x, y) = x + y # => "f (generic function with 1 method)"
|
||||
f_add(3, 4) # => 7
|
||||
|
||||
# Function can also return multiple values as tuple
|
||||
f(x, y) = x + y, x - y
|
||||
f(3, 4) # => (7, -1)
|
||||
fn(x, y) = x + y, x - y
|
||||
fn(3, 4) # => (7, -1)
|
||||
|
||||
# You can define functions that take a variable number of
|
||||
# positional arguments
|
||||
@ -543,7 +552,7 @@ sherekhan = typeof(tigger)(5.6,"fire") # => Tiger(5.6,"fire")
|
||||
# The other kind of types is abstract types.
|
||||
|
||||
# abstract Name
|
||||
abstract Cat # just a name and point in the type hierarchy
|
||||
abstract type Cat end # just a name and point in the type hierarchy
|
||||
|
||||
# Abstract types cannot be instantiated, but can have subtypes.
|
||||
# For example, Number is an abstract type
|
||||
@ -553,30 +562,28 @@ subtypes(Number) # => 2-element Array{Any,1}:
|
||||
subtypes(Cat) # => 0-element Array{Any,1}
|
||||
|
||||
# AbstractString, as the name implies, is also an abstract type
|
||||
subtypes(AbstractString) # 8-element Array{Any,1}:
|
||||
# Base.SubstitutionString{T<:AbstractString}
|
||||
# DirectIndexString
|
||||
# RepString
|
||||
# RevString{T<:AbstractString}
|
||||
# RopeString
|
||||
# SubString{T<:AbstractString}
|
||||
# UTF16String
|
||||
# UTF8String
|
||||
subtypes(AbstractString) # 6-element Array{Union{DataType, UnionAll},1}:
|
||||
# Base.SubstitutionString
|
||||
# Base.Test.GenericString
|
||||
# DirectIndexString
|
||||
# RevString
|
||||
# String
|
||||
# SubString
|
||||
|
||||
# Every type has a super type; use the `super` function to get it.
|
||||
# Every type has a super type; use the `supertype` function to get it.
|
||||
typeof(5) # => Int64
|
||||
super(Int64) # => Signed
|
||||
super(Signed) # => Integer
|
||||
super(Integer) # => Real
|
||||
super(Real) # => Number
|
||||
super(Number) # => Any
|
||||
super(super(Signed)) # => Real
|
||||
super(Any) # => Any
|
||||
supertype(Int64) # => Signed
|
||||
supertype(Signed) # => Integer
|
||||
supertype(Integer) # => Real
|
||||
supertype(Real) # => Number
|
||||
supertype(Number) # => Any
|
||||
supertype(supertype(Signed)) # => Real
|
||||
supertype(Any) # => Any
|
||||
# All of these type, except for Int64, are abstract.
|
||||
typeof("fire") # => ASCIIString
|
||||
super(ASCIIString) # => DirectIndexString
|
||||
super(DirectIndexString) # => AbstractString
|
||||
# Likewise here with ASCIIString
|
||||
typeof("fire") # => String
|
||||
supertype(String) # => AbstractString
|
||||
# Likewise here with String
|
||||
supertype(DirectIndexString) # => AbstractString
|
||||
|
||||
# <: is the subtyping operator
|
||||
type Lion <: Cat # Lion is a subtype of Cat
|
||||
@ -670,23 +677,22 @@ fight(l::Lion,c::Cat) = println("The victorious cat says $(meow(c))")
|
||||
|
||||
fight(Lion("balooga!"),Panther()) # => prints The victorious cat says grrr
|
||||
try
|
||||
fight(Panther(),Lion("RAWR")) # => ERROR: no method fight(Panther,Lion)
|
||||
catch
|
||||
fight(Panther(),Lion("RAWR"))
|
||||
catch e
|
||||
println(e)
|
||||
# => MethodError(fight, (Panther("green"), Lion("green", "RAWR")), 0x000000000000557b)
|
||||
end
|
||||
|
||||
# Also let the cat go first
|
||||
fight(c::Cat,l::Lion) = println("The cat beats the Lion")
|
||||
# => Warning: New definition
|
||||
# fight(Cat,Lion) at none:1
|
||||
# is ambiguous with
|
||||
# fight(Lion,Cat) at none:2.
|
||||
# Make sure
|
||||
# fight(Lion,Lion)
|
||||
# is defined first.
|
||||
#fight (generic function with 4 methods)
|
||||
|
||||
# This warning is because it's unclear which fight will be called in:
|
||||
fight(Lion("RAR"),Lion("brown","rarrr")) # => prints The victorious cat says rarrr
|
||||
try
|
||||
fight(Lion("RAR"),Lion("brown","rarrr")) # => prints The victorious cat says rarrr
|
||||
catch e
|
||||
println(e)
|
||||
# => MethodError(fight, (Lion("green", "RAR"), Lion("brown", "rarrr")), 0x000000000000557c)
|
||||
end
|
||||
# The result may be different in other versions of Julia
|
||||
|
||||
fight(l::Lion,l2::Lion) = println("The lions come to a tie")
|
||||
|
@ -3,6 +3,7 @@ category: Algorithms & Data Structures
|
||||
name: Lambda Calculus
|
||||
contributors:
|
||||
- ["Max Sun", "http://github.com/maxsun"]
|
||||
- ["Yan Hui Hang", "http://github.com/yanhh0"]
|
||||
---
|
||||
|
||||
# Lambda Calculus
|
||||
@ -114,8 +115,100 @@ Using successor, we can define add:
|
||||
|
||||
**Challenge:** try defining your own multiplication function!
|
||||
|
||||
## Get even smaller: SKI, SK and Iota
|
||||
|
||||
### SKI Combinator Calculus
|
||||
|
||||
Let S, K, I be the following functions:
|
||||
|
||||
`I x = x`
|
||||
|
||||
`K x y = x`
|
||||
|
||||
`S x y z = x z (y z)`
|
||||
|
||||
We can convert an expression in the lambda calculus to an expression
|
||||
in the SKI combinator calculus:
|
||||
|
||||
1. `λx.x = I`
|
||||
2. `λx.c = Kc`
|
||||
3. `λx.(y z) = S (λx.y) (λx.z)`
|
||||
|
||||
Take the church number 2 for example:
|
||||
|
||||
`2 = λf.λx.f(f x)`
|
||||
|
||||
For the inner part `λx.f(f x)`:
|
||||
```
|
||||
λx.f(f x)
|
||||
= S (λx.f) (λx.(f x)) (case 3)
|
||||
= S (K f) (S (λx.f) (λx.x)) (case 2, 3)
|
||||
= S (K f) (S (K f) I) (case 2, 1)
|
||||
```
|
||||
|
||||
So:
|
||||
```
|
||||
2
|
||||
= λf.λx.f(f x)
|
||||
= λf.(S (K f) (S (K f) I))
|
||||
= λf.((S (K f)) (S (K f) I))
|
||||
= S (λf.(S (K f))) (λf.(S (K f) I)) (case 3)
|
||||
```
|
||||
|
||||
For the first argument `λf.(S (K f))`:
|
||||
```
|
||||
λf.(S (K f))
|
||||
= S (λf.S) (λf.(K f)) (case 3)
|
||||
= S (K S) (S (λf.K) (λf.f)) (case 2, 3)
|
||||
= S (K S) (S (K K) I) (case 2, 3)
|
||||
```
|
||||
|
||||
For the second argument `λf.(S (K f) I)`:
|
||||
```
|
||||
λf.(S (K f) I)
|
||||
= λf.((S (K f)) I)
|
||||
= S (λf.(S (K f))) (λf.I) (case 3)
|
||||
= S (S (λf.S) (λf.(K f))) (K I) (case 2, 3)
|
||||
= S (S (K S) (S (λf.K) (λf.f))) (K I) (case 1, 3)
|
||||
= S (S (K S) (S (K K) I)) (K I) (case 1, 2)
|
||||
```
|
||||
|
||||
Merging them up:
|
||||
```
|
||||
2
|
||||
= S (λf.(S (K f))) (λf.(S (K f) I))
|
||||
= S (S (K S) (S (K K) I)) (S (S (K S) (S (K K) I)) (K I))
|
||||
```
|
||||
|
||||
Expanding this, we would end up with the same expression for the
|
||||
church number 2 again.
|
||||
|
||||
### SK Combinator Calculus
|
||||
|
||||
The SKI combinator calculus can still be reduced further. We can
|
||||
remove the I combinator by noting that `I = SKK`. We can substitute
|
||||
all `I`'s with `SKK`.
|
||||
|
||||
### Iota Combinator
|
||||
|
||||
The SK combinator calculus is still not minimal. Defining:
|
||||
|
||||
```
|
||||
ι = λf.((f S) K)
|
||||
```
|
||||
|
||||
We have:
|
||||
|
||||
```
|
||||
I = ιι
|
||||
K = ι(ιI) = ι(ι(ιι))
|
||||
S = ι(K) = ι(ι(ι(ιι)))
|
||||
```
|
||||
|
||||
## For more advanced reading:
|
||||
|
||||
1. [A Tutorial Introduction to the Lambda Calculus](http://www.inf.fu-berlin.de/lehre/WS03/alpi/lambda.pdf)
|
||||
2. [Cornell CS 312 Recitation 26: The Lambda Calculus](http://www.cs.cornell.edu/courses/cs3110/2008fa/recitations/rec26.html)
|
||||
3. [Wikipedia - Lambda Calculus](https://en.wikipedia.org/wiki/Lambda_calculus)
|
||||
3. [Wikipedia - Lambda Calculus](https://en.wikipedia.org/wiki/Lambda_calculus)
|
||||
4. [Wikipedia - SKI combinator calculus](https://en.wikipedia.org/wiki/SKI_combinator_calculus)
|
||||
5. [Wikipedia - Iota and Jot](https://en.wikipedia.org/wiki/Iota_and_Jot)
|
||||
|
@ -171,7 +171,7 @@ function arithmetic_functions(a, b, c, d) {
|
||||
# Muitas implementações AWK possuem algumas funções trigonométricas padrão
|
||||
localvar = sin(a)
|
||||
localvar = cos(a)
|
||||
localvar = atan2(a, b) # arco-tangente de b / a
|
||||
localvar = atan2(b, a) # arco-tangente de b / a
|
||||
|
||||
# E conteúdo logarítmico
|
||||
localvar = exp(a)
|
||||
|
@ -138,6 +138,10 @@ len("This is a string") # => 16
|
||||
# still use the old style of formatting:
|
||||
"%s can be %s the %s way" % ("Strings", "interpolated", "old") # => "Strings can be interpolated the old way"
|
||||
|
||||
# You can also format using f-strings or formatted string literals
|
||||
name = "Reiko"
|
||||
f"She said her name is {name}." # => "She said her name is Reiko"
|
||||
|
||||
|
||||
# None is an object
|
||||
None # => None
|
||||
|
459
ro-ro/elixir-ro.html.markdown
Normal file
459
ro-ro/elixir-ro.html.markdown
Normal file
@ -0,0 +1,459 @@
|
||||
---
|
||||
language: elixir
|
||||
contributors:
|
||||
- ["Joao Marques", "http://github.com/mrshankly"]
|
||||
- ["Dzianis Dashkevich", "https://github.com/dskecse"]
|
||||
- ["Ryan Plant", "https://github.com/ryanplant-au"]
|
||||
- ["Ev Bogdanov", "https://github.com/evbogdanov"]
|
||||
translators:
|
||||
- ["Vitalie Lazu", "https://github.com/vitaliel"]
|
||||
|
||||
filename: learnelixir-ro.ex
|
||||
---
|
||||
|
||||
Elixir este un limbaj funcțional modern construit pe baza mașinii virtuale Erlang.
|
||||
E total compatibil cu Erlang, dar are o sintaxă mai prietenoasă și propune mai multe
|
||||
posibilități.
|
||||
|
||||
```elixir
|
||||
|
||||
# Comentariile de o linie încep cu simbolul diez.
|
||||
|
||||
# Pentru comentarii pe mai multe linii nu există sintaxă separată,
|
||||
# de aceea folosiți mai multe linii cu comentarii.
|
||||
|
||||
# Pentru a folosi shell-ul elixir utilizați comanda `iex`.
|
||||
# Compilați modulele cu comanda `elixirc`.
|
||||
|
||||
# Ambele comenzi vor lucra în terminal, dacă ați instalat Elixir corect.
|
||||
|
||||
## ---------------------------
|
||||
## -- Tipuri de bază
|
||||
## ---------------------------
|
||||
|
||||
# Numere
|
||||
3 # număr întreg
|
||||
0x1F # număr întreg
|
||||
3.0 # număr cu virgulă mobilă
|
||||
|
||||
# Atomii, sunt constante nenumerice. Ei încep cu `:`.
|
||||
:salut # atom
|
||||
|
||||
# Tuplele sunt păstrate în memorie consecutiv.
|
||||
{1,2,3} # tuple
|
||||
|
||||
# Putem accesa elementul tuplelui folosind funcția `elem`:
|
||||
elem({1, 2, 3}, 0) #=> 1
|
||||
|
||||
# Listele sunt implementate ca liste înlănțuite.
|
||||
[1,2,3] # listă
|
||||
|
||||
# Fiecare listă ne vidă are cap (primul element al listei)
|
||||
# și coadă (restul elementelor).
|
||||
# Putem accesa capul și coada listei cum urmează:
|
||||
[cap | coadă] = [1,2,3]
|
||||
cap #=> 1
|
||||
coadă #=> [2, 3]
|
||||
|
||||
# În Elixir, ca și în Erlang, simbolul `=` denotă potrivirea șabloanelor și
|
||||
# nu atribuire.
|
||||
#
|
||||
# Aceasta înseamnă că expresia din stînga (șablonul) se potrivește cu
|
||||
# expresia din dreaptă.
|
||||
#
|
||||
# În modul acesta exemplul de mai sus lucrează accesînd capul și coada unei liste.
|
||||
|
||||
# Potrivirea șablonului va da eroare cînd expresiile din stînga și dreapta nu se
|
||||
# potrivesc, în exemplu acesta tuplele au lungime diferită.
|
||||
{a, b, c} = {1, 2} #=> ** (MatchError)
|
||||
|
||||
# Există și date binare
|
||||
<<1,2,3>>
|
||||
|
||||
# Sunt două tipuri de șiruri de caractere
|
||||
"salut" # șir de caractere Elixir
|
||||
'salut' # listă de caractere Erlang
|
||||
|
||||
# Șir de caractere pe mai multe linii
|
||||
"""
|
||||
Sunt un șir de caractere
|
||||
pe mai multe linii.
|
||||
"""
|
||||
#=> "Sunt un șir de caractere\npe mai multe linii..\n"
|
||||
|
||||
# Șirurile de caractere sunt codificate în UTF-8:
|
||||
"Bună dimineața" #=> "Bună dimineața"
|
||||
|
||||
# Șirurile de caractere sunt date binare, listele de caractere doar liste.
|
||||
<<?a, ?b, ?c>> #=> "abc"
|
||||
[?a, ?b, ?c] #=> 'abc'
|
||||
|
||||
# `?a` în Elixir întoarce codul ASCII pentru litera `a`
|
||||
?a #=> 97
|
||||
|
||||
# Pentru a concatena listele folosiți `++`, pentru date binare - `<>`
|
||||
[1,2,3] ++ [4,5] #=> [1,2,3,4,5]
|
||||
'Salut ' ++ 'lume' #=> 'Salut lume'
|
||||
|
||||
<<1,2,3>> <> <<4,5>> #=> <<1,2,3,4,5>>
|
||||
"Salut " <> "lume" #=> "Salut lume"
|
||||
|
||||
# Diapazoanele sunt reprezentate ca `început..sfîrșit` (inclusiv)
|
||||
1..10 #=> 1..10
|
||||
început..sfîrșit = 1..10 # Putem folosi potrivirea șabloanelor cu diapazoane de asemenea
|
||||
[început, sfîrșit] #=> [1, 10]
|
||||
|
||||
# Dicţionarele stochează chei şi o valoare pentru fiecare cheie
|
||||
genuri = %{"Ion" => "bărbat", "Maria" => "femeie"}
|
||||
genuri["Ion"] #=> "bărbat"
|
||||
|
||||
# Dicționare cu chei de tip atom au sintaxă specială
|
||||
genuri = %{ion: "bărbat", maria: "femeie"}
|
||||
genuri.ion #=> "bărbat"
|
||||
|
||||
## ---------------------------
|
||||
## -- Operatori
|
||||
## ---------------------------
|
||||
|
||||
# Operații matematice
|
||||
1 + 1 #=> 2
|
||||
10 - 5 #=> 5
|
||||
5 * 2 #=> 10
|
||||
10 / 2 #=> 5.0
|
||||
|
||||
# În Elixir operatorul `/` întotdeauna întoarce un număr cu virgulă mobilă.
|
||||
|
||||
# Folosiți `div` pentru împărțirea numerelor întregi
|
||||
div(10, 2) #=> 5
|
||||
|
||||
# Pentru a obține restul de la împărțire utilizați `rem`
|
||||
rem(10, 3) #=> 1
|
||||
|
||||
# Există și operatori booleni: `or`, `and` and `not`.
|
||||
# Acești operatori așteaptă ca primul argument o expresie booleană.
|
||||
true and true #=> true
|
||||
false or true #=> true
|
||||
1 and true #=> ** (BadBooleanError)
|
||||
|
||||
# Elixir de asemenea oferă `||`, `&&` și `!` care acceptă argumente de orice tip.
|
||||
# Toate valorile în afară de `false` și `nil` se vor evalua ca `true`.
|
||||
1 || true #=> 1
|
||||
false && 1 #=> false
|
||||
nil && 20 #=> nil
|
||||
!true #=> false
|
||||
|
||||
# Operatori de comparație: `==`, `!=`, `===`, `!==`, `<=`, `>=`, `<` și `>`
|
||||
1 == 1 #=> true
|
||||
1 != 1 #=> false
|
||||
1 < 2 #=> true
|
||||
|
||||
# `===` și `!==` au strictețe mai mare cînd comparăm numere întregi și reale:
|
||||
1 == 1.0 #=> true
|
||||
1 === 1.0 #=> false
|
||||
|
||||
# Putem compara de asemenea și date de diferite tipuri:
|
||||
1 < :salut #=> true
|
||||
|
||||
# La compararea diferitor tipuri folosiți următoare prioritate:
|
||||
# număr < atom < referință < funcție < port < proces < tuple < listă < șir de caractere
|
||||
|
||||
# Cităm pe Joe Armstrong în acest caz: "Ordinea actuală nu e importantă,
|
||||
dar că ordinea totală este bine definită este important."
|
||||
|
||||
## ---------------------------
|
||||
## -- Ordinea execuției
|
||||
## ---------------------------
|
||||
|
||||
# expresia `if`
|
||||
if false do
|
||||
"Aceasta nu veți vedea niciodată"
|
||||
else
|
||||
"Aceasta veți vedea"
|
||||
end
|
||||
|
||||
# expresia opusă `unless`
|
||||
unless true do
|
||||
"Aceasta nu veți vedea niciodată"
|
||||
else
|
||||
"Aceasta veți vedea"
|
||||
end
|
||||
|
||||
# Țineți minte potrivirea șabloanelor? Multe structuri în Elixir se bazează pe ea.
|
||||
|
||||
# `case` ne permite să comparăm o valoare cu multe șabloane:
|
||||
case {:unu, :doi} do
|
||||
{:patru, :cinci} ->
|
||||
"Aceasta nu se potrivește"
|
||||
{:unu, x} ->
|
||||
"Aceasta se potrivește și atribuie lui `x` `:doi` în acest bloc"
|
||||
_ ->
|
||||
"Aceasta se va potrivi cu orice valoare"
|
||||
end
|
||||
|
||||
# Simbolul `_` se numește variabila anonimă.
|
||||
# Folosiți-l pentru valori ce nu vă interesează.
|
||||
# De exemplu, dacă doar capul listei ne intereseaza:
|
||||
[cap | _] = [1,2,3]
|
||||
cap #=> 1
|
||||
|
||||
# Pentru o citire mai bună putem scri:
|
||||
[cap | _coadă] = [:a, :b, :c]
|
||||
cap #=> :a
|
||||
|
||||
# `cond` ne permite să verificăm multe condiții de odată.
|
||||
# Folosiți `cond` în schimbul la multe expresii `if`.
|
||||
cond do
|
||||
1 + 1 == 3 ->
|
||||
"Aceasta nu veți vedea niciodată"
|
||||
2 * 5 == 12 ->
|
||||
"Pe mine la fel"
|
||||
1 + 2 == 3 ->
|
||||
"Aceasta veți vedea"
|
||||
end
|
||||
|
||||
# Este obușnuit de setat ultima condiție cu `true`, care se va potrivi întotdeauna.
|
||||
cond do
|
||||
1 + 1 == 3 ->
|
||||
"Aceasta nu veți vedea niciodată"
|
||||
2 * 5 == 12 ->
|
||||
"Pe mine la fel"
|
||||
true ->
|
||||
"Aceasta veți vedea (este else în esență)"
|
||||
end
|
||||
|
||||
# Blocul `try/catch` se foloște pentru prelucrarea excepțiilor.
|
||||
# Elixir suportă blocul `after` care se execută în orice caz.
|
||||
try do
|
||||
throw(:salut)
|
||||
catch
|
||||
mesaj -> "Am primit #{mesaj}."
|
||||
after
|
||||
IO.puts("Sunt în blocul after.")
|
||||
end
|
||||
#=> Sunt în blocul after.
|
||||
# "Am primit salut"
|
||||
|
||||
## ---------------------------
|
||||
## -- Module și Funcții
|
||||
## ---------------------------
|
||||
|
||||
# Funcții anonime (atenție la punct la apelarea funcției)
|
||||
square = fn(x) -> x * x end
|
||||
square.(5) #=> 25
|
||||
|
||||
# Ele de asemenea aceptă multe clauze și expresii de gardă.
|
||||
# Expresiile de gardă vă permit să acordați potrivirea șabloanelor,
|
||||
# ele sunt indicate după cuvîntul cheie `when`:
|
||||
f = fn
|
||||
x, y when x > 0 -> x + y
|
||||
x, y -> x * y
|
||||
end
|
||||
|
||||
f.(1, 3) #=> 4
|
||||
f.(-1, 3) #=> -3
|
||||
|
||||
# Elixir de asemenea oferă multe funcții incorporate.
|
||||
# Ele sunt accesibile în scopul curent.
|
||||
is_number(10) #=> true
|
||||
is_list("salut") #=> false
|
||||
elem({1,2,3}, 0) #=> 1
|
||||
|
||||
# Puteți grupa cîteva funcții într-un modul. În interiorul modulului folosiți `def`
|
||||
# pentru a defini funcțiile necesare.
|
||||
defmodule Math do
|
||||
def sum(a, b) do
|
||||
a + b
|
||||
end
|
||||
|
||||
def square(x) do
|
||||
x * x
|
||||
end
|
||||
end
|
||||
|
||||
Math.sum(1, 2) #=> 3
|
||||
Math.square(3) #=> 9
|
||||
|
||||
# Pentru a compila modulul nostru simplu Math îl salvăm ca `math.ex` și utilizăm `elixirc`.
|
||||
# în terminal: elixirc math.ex
|
||||
|
||||
# În interiorul modulului putem defini funcții cu `def` și funcții private cu `defp`.
|
||||
defmodule PrivateMath do
|
||||
# O funcție definită cu `def` este accesibilă pentru apelare din alte module,
|
||||
def sum(a, b) do
|
||||
do_sum(a, b)
|
||||
end
|
||||
|
||||
# O funcție privată poate fi apelată doar local.
|
||||
defp do_sum(a, b) do
|
||||
a + b
|
||||
end
|
||||
end
|
||||
|
||||
PrivateMath.sum(1, 2) #=> 3
|
||||
PrivateMath.do_sum(1, 2) #=> ** (UndefinedFunctionError)
|
||||
|
||||
# Declarația funcției de asemenea suportă expresii de gardă și multe clauze:
|
||||
defmodule Geometry do
|
||||
def area({:rectangle, w, h}) do
|
||||
w * h
|
||||
end
|
||||
|
||||
def area({:circle, r}) when is_number(r) do
|
||||
3.14 * r * r
|
||||
end
|
||||
end
|
||||
|
||||
Geometry.area({:rectangle, 2, 3}) #=> 6
|
||||
Geometry.area({:circle, 3}) #=> 28.25999999999999801048
|
||||
Geometry.area({:circle, "not_a_number"}) #=> ** (FunctionClauseError)
|
||||
|
||||
# Din cauza variabilelor imutabile, un rol important îl ocupă funcțiile recursive
|
||||
defmodule Recursion do
|
||||
def sum_list([head | tail], acc) do
|
||||
sum_list(tail, acc + head)
|
||||
end
|
||||
|
||||
def sum_list([], acc) do
|
||||
acc
|
||||
end
|
||||
end
|
||||
|
||||
Recursion.sum_list([1,2,3], 0) #=> 6
|
||||
|
||||
# Modulele în Elixir suportă atribute, există atribute incorporate și
|
||||
# puteți adăuga altele.
|
||||
defmodule MyMod do
|
||||
@moduledoc """
|
||||
Este un atribut incorporat
|
||||
"""
|
||||
|
||||
@my_data 100 # Acesta e atributul nostru
|
||||
IO.inspect(@my_data) #=> 100
|
||||
end
|
||||
|
||||
# Operatorul |> permite transferarea rezultatului unei expresii din stînga
|
||||
# ca primul argument al unei funcții din dreapta.
|
||||
Range.new(1,10)
|
||||
|> Enum.map(fn x -> x * x end)
|
||||
|> Enum.filter(fn x -> rem(x, 2) == 0 end)
|
||||
#=> [4, 16, 36, 64, 100]
|
||||
|
||||
## ---------------------------
|
||||
## -- Structuri și Excepții
|
||||
## ---------------------------
|
||||
|
||||
# Structurile sunt extensii a dicționarelor ce au valori implicite,
|
||||
# verificări în timpul compilării și polimorfism
|
||||
defmodule Person do
|
||||
defstruct name: nil, age: 0, height: 0
|
||||
end
|
||||
|
||||
joe_info = %Person{ name: "Joe", age: 30, height: 180 }
|
||||
#=> %Person{age: 30, height: 180, name: "Joe"}
|
||||
|
||||
# Acesarea cîmpului din structură
|
||||
joe_info.name #=> "Joe"
|
||||
|
||||
# Actualizarea valorii cîmpului
|
||||
older_joe_info = %{ joe_info | age: 31 }
|
||||
#=> %Person{age: 31, height: 180, name: "Joe"}
|
||||
|
||||
# Blocul `try` cu cuvîntul cheie `rescue` e folosit pentru a prinde excepții
|
||||
try do
|
||||
raise "o eroare"
|
||||
rescue
|
||||
RuntimeError -> "a fost prinsă o eroare runtime"
|
||||
_error -> "aici vor fi prinse toate erorile"
|
||||
end
|
||||
#=> "a fost prinsă o eroare runtime"
|
||||
|
||||
# Toate excepțiile au un mesaj
|
||||
try do
|
||||
raise "o eroare"
|
||||
rescue
|
||||
x in [RuntimeError] ->
|
||||
x.message
|
||||
end
|
||||
#=> "o eroare"
|
||||
|
||||
## ---------------------------
|
||||
## -- Concurența
|
||||
## ---------------------------
|
||||
|
||||
# Concurența în Elixir se bazează pe modelul actor. Pentru a scrie programe
|
||||
# concurente avem nevoie de trei lucruri:
|
||||
# 1. Crearea proceselor
|
||||
# 2. Trimiterea mesajelor
|
||||
# 3. Primirea mesajelor
|
||||
|
||||
# Un nou proces se crează folosind funcția `spawn`, care primește o funcție
|
||||
# ca argument.
|
||||
f = fn -> 2 * 2 end #=> #Function<erl_eval.20.80484245>
|
||||
spawn(f) #=> #PID<0.40.0>
|
||||
|
||||
# `spawn` întoarce identificatorul procesului pid, îl puteți folosi pentru
|
||||
# a trimite mesaje procesului. Mesajele se transmit folosind operatorul `send`.
|
||||
# Pentru primirea mesajelor se folosește mecanismul `receive`:
|
||||
|
||||
# Blocul `receive do` este folosit pentru așteptarea mesajelor și prelucrarea lor
|
||||
# cînd au fost primite. Blocul `receive do` va procesa doar un singur mesaj primit.
|
||||
# Pentru a procesa mai multe mesaje, funcția cu blocul `receive do` trebuie
|
||||
# recursiv să se auto apeleze.
|
||||
|
||||
defmodule Geometry do
|
||||
def area_loop do
|
||||
receive do
|
||||
{:rectangle, w, h} ->
|
||||
IO.puts("Aria = #{w * h}")
|
||||
area_loop()
|
||||
{:circle, r} ->
|
||||
IO.puts("Aria = #{3.14 * r * r}")
|
||||
area_loop()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Compilați modulul și creați un proces
|
||||
pid = spawn(fn -> Geometry.area_loop() end) #=> #PID<0.40.0>
|
||||
# Un alt mod
|
||||
pid = spawn(Geometry, :area_loop, [])
|
||||
|
||||
# Trimiteți un mesaj către `pid` care se va potrivi cu un șablon din blocul `receive`
|
||||
send pid, {:rectangle, 2, 3}
|
||||
#=> Aria = 6
|
||||
# {:rectangle,2,3}
|
||||
|
||||
send pid, {:circle, 2}
|
||||
#=> Aria = 12.56000000000000049738
|
||||
# {:circle,2}
|
||||
|
||||
# Interpretatorul este de asemenea un proces, puteți folosi `self`
|
||||
# pentru a primi identificatorul de proces:
|
||||
self() #=> #PID<0.27.0>
|
||||
|
||||
## ---------------------------
|
||||
## -- Agenții
|
||||
## ---------------------------
|
||||
|
||||
# Un agent este un proces care urmărește careva valori ce se schimbă.
|
||||
|
||||
# Creați un agent cu `Agent.start_link`, transmițînd o funcție.
|
||||
# Stare inițială a agentului va fi rezultatul funcției.
|
||||
{ok, my_agent} = Agent.start_link(fn -> ["roșu", "verde"] end)
|
||||
|
||||
# `Agent.get` primește numele agentului și o `fn` care primește starea curentă
|
||||
# Orice va întoarce `fn` este ceea ce veți primi înapoi:
|
||||
Agent.get(my_agent, fn colors -> colors end) #=> ["roșu", "verde"]
|
||||
|
||||
# Actualizați starea agentului în acelaș mod:
|
||||
Agent.update(my_agent, fn colors -> ["albastru" | colors] end)
|
||||
```
|
||||
|
||||
## Link-uri utile
|
||||
|
||||
* [Primii pași](http://elixir-lang.org/getting-started/introduction.html) de pe [situl Elixir](http://elixir-lang.org)
|
||||
* [Documentația oficială Elixir](http://elixir-lang.org/docs/master/)
|
||||
* [Un mic conspect pe Elixir](http://media.pragprog.com/titles/elixir/ElixirCheat.pdf)
|
||||
* [Cartea "Programming Elixir"](https://pragprog.com/book/elixir/programming-elixir) de Dave Thomas
|
||||
* [Cartea "Learn You Some Erlang for Great Good!"](http://learnyousomeerlang.com/) de Fred Hebert
|
||||
* [Cartea "Programming Erlang: Software for a Concurrent World"](https://pragprog.com/book/jaerlang2/programming-erlang) de Joe Armstrong
|
@ -28,12 +28,12 @@ tipten bağımsızlık, exception'lar ve sınıflar gibi yüksek-seviyeli özell
|
||||
Bu hız ve kullanışlılık C++'ı en çok kullanılan dillerden biri yapar.
|
||||
|
||||
```c++
|
||||
//////////////////
|
||||
//////////////////////
|
||||
// C ile karşılaştırma
|
||||
//////////////////
|
||||
//////////////////////
|
||||
|
||||
// C++ _neredeyse_ C'nin bir üstkümesidir, değişken tanımı, basit tipleri
|
||||
ve fonksiyonları için temelde aynı sözdizimini paylaşır.
|
||||
// ve fonksiyonları için temelde aynı sözdizimini paylaşır.
|
||||
|
||||
// Aynı C gibi, programın başlangıç noktası bir integer döndüren
|
||||
// main fonksiyonudur.
|
||||
@ -106,7 +106,7 @@ int main()
|
||||
|
||||
////////////////////////////////
|
||||
// Default fonksiyon argümanları
|
||||
/////////////////////////////i//
|
||||
////////////////////////////////
|
||||
|
||||
// Eğer çağırıcı tarafından fonksiyona argüman sağlanmamışsa,
|
||||
// fonksiyona default argüman verebilirsin
|
||||
@ -264,7 +264,7 @@ string retVal = tempObjectFun();
|
||||
// Bu iki satırda aslında ne oluyor:
|
||||
// - tempObjectFun fonksiyonundan bir string nesnesi dönüyor
|
||||
// - dönmüş olan nesneyle yeni bir string oluşturuyor
|
||||
/ - dönmüş olan nesne yok ediliyor
|
||||
// - dönmüş olan nesne yok ediliyor
|
||||
// İşte bu dönen nesneye geçici nesne denir. Geçici nesneler fonksiyon nesne
|
||||
// döndürdüğünde oluşturulur ve ifade işini bitirdiğinde yok edilir (Aslında,
|
||||
// standard'ın söylediği şey bu ama derleyiciler bu davranışı değiştirmemize
|
||||
@ -367,7 +367,6 @@ void WritePreferredCarTypeToFile(ECarTypes InputCarType)
|
||||
// Sınıfı tanımla.
|
||||
// Sınıflar genelde header (.h veya .hpp) dosyalarında tanımlanır.
|
||||
class Dog {
|
||||
// Member variables and functions are private by default.
|
||||
// Üye değişkenler ve fonksiyonlar default olarak private'dir.
|
||||
std::string name;
|
||||
int weight;
|
||||
@ -549,7 +548,7 @@ int main () {
|
||||
// Şablonlar C++ dilinde tipten bağımsız programlama için kullanılır.
|
||||
|
||||
// Zaten aşina olduğun tipten bağımsız programlamayla başladık. Bir tip parametresi
|
||||
alan fonksiyon veya sınıf tanımlamaık için:
|
||||
// alan fonksiyon veya sınıf tanımlamaık için:
|
||||
template<class T>
|
||||
class Box {
|
||||
public:
|
||||
@ -802,9 +801,9 @@ sort(tester.begin(), tester.end(), [](const pair<int, int>& lhs, const pair<int,
|
||||
// "Tutma listesi", fonksiyon gövdesinde nelerin, ne şekilde erişilebilir olduğunu tanımlar
|
||||
// Şunlardan biri olabilir:
|
||||
// 1. bir değer : [x]
|
||||
2. bir referans : [&x]
|
||||
3. mevcut scope içindeki herhangi bir değişkene referans ile [&]
|
||||
4. 3 ile aynı, ama değer ile [=]
|
||||
// 2. bir referans : [&x]
|
||||
// 3. mevcut scope içindeki herhangi bir değişkene referans ile [&]
|
||||
// 4. 3 ile aynı, ama değer ile [=]
|
||||
// Mesela:
|
||||
vector<int> dog_ids;
|
||||
// number_of_dogs = 3;
|
||||
@ -843,9 +842,9 @@ for(auto elem: arr) {
|
||||
// arr dizisinin elemanlarıyla ilgili bir şeyler yap
|
||||
}
|
||||
|
||||
/////////////////////
|
||||
////////////////
|
||||
// Güzel Şeyler
|
||||
/////////////////////
|
||||
////////////////
|
||||
|
||||
// C++ dilinin bakış açısı yeni başlayanlar için (hatta dili iyi bilenler için bile)
|
||||
// şaşırtıcı olabilir.
|
||||
|
@ -30,7 +30,7 @@ JavaDoc-коментар виглядає так. Використовуєтьс
|
||||
|
||||
// Імпорт класу ArrayList з пакета java.util
|
||||
import java.util.ArrayList;
|
||||
// Імпорт усіх класів з пакета java.security
|
||||
// Імпорт усіх класів з пакета java.security
|
||||
import java.security.*;
|
||||
|
||||
// Кожний .java файл містить один зовнішній публічний клас, ім’я якого співпадає
|
||||
@ -99,13 +99,13 @@ public class LearnJava {
|
||||
|
||||
// Примітка: Java не має беззнакових типів.
|
||||
|
||||
// Float — 32-бітне число з рухомою комою одиничної точності за стандартом IEEE 754
|
||||
// Float — 32-бітне число з рухомою комою одиничної точності за стандартом IEEE 754
|
||||
// 2^-149 <= float <= (2-2^-23) * 2^127
|
||||
float fooFloat = 234.5f;
|
||||
// f або F використовується для позначення того, що змінна має тип float;
|
||||
// інакше трактується як double.
|
||||
|
||||
// Double — 64-бітне число з рухомою комою подвійної точності за стандартом IEEE 754
|
||||
// Double — 64-бітне число з рухомою комою подвійної точності за стандартом IEEE 754
|
||||
// 2^-1074 <= x <= (2-2^-52) * 2^1023
|
||||
double fooDouble = 123.4;
|
||||
|
||||
@ -130,13 +130,13 @@ public class LearnJava {
|
||||
// байтів, операції над ними виконуються функціями, які мають клас BigInteger
|
||||
//
|
||||
// BigInteger можна ініціалізувати, використовуючи масив байтів чи рядок.
|
||||
|
||||
|
||||
BigInteger fooBigInteger = new BigInteger(fooByteArray);
|
||||
|
||||
|
||||
// BigDecimal — Незмінні знакові дробові числа довільної точності
|
||||
//
|
||||
// BigDecimal складається з двох частин: цілого числа довільної точності
|
||||
// BigDecimal складається з двох частин: цілого числа довільної точності
|
||||
// з немасштабованим значенням та 32-бітного масштабованого цілого числа
|
||||
//
|
||||
// BigDecimal дозволяє розробникам контролювати десяткове округлення.
|
||||
@ -147,10 +147,10 @@ public class LearnJava {
|
||||
// чи немасштабованим значенням (BigInteger) і масштабованим значенням (int).
|
||||
|
||||
BigDecimal fooBigDecimal = new BigDecimal(fooBigInteger, fooInt);
|
||||
|
||||
|
||||
// Для дотримання заданої точності рекомендується використовувати
|
||||
// конструктор, який приймає String
|
||||
|
||||
// конструктор, який приймає String
|
||||
|
||||
BigDecimal tenCents = new BigDecimal("0.1");
|
||||
|
||||
|
||||
@ -295,7 +295,7 @@ public class LearnJava {
|
||||
// Виконається 10 разів, fooFor 0->9
|
||||
}
|
||||
System.out.println("Значення fooFor: " + fooFor);
|
||||
|
||||
|
||||
// Вихід із вкладеного циклу через мітку
|
||||
outer:
|
||||
for (int i = 0; i < 10; i++) {
|
||||
@ -306,7 +306,7 @@ public class LearnJava {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Цикл For Each
|
||||
// Призначений для перебору масивів та колекцій
|
||||
int[] fooList = {1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
@ -318,7 +318,7 @@ public class LearnJava {
|
||||
|
||||
// Оператор вибору Switch Case
|
||||
// Оператор вибору працює з типами даних byte, short, char, int.
|
||||
// Також працює з переліками Enum,
|
||||
// Також працює з переліками Enum,
|
||||
// класом String та класами-обгортками примітивних типів:
|
||||
// Character, Byte, Short та Integer.
|
||||
int month = 3;
|
||||
@ -334,7 +334,7 @@ public class LearnJava {
|
||||
break;
|
||||
}
|
||||
System.out.println("Результат Switch Case: " + monthString);
|
||||
|
||||
|
||||
// Починаючи з Java 7 і далі, вибір рядкових змінних здійснюється так:
|
||||
String myAnswer = "можливо";
|
||||
switch(myAnswer) {
|
||||
@ -398,7 +398,7 @@ public class LearnJava {
|
||||
|
||||
// toString повертає рядкове представлення об’єкту.
|
||||
System.out.println("Інформація про об’єкт trek: " + trek.toString());
|
||||
|
||||
|
||||
// У Java немає синтаксису для явного створення статичних колекцій.
|
||||
// Це можна зробити так:
|
||||
|
||||
@ -554,7 +554,7 @@ public interface Digestible {
|
||||
|
||||
// Можна створити клас, що реалізує обидва інтерфейси.
|
||||
public class Fruit implements Edible, Digestible {
|
||||
|
||||
|
||||
@Override
|
||||
public void eat() {
|
||||
// ...
|
||||
@ -694,41 +694,41 @@ public abstract class Mammal()
|
||||
|
||||
public enum Day {
|
||||
SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
|
||||
THURSDAY, FRIDAY, SATURDAY
|
||||
THURSDAY, FRIDAY, SATURDAY
|
||||
}
|
||||
|
||||
// Перелік Day можна використовувати так:
|
||||
|
||||
public class EnumTest {
|
||||
|
||||
|
||||
// Змінна того же типу, що й перелік
|
||||
Day day;
|
||||
|
||||
|
||||
public EnumTest(Day day) {
|
||||
this.day = day;
|
||||
}
|
||||
|
||||
|
||||
public void tellItLikeItIs() {
|
||||
switch (day) {
|
||||
case MONDAY:
|
||||
System.out.println("Понеділкі важкі.");
|
||||
System.out.println("Понеділки важкі.");
|
||||
break;
|
||||
|
||||
|
||||
case FRIDAY:
|
||||
System.out.println("П’ятниці краще.");
|
||||
break;
|
||||
|
||||
case SATURDAY:
|
||||
|
||||
case SATURDAY:
|
||||
case SUNDAY:
|
||||
System.out.println("Вихідні найліпші.");
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
System.out.println("Середина тижня так собі.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
EnumTest firstDay = new EnumTest(Day.MONDAY);
|
||||
firstDay.tellItLikeItIs(); // => Понеділки важкі.
|
||||
@ -737,7 +737,7 @@ public class EnumTest {
|
||||
}
|
||||
}
|
||||
|
||||
// Переліки набагато потужніші, ніж тут показано.
|
||||
// Переліки набагато потужніші, ніж тут показано.
|
||||
// Тіло переліків може містити методи та інші змінні.
|
||||
// Дивіться більше тут: https://docs.oracle.com/javase/tutorial/java/javaOO/enum.html
|
||||
|
||||
|
@ -45,7 +45,7 @@ doStuff()
|
||||
3; // = 3
|
||||
1.5; // = 1.5
|
||||
|
||||
// Деякі прості арифметичні операції працють так, як ми очікуємо.
|
||||
// Деякі прості арифметичні операції працюють так, як ми очікуємо.
|
||||
1 + 1; // = 2
|
||||
0.1 + 0.2; // = 0.30000000000000004 (а деякі - ні)
|
||||
8 - 1; // = 7
|
||||
@ -106,7 +106,7 @@ null == undefined; // = true
|
||||
|
||||
// ... але приведення не виконується при ===
|
||||
"5" === 5; // = false
|
||||
null === undefined; // = false
|
||||
null === undefined; // = false
|
||||
|
||||
// ... приведення типів може призвести до дивних результатів
|
||||
13 + !0; // 14
|
||||
@ -171,7 +171,7 @@ myArray[3] = "світ";
|
||||
// Об’єкти в JavaScript схожі на словники або асоціативні масиви в інших мовах
|
||||
var myObj = {key1: "Hello", key2: "World"};
|
||||
|
||||
// Ключі - це рядки, але лапки не обов’язкі, якщо ключ задовольняє
|
||||
// Ключі - це рядки, але лапки не обов’язкові, якщо ключ задовольняє
|
||||
// правилам формування назв змінних. Значення можуть бути будь-яких типів.
|
||||
var myObj = {myKey: "myValue", "my other key": 4};
|
||||
|
||||
@ -258,7 +258,7 @@ function myFunction(thing) {
|
||||
return thing.toUpperCase();
|
||||
}
|
||||
myFunction("foo"); // = "FOO"
|
||||
|
||||
|
||||
// Зверніть увагу, що значення яке буде повернено, повинно починатися на тому ж
|
||||
// рядку, що і ключове слово return, інакше завжди буде повертатися значення undefined
|
||||
// через автоматичну вставку крапки з комою
|
||||
@ -332,7 +332,7 @@ var myObj = {
|
||||
};
|
||||
myObj.myFunc(); // = "Hello, world!"
|
||||
|
||||
// Функції, що прикріплені до об’єктів мають доступ до поточного об’єкта за
|
||||
// Функції, що прикріплені до об’єктів мають доступ до поточного об’єкта за
|
||||
// допомогою ключового слова this.
|
||||
myObj = {
|
||||
myString: "Hello, world!",
|
||||
@ -348,7 +348,7 @@ myObj.myFunc(); // = "Hello, world!"
|
||||
var myFunc = myObj.myFunc;
|
||||
myFunc(); // = undefined
|
||||
|
||||
// Функція може бути присвоєна іншому об’єкту. Тоді вона матиме доступ до
|
||||
// Функція може бути присвоєна іншому об’єкту. Тоді вона матиме доступ до
|
||||
// цього об’єкта через this
|
||||
var myOtherFunc = function() {
|
||||
return this.myString.toUpperCase();
|
||||
@ -371,7 +371,7 @@ Math.min(42, 6, 27); // = 6
|
||||
Math.min([42, 6, 27]); // = NaN (Ой-ой!)
|
||||
Math.min.apply(Math, [42, 6, 27]); // = 6
|
||||
|
||||
// Але call і apply — тимчасові. Коли ми хочемо зв’язати функцію і об’єкт
|
||||
// Але call і apply — тимчасові. Коли ми хочемо зв’язати функцію і об’єкт
|
||||
// використовують bind
|
||||
var boundFunc = anotherFunc.bind(myObj);
|
||||
boundFunc(" Hello!"); // = "Hello world, Hello!"
|
||||
@ -475,7 +475,7 @@ if (Object.create === undefined) { // не перезаписуємо метод
|
||||
// Створюємо правильний конструктор з правильним прототипом
|
||||
var Constructor = function(){};
|
||||
Constructor.prototype = proto;
|
||||
|
||||
|
||||
return new Constructor();
|
||||
}
|
||||
}
|
||||
|
435
zh-cn/fortran95-cn.html.markdown
Normal file
435
zh-cn/fortran95-cn.html.markdown
Normal file
@ -0,0 +1,435 @@
|
||||
---
|
||||
language: Fortran
|
||||
filename: learnfortran-cn.f95
|
||||
contributors:
|
||||
- ["Robert Steed", "https://github.com/robochat"]
|
||||
translators:
|
||||
- ["Corvusnest", "https://github.com/Corvusnest"]
|
||||
lang: zh-cn
|
||||
---
|
||||
|
||||
Fortran 是最古老的计算机语言之一。它由IBM开发于1950年用于数值运算(Fortran 为 "Formula
|
||||
Translation" 的缩写)。虽然该语言已年代久远,但目前仍用于高性能计算,如天气预报。
|
||||
该语言仍在持续发展,并且基本保持向下兼容。知名的版本为 Fortran 77, Fortran 90,
|
||||
Fortran 95, Fortran 2003, Fortran 2008 与 Fortran 2015。
|
||||
|
||||
这篇概要将讨论 Fortran 95 的一些特征。因为它是目前所广泛采用的标准版本,并且与最新版本的内容
|
||||
也基本相同(而 Fortran 77 则是一个非常不同的版本)。
|
||||
|
||||
```fortran
|
||||
|
||||
! 这是一行注释
|
||||
|
||||
|
||||
program example !声明一个叫做 example 的程序
|
||||
|
||||
! 代码只能放在程序、函数、子程序或者模块内部
|
||||
! 推荐使用缩进,但不是必须的。
|
||||
|
||||
! 声明变量
|
||||
! ===================
|
||||
|
||||
! 所有的声明必须放在语句与表达式之前
|
||||
|
||||
implicit none !阻止变量的隐式声明 (推荐!)
|
||||
! Implicit none 必须在每一个 函数/程序/模块 中进行声明
|
||||
|
||||
! 重要 - Fortran 对大小写不敏感
|
||||
real z
|
||||
REAL Z2
|
||||
|
||||
real :: v,x ! 警告: 默认值取决于编译器!
|
||||
real :: a = 3, b=2E12, c = 0.01
|
||||
integer :: i, j, k=1, m
|
||||
real, parameter :: PI = 3.1415926535897931 !声明一个常量
|
||||
logical :: y = .TRUE. , n = .FALSE. !布尔值
|
||||
complex :: w = (0,1) !sqrt(-1) (译注: 定义复数,此为-1的平方根)
|
||||
character (len=3) :: month !长度为3的字符串
|
||||
|
||||
real :: array(6) !声明长度为6的浮点数数组
|
||||
real, dimension(4) :: arrayb !声明数组的另一种方法
|
||||
integer :: arrayc(-10:10) !有着自定义索引的数组
|
||||
real :: array2d(3,2) !多维数组
|
||||
|
||||
! 分隔符 '::' 并不总是必要的,但推荐使用
|
||||
|
||||
! 还存在很多其他的变量特征:
|
||||
real, pointer :: p !声明一个指针
|
||||
|
||||
integer, parameter :: LP = selected_real_kind(20)
|
||||
real (kind = LP) :: d !长精度变量
|
||||
|
||||
! 警告:在声明期间初始化变量将导致在函数内发生问题,因为这将自动具备了 “save” 属性,
|
||||
! 因此变量的值在函数的多次调用期间将被存储。一般来说,除了常量,应分开声明与初始化!
|
||||
|
||||
! 字符串
|
||||
! =======
|
||||
|
||||
character :: a_char = 'i'
|
||||
character (len = 6) :: a_str = "qwerty"
|
||||
character (len = 30) :: str_b
|
||||
character (len = *), parameter :: a_long_str = "This is a long string."
|
||||
!可以通过使用 (len=*) 来自动判断长度,但只对常量有效
|
||||
|
||||
str_b = a_str // " keyboard" !通过 // 操作符来连接字符串
|
||||
|
||||
|
||||
! 任务与计算
|
||||
! =======================
|
||||
|
||||
Z = 1 !向之前声明的变量 z 赋值 (大小写不敏感).
|
||||
j = 10 + 2 - 3
|
||||
a = 11.54 / (2.3 * 3.1)
|
||||
b = 2**3 !幂
|
||||
|
||||
|
||||
! 控制流程语句 与 操作符
|
||||
! ===================================
|
||||
|
||||
!单行 if 语句
|
||||
if (z == a) b = 4 !判别句永远需要放在圆括号内
|
||||
|
||||
if (z /= a) then !z 不等于 a
|
||||
! 其他的比较运算符: < > <= >= == /=
|
||||
b = 4
|
||||
else if (z .GT. a) then !z 大于(Greater) a
|
||||
! 文本形式的比较运算符: .LT. .GT. .LE. .GE. .EQ. .NE.
|
||||
b = 6
|
||||
else if (z < a) then !'then' 必须放在该行
|
||||
b = 5 !执行部分必须放在新的一行里
|
||||
else
|
||||
b = 10
|
||||
end if !结束语句需要 'if' (也可以用 'endif').
|
||||
|
||||
|
||||
if (.NOT. (x < c .AND. v >= a .OR. z == z)) then !布尔操作符
|
||||
inner: if (.TRUE.) then !可以为 if 结构命名
|
||||
b = 1
|
||||
endif inner !接下来必须命名 endif 语句.
|
||||
endif
|
||||
|
||||
|
||||
i = 20
|
||||
select case (i)
|
||||
case (0) !当 i == 0
|
||||
j=0
|
||||
case (1:10) !当 i 为 1 到 10 之内 ( 1 <= i <= 10 )
|
||||
j=1
|
||||
case (11:) !当 i>=11
|
||||
j=2
|
||||
case default
|
||||
j=3
|
||||
end select
|
||||
|
||||
|
||||
month = 'jan'
|
||||
! 状态值可以为整数、布尔值或者字符类型
|
||||
! Select 结构同样可以被命名
|
||||
monthly: select case (month)
|
||||
case ("jan")
|
||||
j = 0
|
||||
case default
|
||||
j = -1
|
||||
end select monthly
|
||||
|
||||
do i=2,10,2 !从2到10(包含2和10)以2为步进值循环
|
||||
innerloop: do j=1,3 !循环同样可以被命名
|
||||
exit !跳出循环
|
||||
end do innerloop
|
||||
cycle !重复跳入下一次循环
|
||||
enddo
|
||||
|
||||
|
||||
! Goto 语句是存在的,但强烈不建议使用
|
||||
goto 10
|
||||
stop 1 !立即停止程序 (返回一个设定的状态码).
|
||||
10 j = 201 !这一行被标注为 10 行 (line 10)
|
||||
|
||||
|
||||
! 数组
|
||||
! ======
|
||||
array = (/1,2,3,4,5,6/)
|
||||
array = [1,2,3,4,5,6] !当使用 Fortran 2003 版本.
|
||||
arrayb = [10.2,3e3,0.41,4e-5]
|
||||
array2d = reshape([1.0,2.0,3.0,4.0,5.0,6.0], [3,2])
|
||||
|
||||
! Fortran 数组索引起始于 1
|
||||
! (默认下如此,也可以为数组定义不同的索引起始)
|
||||
v = array(1) !获取数组的第一个元素
|
||||
v = array2d(2,2)
|
||||
|
||||
print *, array(3:5) !打印从第3到第五5之内的所有元素
|
||||
print *, array2d(1,:) !打印2维数组的第一列
|
||||
|
||||
array = array*3 + 2 !可为数组设置数学表达式
|
||||
array = array*array !数组操作支持元素级(操作) (element-wise)
|
||||
!array = array*array2d !这两类数组并不是同一个维度的
|
||||
|
||||
! 有很多内置的数组操作函数
|
||||
c = dot_product(array,array) !点乘 (点积)
|
||||
! 用 matmul() 来进行矩阵运算.
|
||||
c = sum(array)
|
||||
c = maxval(array)
|
||||
print *, minloc(array)
|
||||
c = size(array)
|
||||
print *, shape(array)
|
||||
m = count(array > 0)
|
||||
|
||||
! 遍历一个数组 (一般使用 Product() 函数).
|
||||
v = 1
|
||||
do i = 1, size(array)
|
||||
v = v*array(i)
|
||||
end do
|
||||
|
||||
! 有条件地执行元素级操作
|
||||
array = [1,2,3,4,5,6]
|
||||
where (array > 3)
|
||||
array = array + 1
|
||||
elsewhere (array == 2)
|
||||
array = 1
|
||||
elsewhere
|
||||
array = 0
|
||||
end where
|
||||
|
||||
! 隐式DO循环可以很方便地创建数组
|
||||
array = [ (i, i = 1,6) ] !创建数组 [1,2,3,4,5,6]
|
||||
array = [ (i, i = 1,12,2) ] !创建数组 [1,3,5,7,9,11]
|
||||
array = [ (i**2, i = 1,6) ] !创建数组 [1,4,9,16,25,36]
|
||||
array = [ (4,5, i = 1,3) ] !创建数组 [4,5,4,5,4,5]
|
||||
|
||||
|
||||
! 输入/输出
|
||||
! ============
|
||||
|
||||
print *, b !向命令行打印变量 'b'
|
||||
|
||||
! 我们可以格式化输出
|
||||
print "(I6)", 320 !打印 ' 320'
|
||||
print "(I6.4)", 3 !打印 ' 0003'
|
||||
print "(F6.3)", 4.32 !打印 ' 4.320'
|
||||
|
||||
|
||||
! 该字母与数值规定了给定的数值与字符所用于打印输出的类型与格式
|
||||
! 字母可为 I (整数), F (浮点数), E (工程格式),
|
||||
! L (逻辑/布尔值), A (字符) ...
|
||||
print "(I3)", 3200 !如果数值无法符合格式将打印 '***'
|
||||
|
||||
! 可以同时设定多种格式
|
||||
print "(I5,F6.2,E6.2)", 120, 43.41, 43.41
|
||||
print "(3I5)", 10, 20, 30 !连续打印3个整数 (字段宽度 = 5).
|
||||
print "(2(I5,F6.2))", 120, 43.42, 340, 65.3 !连续分组格式
|
||||
|
||||
! 我们也可以从终端读取输入
|
||||
read *, v
|
||||
read "(2F6.2)", v, x !读取2个数值
|
||||
|
||||
! 读取文件
|
||||
open(unit=11, file="records.txt", status="old")
|
||||
! 文件被引用带有一个单位数 'unit', 为一个取值范围在9-99的整数
|
||||
! 'status' 可以为 {'old','replace','new'} 其中之一
|
||||
read(unit=11, fmt="(3F10.2)") a, b, c
|
||||
close(11)
|
||||
|
||||
! 写入一个文件
|
||||
open(unit=12, file="records.txt", status="replace")
|
||||
write(12, "(F10.2,F10.2,F10.2)") c, b, a
|
||||
close(12)
|
||||
! 在讨论范围之外的还有更多的细节与可用功能,并于老版本的 Fortran 保持兼容
|
||||
|
||||
|
||||
! 内置函数
|
||||
! ==================
|
||||
|
||||
! Fortran 拥有大约 200 个内置函数/子程序
|
||||
! 例子
|
||||
call cpu_time(v) !以秒为单位设置时间
|
||||
k = ior(i,j) !2个整数的位或运算
|
||||
v = log10(x) !以10为底的log运算
|
||||
i = floor(b) !返回一个最接近的整数小于或等于x (地板数)
|
||||
v = aimag(w) !复数的虚数部分
|
||||
|
||||
|
||||
! 函数与子程序
|
||||
! =======================
|
||||
|
||||
! 一个子程序会根据输入值运行一些代码并会导致副作用 (side-effects) 或修改输入值
|
||||
! (译者注: 副作用是指对子程序/函数外的环境产生影响,如修改变量)
|
||||
|
||||
call routine(a,c,v) !调用子程序
|
||||
|
||||
! 一个函数会根据输入的一系列数值来返回一个单独的值
|
||||
! 但输入值仍然可能被修改以及产生副作用
|
||||
|
||||
m = func(3,2,k) !调用函数
|
||||
|
||||
! 函数可以在表达式内被调用
|
||||
Print *, func2(3,2,k)
|
||||
|
||||
! 一个纯函数不会去修改输入值或产生副作用
|
||||
m = func3(3,2,k)
|
||||
|
||||
|
||||
contains ! 用于定义程序内部的副程序(sub-programs)的区域
|
||||
|
||||
! Fortran 拥有一些不同的方法去定义函数
|
||||
|
||||
integer function func(a,b,c) !一个返回一个整数的函数
|
||||
implicit none !最好也在函数内将含蓄模式关闭 (implicit none)
|
||||
integer :: a,b,c !输入值类型定义在函数内部
|
||||
if (a >= 2) then
|
||||
func = a + b + c !返回值默认为函数名
|
||||
return !可以在函数内任意时间返回当前值
|
||||
endif
|
||||
func = a + c
|
||||
! 在函数的结尾不需要返回语句
|
||||
end function func
|
||||
|
||||
|
||||
function func2(a,b,c) result(f) !将返回值声明为 'f'
|
||||
implicit none
|
||||
integer, intent(in) :: a,b !可以声明让变量无法被函数修改
|
||||
integer, intent(inout) :: c
|
||||
integer :: f !函数的返回值类型在函数内声明
|
||||
integer :: cnt = 0 !注意 - 隐式的初始化变量将在函数的多次调用间被存储
|
||||
f = a + b - c
|
||||
c = 4 !变动一个输入变量的值
|
||||
cnt = cnt + 1 !记录函数的被调用次数
|
||||
end function func2
|
||||
|
||||
|
||||
pure function func3(a,b,c) !一个没有副作用的纯函数
|
||||
implicit none
|
||||
integer, intent(in) :: a,b,c
|
||||
integer :: func3
|
||||
func3 = a*b*c
|
||||
end function func3
|
||||
|
||||
|
||||
subroutine routine(d,e,f)
|
||||
implicit none
|
||||
real, intent(inout) :: f
|
||||
real, intent(in) :: d,e
|
||||
f = 2*d + 3*e + f
|
||||
end subroutine routine
|
||||
|
||||
|
||||
end program example ! 函数定义完毕 -----------------------
|
||||
|
||||
! 函数与子程序的外部声明对于生成程序清单来说,需要一个接口声明(即使它们在同一个源文件内)(见下)
|
||||
! 使用 'contains' 可以很容易地在模块或程序内定义它们
|
||||
|
||||
elemental real function func4(a) result(res)
|
||||
! 一个元函数(elemental function) 为一个纯函数使用一个标量输入值
|
||||
! 但同时也可以用在一个数组并对其中的元素分别处理,之后返回一个新的数组
|
||||
real, intent(in) :: a
|
||||
res = a**2 + 1.0
|
||||
end function func4
|
||||
|
||||
|
||||
! 模块
|
||||
! =======
|
||||
|
||||
! 模块十分适合于存放与复用相关联的一组声明、函数与子程序
|
||||
|
||||
module fruit
|
||||
real :: apple
|
||||
real :: pear
|
||||
real :: orange
|
||||
end module fruit
|
||||
|
||||
|
||||
module fruity
|
||||
|
||||
! 声明必须按照顺序: 模块、接口、变量
|
||||
! (同样可在程序内声明模块和接口)
|
||||
|
||||
use fruit, only: apple, pear ! 使用来自于 fruit 模块的 apple 和 pear
|
||||
implicit none !在模块导入后声明
|
||||
|
||||
private !使得模块内容为私有(private)(默认为公共 public)
|
||||
! 显式声明一些变量/函数为公共
|
||||
public :: apple,mycar,create_mycar
|
||||
! 声明一些变量/函数为私有(在当前情况下没必要)(译注: 因为前面声明了模块全局 private)
|
||||
private :: func4
|
||||
|
||||
! 接口
|
||||
! ==========
|
||||
! 在模块内显式声明一个外部函数/程序
|
||||
! 一般最好将函数/程序放进 'contains' 部分内
|
||||
interface
|
||||
elemental real function func4(a) result(res)
|
||||
real, intent(in) :: a
|
||||
end function func4
|
||||
end interface
|
||||
|
||||
! 重载函数可以通过已命名的接口来定义
|
||||
interface myabs
|
||||
! 可以通过使用 'module procedure' 关键词来包含一个已在模块内定义的函数
|
||||
module procedure real_abs, complex_abs
|
||||
end interface
|
||||
|
||||
! 派生数据类型
|
||||
! ==================
|
||||
! 可创建自定义数据结构
|
||||
type car
|
||||
character (len=100) :: model
|
||||
real :: weight !(公斤 kg)
|
||||
real :: dimensions(3) !例: 长宽高(米)
|
||||
character :: colour
|
||||
end type car
|
||||
|
||||
type(car) :: mycar !声明一个自定义类型的变量
|
||||
! 用法具体查看 create_mycar()
|
||||
|
||||
! 注: 模块内没有可执行的语句
|
||||
|
||||
contains
|
||||
|
||||
subroutine create_mycar(mycar)
|
||||
! 展示派生数据类型的使用
|
||||
implicit none
|
||||
type(car),intent(out) :: mycar
|
||||
|
||||
! 通过 '%' 操作符来访问(派生数据)类型的元素
|
||||
mycar%model = "Ford Prefect"
|
||||
mycar%colour = 'r'
|
||||
mycar%weight = 1400
|
||||
mycar%dimensions(1) = 5.0 !索引默认起始值为 1 !
|
||||
mycar%dimensions(2) = 3.0
|
||||
mycar%dimensions(3) = 1.5
|
||||
|
||||
end subroutine
|
||||
|
||||
real function real_abs(x)
|
||||
real :: x
|
||||
if (x<0) then
|
||||
real_abs = -x
|
||||
else
|
||||
real_abs = x
|
||||
end if
|
||||
end function real_abs
|
||||
|
||||
real function complex_abs(z)
|
||||
complex :: z
|
||||
! 过长的一行代码可通过延续符 '&' 来换行
|
||||
complex_abs = sqrt(real(z)**2 + &
|
||||
aimag(z)**2)
|
||||
end function complex_abs
|
||||
|
||||
|
||||
end module fruity
|
||||
|
||||
```
|
||||
|
||||
### 更多资源
|
||||
|
||||
了解更多的 Fortran 信息:
|
||||
|
||||
+ [wikipedia](https://en.wikipedia.org/wiki/Fortran)
|
||||
+ [Fortran_95_language_features](https://en.wikipedia.org/wiki/Fortran_95_language_features)
|
||||
+ [fortranwiki.org](http://fortranwiki.org)
|
||||
+ [www.fortran90.org/](http://www.fortran90.org)
|
||||
+ [list of Fortran 95 tutorials](http://www.dmoz.org/Computers/Programming/Languages/Fortran/FAQs%2C_Help%2C_and_Tutorials/Fortran_90_and_95/)
|
||||
+ [Fortran wikibook](https://en.wikibooks.org/wiki/Fortran)
|
||||
+ [Fortran resources](http://www.fortranplus.co.uk/resources/fortran_resources.pdf)
|
||||
+ [Mistakes in Fortran 90 Programs That Might Surprise You](http://www.cs.rpi.edu/~szymansk/OOF90/bugs.html)
|
Loading…
Reference in New Issue
Block a user