mirror of
https://github.com/adambard/learnxinyminutes-docs.git
synced 2025-04-27 07:33:57 +00:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
d543f672c4
@ -17,7 +17,7 @@ Beinahe alle der folgenden Beispiele können als Teile eines Shell-Skripts oder
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# Die erste Zeile des Scripts nennt sich Shebang in gibt dem System an, wie
|
# Die erste Zeile des Scripts nennt sich Shebang, dies gibt dem System an,
|
||||||
# wie das Script ausgeführt werden soll: http://de.wikipedia.org/wiki/Shebang
|
# wie das Script ausgeführt werden soll: http://de.wikipedia.org/wiki/Shebang
|
||||||
# Du hast es bestimmt schon mitgekriegt, Kommentare fangen mit # an. Das Shebang ist auch ein Kommentar
|
# Du hast es bestimmt schon mitgekriegt, Kommentare fangen mit # an. Das Shebang ist auch ein Kommentar
|
||||||
|
|
||||||
|
138
de-de/yaml-de.html.markdown
Normal file
138
de-de/yaml-de.html.markdown
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
---
|
||||||
|
language: yaml
|
||||||
|
filename: learnyaml.yaml
|
||||||
|
contributors:
|
||||||
|
- ["Adam Brenecki", "https://github.com/adambrenecki"]
|
||||||
|
translators:
|
||||||
|
- ["Ruben M.", https://github.com/switchhax]
|
||||||
|
---
|
||||||
|
|
||||||
|
YAML ist eine Sprache zur Datenserialisierung, die sofort von Menschenhand geschrieben und gelesen werden kann.
|
||||||
|
|
||||||
|
YAML ist eine Erweiterung von JSON, mit der Erweiterung von syntaktisch wichtigen Zeilenumbrüche und Einrückung sowie in Python. Anders als in Python erlaubt YAML keine Tabulator-Zeichen.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# Kommentare in YAML schauen so aus.
|
||||||
|
|
||||||
|
#################
|
||||||
|
# SKALARE TYPEN #
|
||||||
|
#################
|
||||||
|
|
||||||
|
# Unser Kernobjekt (für das ganze Dokument) wird das Assoziative Datenfeld (Map) sein,
|
||||||
|
# welches equivalent zu einem Hash oder einem Objekt einer anderen Sprache ist.
|
||||||
|
Schlüssel: Wert
|
||||||
|
nochn_Schlüssel: Hier kommt noch ein Wert hin.
|
||||||
|
eine_Zahl: 100
|
||||||
|
wissenschaftliche_Notation: 1e+12
|
||||||
|
boolean: true
|
||||||
|
null_Wert: null
|
||||||
|
Schlüssel mit Leerzeichen: value
|
||||||
|
# Strings müssen nicht immer mit Anführungszeichen umgeben sein, können aber:
|
||||||
|
jedoch: "Ein String in Anführungzeichen"
|
||||||
|
"Ein Schlüssel in Anführungszeichen": "Nützlich, wenn du einen Doppelpunkt im Schluessel haben willst."
|
||||||
|
|
||||||
|
# Mehrzeilige Strings schreibst du am besten als 'literal block' (| gefolgt vom Text)
|
||||||
|
# oder ein 'folded block' (> gefolgt vom text).
|
||||||
|
literal_block: |
|
||||||
|
Dieser ganze Block an Text ist der Wert vom Schlüssel literal_block,
|
||||||
|
mit Erhaltung der Zeilenumbrüche.
|
||||||
|
|
||||||
|
Das Literal fährt solange fort bis dieses unverbeult ist und die vorherschende Einrückung wird
|
||||||
|
gekürzt.
|
||||||
|
|
||||||
|
Zeilen, die weiter eingerückt sind, behalten den Rest ihrer Einrückung -
|
||||||
|
diese Zeilen sind mit 4 Leerzeichen eingerückt.
|
||||||
|
folded_style: >
|
||||||
|
Dieser ganze Block an Text ist der Wert vom Schlüssel folded_style, aber diesmal
|
||||||
|
werden alle Zeilenumbrüche durch ein Leerzeichen ersetzt.
|
||||||
|
|
||||||
|
Freie Zeilen, wie obendrüber, werden in einen Zeilenumbruch verwandelt.
|
||||||
|
|
||||||
|
Weiter eingerückte Zeilen behalten ihre Zeilenumbrüche -
|
||||||
|
diese Textpassage wird auf zwei Zeilen sichtbar sein.
|
||||||
|
|
||||||
|
####################
|
||||||
|
# COLLECTION TYPEN #
|
||||||
|
####################
|
||||||
|
|
||||||
|
# Verschachtelung wird duch Einrückung erzielt.
|
||||||
|
eine_verschachtelte_map:
|
||||||
|
schlüssel: wert
|
||||||
|
nochn_Schlüssel: Noch ein Wert.
|
||||||
|
noch_eine_verschachtelte_map:
|
||||||
|
hallo: hallo
|
||||||
|
|
||||||
|
# Schlüssel müssen nicht immer String sein.
|
||||||
|
0.25: ein Float-Wert als Schluessel
|
||||||
|
|
||||||
|
# Schlüssel können auch mehrzeilig sein, ? symbolisiert den Anfang des Schlüssels
|
||||||
|
? |
|
||||||
|
Dies ist ein Schlüssel,
|
||||||
|
der mehrzeilig ist.
|
||||||
|
: und dies ist sein Wert
|
||||||
|
|
||||||
|
# YAML erlaubt auch Collections als Schlüssel, doch viele Programmiersprachen
|
||||||
|
# werden sich beklagen.
|
||||||
|
|
||||||
|
# Folgen (equivalent zu Listen oder Arrays) schauen so aus:
|
||||||
|
eine_Folge:
|
||||||
|
- Artikel 1
|
||||||
|
- Artikel 2
|
||||||
|
- 0.5 # Folgen können verschiedene Typen enthalten.
|
||||||
|
- Artikel 4
|
||||||
|
- schlüssel: wert
|
||||||
|
nochn_schlüssel: nochn_wert
|
||||||
|
-
|
||||||
|
- Dies ist eine Folge
|
||||||
|
- innerhalb einer Folge
|
||||||
|
|
||||||
|
# Weil YAML eine Erweiterung von JSON ist, können JSON-ähnliche Maps und Folgen
|
||||||
|
# geschrieben werden:
|
||||||
|
json_map: {"schlüssel": "wert"}
|
||||||
|
json_seq: [3, 2, 1, "Start"]
|
||||||
|
|
||||||
|
############################
|
||||||
|
# EXTRA YAML EIGENSCHAFTEN #
|
||||||
|
############################
|
||||||
|
|
||||||
|
# YAML stellt zusätzlich Verankerung zu Verfügung, welche es einfach machen
|
||||||
|
# Inhalte im Dokument zu vervielfältigen. Beide Schlüssel werden den selben Wert haben.
|
||||||
|
verankerter_inhalt: &anker_name Dieser String wird als Wert beider Schlüssel erscheinen.
|
||||||
|
anderer_anker: *anker_name
|
||||||
|
|
||||||
|
# YAML hat auch Tags, mit denen man explizit Typangaben angibt.
|
||||||
|
explicit_string: !!str 0.5
|
||||||
|
# Manche Parser implementieren sprachspezifische Tags wie dieser hier für Pythons
|
||||||
|
# komplexe Zahlen.
|
||||||
|
python_komplexe_Zahlen: !!python/komplex 1+2j
|
||||||
|
|
||||||
|
####################
|
||||||
|
# EXTRA YAML TYPEN #
|
||||||
|
####################
|
||||||
|
|
||||||
|
# Strings and Zahlen sind nicht die einzigen Skalare, welche YAML versteht.
|
||||||
|
# ISO-formatierte Datumsangaben and Zeiangaben können ebenso geparsed werden.
|
||||||
|
DatumZeit: 2001-12-15T02:59:43.1Z
|
||||||
|
DatumZeit_mit_Leerzeichen: 2001-12-14 21:59:43.10 -5
|
||||||
|
Datum: 2002-12-14
|
||||||
|
|
||||||
|
# Der !!binary Tag zeigt das ein String base64 verschlüsselt ist.
|
||||||
|
# Representation des Binären Haufens
|
||||||
|
gif_datei: !!binary |
|
||||||
|
R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5
|
||||||
|
OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+
|
||||||
|
+f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC
|
||||||
|
AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs=
|
||||||
|
|
||||||
|
# YAML bietet auch Mengen (Sets), welche so ausschauen
|
||||||
|
menge:
|
||||||
|
? artikel1
|
||||||
|
? artikel2
|
||||||
|
? artikel3
|
||||||
|
|
||||||
|
# Wie in Python sind Mengen nicht anderes als Maps nur mit null als Wert; das Beispiel oben drüber ist equivalent zu:
|
||||||
|
menge:
|
||||||
|
artikel1: null
|
||||||
|
artikel2: null
|
||||||
|
artikel3: null
|
||||||
|
```
|
@ -268,7 +268,7 @@ end
|
|||||||
# implicitement la valeur de la dernière instruction évaluée
|
# implicitement la valeur de la dernière instruction évaluée
|
||||||
double(2) #=> 4
|
double(2) #=> 4
|
||||||
|
|
||||||
# Les paranthèses sont facultative
|
# Les parenthèses sont facultatives
|
||||||
# lorsqu'il n'y a pas d'ambiguïté sur le résultat
|
# lorsqu'il n'y a pas d'ambiguïté sur le résultat
|
||||||
double 3 #=> 6
|
double 3 #=> 6
|
||||||
|
|
||||||
|
762
ja-jp/julia-jp.html.markdown
Normal file
762
ja-jp/julia-jp.html.markdown
Normal file
@ -0,0 +1,762 @@
|
|||||||
|
---
|
||||||
|
language: Julia
|
||||||
|
contributors:
|
||||||
|
- ["Leah Hanson", "http://leahhanson.us"]
|
||||||
|
translators:
|
||||||
|
- ["Yuichi Motoyama", "https://github.com/yomichi"]
|
||||||
|
filename: learnjulia-jp.jl
|
||||||
|
lang: ja-jp
|
||||||
|
---
|
||||||
|
|
||||||
|
Julia は科学技術計算向けに作られた、同図像性を持った(homoiconic) プログラミング言語です。
|
||||||
|
マクロによる同図像性や第一級関数などの抽象化機能の恩恵を受けつつ、低階層をも扱えますが、
|
||||||
|
それでいてPython 並に学習しやすく、使いやすい言語となっています。
|
||||||
|
|
||||||
|
この文章は、Julia の2013年10月18日現在の開発バージョンを元にしています。
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
|
||||||
|
# ハッシュ(シャープ)記号から改行までは単一行コメントとなります。
|
||||||
|
#= 複数行コメントは、
|
||||||
|
'#=' と '=#' とで囲むことで行えます。
|
||||||
|
#=
|
||||||
|
入れ子構造にすることもできます。
|
||||||
|
=#
|
||||||
|
=#
|
||||||
|
|
||||||
|
####################################################
|
||||||
|
## 1. 基本的な型と演算子
|
||||||
|
####################################################
|
||||||
|
|
||||||
|
# Julia ではすべて式となります。
|
||||||
|
|
||||||
|
# 基本となる数値型がいくつかあります。
|
||||||
|
3 # => 3 (Int64)
|
||||||
|
3.2 # => 3.2 (Float64)
|
||||||
|
2 + 1im # => 2 + 1im (Complex{Int64})
|
||||||
|
2//3 # => 2//3 (Rational{Int64})
|
||||||
|
|
||||||
|
# 一般的な中置演算子が使用可能です。
|
||||||
|
1 + 1 # => 2
|
||||||
|
8 - 1 # => 7
|
||||||
|
10 * 2 # => 20
|
||||||
|
35 / 5 # => 7.0
|
||||||
|
5 / 2 # => 2.5 # 整数型同士の割り算の結果は、浮動小数点数型になります
|
||||||
|
div(5, 2) # => 2 # 整数のまま割り算するには、 div を使います
|
||||||
|
5 \ 35 # => 7.0
|
||||||
|
2 ^ 2 # => 4 # べき乗です。排他的論理和ではありません
|
||||||
|
12 % 10 # => 2
|
||||||
|
|
||||||
|
# 丸括弧で演算の優先順位をコントロールできます
|
||||||
|
(1 + 3) * 2 # => 8
|
||||||
|
|
||||||
|
# ビット演算
|
||||||
|
~2 # => -3 # ビット反転
|
||||||
|
3 & 5 # => 1 # ビット積
|
||||||
|
2 | 4 # => 6 # ビット和
|
||||||
|
2 $ 4 # => 6 # ビット排他的論理和
|
||||||
|
2 >>> 1 # => 1 # 右論理シフト
|
||||||
|
2 >> 1 # => 1 # 右算術シフト
|
||||||
|
2 << 1 # => 4 # 左シフト
|
||||||
|
|
||||||
|
# bits 関数を使うことで、数の二進表現を得られます。
|
||||||
|
bits(12345)
|
||||||
|
# => "0000000000000000000000000000000000000000000000000011000000111001"
|
||||||
|
bits(12345.0)
|
||||||
|
# => "0100000011001000000111001000000000000000000000000000000000000000"
|
||||||
|
|
||||||
|
# ブール値が用意されています
|
||||||
|
true
|
||||||
|
false
|
||||||
|
|
||||||
|
# ブール代数
|
||||||
|
!true # => false
|
||||||
|
!false # => true
|
||||||
|
1 == 1 # => true
|
||||||
|
2 == 1 # => false
|
||||||
|
1 != 1 # => false
|
||||||
|
2 != 1 # => true
|
||||||
|
1 < 10 # => true
|
||||||
|
1 > 10 # => false
|
||||||
|
2 <= 2 # => true
|
||||||
|
2 >= 2 # => true
|
||||||
|
# 比較演算子をつなげることもできます
|
||||||
|
1 < 2 < 3 # => true
|
||||||
|
2 < 3 < 2 # => false
|
||||||
|
|
||||||
|
# 文字列は " で作れます
|
||||||
|
"This is a string."
|
||||||
|
|
||||||
|
# 文字リテラルは ' で作れます
|
||||||
|
'a'
|
||||||
|
|
||||||
|
# 文字列は文字の配列のように添字アクセスできます
|
||||||
|
"This is a string"[1] # => 'T' # Julia では添字は 1 から始まります
|
||||||
|
# ただし、UTF8 文字列の場合は添字アクセスではうまくいかないので、
|
||||||
|
# イテレーションを行ってください(map 関数や for ループなど)
|
||||||
|
|
||||||
|
# $ を使うことで、文字列に変数や、任意の式を埋め込めます。
|
||||||
|
"2 + 2 = $(2 + 2)" # => "2 + 2 = 4"
|
||||||
|
|
||||||
|
# 他にも、printf マクロを使うことでも変数を埋め込めます。
|
||||||
|
@printf "%d is less than %f" 4.5 5.3 # 5 is less than 5.300000
|
||||||
|
|
||||||
|
# 出力も簡単です
|
||||||
|
println("I'm Julia. Nice to meet you!")
|
||||||
|
|
||||||
|
####################################################
|
||||||
|
## 2. 変数と配列、タプル、集合、辞書
|
||||||
|
####################################################
|
||||||
|
|
||||||
|
# 変数の宣言は不要で、いきなり変数に値を代入・束縛できます。
|
||||||
|
some_var = 5 # => 5
|
||||||
|
some_var # => 5
|
||||||
|
|
||||||
|
# 値に束縛されていない変数を使おうとするとエラーになります。
|
||||||
|
try
|
||||||
|
some_other_var # => ERROR: some_other_var not defined
|
||||||
|
catch e
|
||||||
|
println(e)
|
||||||
|
end
|
||||||
|
|
||||||
|
# 変数名は数字や記号以外の文字から始めます。
|
||||||
|
# その後は、数字やアンダースコア(_), 感嘆符(!)も使えます。
|
||||||
|
SomeOtherVar123! = 6 # => 6
|
||||||
|
|
||||||
|
# Unicode 文字も使えます。
|
||||||
|
☃ = 8 # => 8
|
||||||
|
# ギリシャ文字などを使うことで数学的な記法が簡単にかけます。
|
||||||
|
2 * π # => 6.283185307179586
|
||||||
|
|
||||||
|
# Julia における命名習慣について:
|
||||||
|
#
|
||||||
|
# * 変数名における単語の区切りにはアンダースコアを使っても良いですが、
|
||||||
|
# 使わないと読みにくくなる、というわけではない限り、
|
||||||
|
# 推奨はされません。
|
||||||
|
#
|
||||||
|
# * 型名は大文字で始め、単語の区切りにはキャメルケースを使います。
|
||||||
|
#
|
||||||
|
# * 関数やマクロの名前は小文字で書きます。
|
||||||
|
# 単語の分かち書きにはアンダースコアをつかわず、直接つなげます。
|
||||||
|
#
|
||||||
|
# * 内部で引数を変更する関数は、名前の最後に ! をつけます。
|
||||||
|
# この手の関数は、しばしば「破壊的な関数」とか「in-place な関数」とか呼ばれます。
|
||||||
|
|
||||||
|
|
||||||
|
# 配列は、1 から始まる整数によって添字付けられる、値の列です。
|
||||||
|
a = Int64[] # => 0-element Int64 Array
|
||||||
|
|
||||||
|
# 一次元配列(列ベクトル)は、角括弧 [] のなかにカンマ , 区切りで値を並べることで作ります。
|
||||||
|
b = [4, 5, 6] # => 3-element Int64 Array: [4, 5, 6]
|
||||||
|
b[1] # => 4
|
||||||
|
b[end] # => 6
|
||||||
|
|
||||||
|
# 二次元配列は、空白区切りで作った行を、セミコロンで区切ることで作ります。
|
||||||
|
matrix = [1 2; 3 4] # => 2x2 Int64 Array: [1 2; 3 4]
|
||||||
|
|
||||||
|
# 配列の末尾に値を追加するには push! を、
|
||||||
|
# 他の配列を結合するには append! を使います。
|
||||||
|
push!(a,1) # => [1]
|
||||||
|
push!(a,2) # => [1,2]
|
||||||
|
push!(a,4) # => [1,2,4]
|
||||||
|
push!(a,3) # => [1,2,4,3]
|
||||||
|
append!(a,b) # => [1,2,4,3,4,5,6]
|
||||||
|
|
||||||
|
# 配列の末尾から値を削除するには pop! を使います。
|
||||||
|
pop!(b) # => 6 and b is now [4,5]
|
||||||
|
|
||||||
|
# 一旦元に戻しておきましょう。
|
||||||
|
push!(b,6) # b is now [4,5,6] again.
|
||||||
|
|
||||||
|
a[1] # => 1 # Julia では添字は0 ではなく1 から始まること、お忘れなく!
|
||||||
|
|
||||||
|
# end は最後の添字を表す速記法です。
|
||||||
|
# 添字を書く場所ならどこにでも使えます。
|
||||||
|
a[end] # => 6
|
||||||
|
|
||||||
|
# 先頭に対する削除・追加は shift!, unshift! です。
|
||||||
|
shift!(a) # => 1 and a is now [2,4,3,4,5,6]
|
||||||
|
unshift!(a,7) # => [7,2,4,3,4,5,6]
|
||||||
|
|
||||||
|
# ! で終わる関数名は、その引数を変更するということを示します。
|
||||||
|
arr = [5,4,6] # => 3-element Int64 Array: [5,4,6]
|
||||||
|
sort(arr) # => [4,5,6]; arr is still [5,4,6]
|
||||||
|
sort!(arr) # => [4,5,6]; arr is now [4,5,6]
|
||||||
|
|
||||||
|
# 配列の範囲外アクセスをすると BoundsError が発生します。
|
||||||
|
try
|
||||||
|
a[0] # => ERROR: BoundsError() in getindex at array.jl:270
|
||||||
|
a[end+1] # => ERROR: BoundsError() in getindex at array.jl:270
|
||||||
|
catch e
|
||||||
|
println(e)
|
||||||
|
end
|
||||||
|
|
||||||
|
# エラーが発生すると、どのファイルのどの行で発生したかが表示されます。
|
||||||
|
# 標準ライブラリで発生したものでもファイル名と行数が出ます。
|
||||||
|
# ソースからビルドした場合など、標準ライブラリのソースが手元にある場合は
|
||||||
|
# base/ ディレクトリから探し出して見てください。
|
||||||
|
|
||||||
|
# 配列は範囲オブジェクトから作ることもできます。
|
||||||
|
a = [1:5] # => 5-element Int64 Array: [1,2,3,4,5]
|
||||||
|
|
||||||
|
# 添字として範囲オブジェクトを渡すことで、
|
||||||
|
# 配列の部分列を得ることもできます。
|
||||||
|
a[1:3] # => [1, 2, 3]
|
||||||
|
a[2:end] # => [2, 3, 4, 5]
|
||||||
|
|
||||||
|
# 添字を用いて配列から値の削除をしたい場合は、splice! を使います。
|
||||||
|
arr = [3,4,5]
|
||||||
|
splice!(arr,2) # => 4 ; arr is now [3,5]
|
||||||
|
|
||||||
|
# 配列の結合は append! です。
|
||||||
|
b = [1,2,3]
|
||||||
|
append!(a,b) # Now a is [1, 2, 3, 4, 5, 1, 2, 3]
|
||||||
|
|
||||||
|
# 配列内に指定した値があるかどうかを調べるのには in を使います。
|
||||||
|
in(1, a) # => true
|
||||||
|
|
||||||
|
# length で配列の長さを取得できます。
|
||||||
|
length(a) # => 8
|
||||||
|
|
||||||
|
# 変更不可能 (immutable) な値の組として、タプルが使えます。
|
||||||
|
tup = (1, 2, 3) # => (1,2,3) # an (Int64,Int64,Int64) tuple.
|
||||||
|
tup[1] # => 1
|
||||||
|
try:
|
||||||
|
tup[1] = 3 # => ERROR: no method setindex!((Int64,Int64,Int64),Int64,Int64)
|
||||||
|
catch e
|
||||||
|
println(e)
|
||||||
|
end
|
||||||
|
|
||||||
|
# 配列に関する関数の多くが、タプルでも使えます。
|
||||||
|
length(tup) # => 3
|
||||||
|
tup[1:2] # => (1,2)
|
||||||
|
in(2, tup) # => true
|
||||||
|
|
||||||
|
# タプルから値をばらして(unpack して) 複数の変数に代入できます。
|
||||||
|
a, b, c = (1, 2, 3) # => (1,2,3) # a is now 1, b is now 2 and c is now 3
|
||||||
|
|
||||||
|
# 丸括弧なしでもタプルになります。
|
||||||
|
d, e, f = 4, 5, 6 # => (4,5,6)
|
||||||
|
|
||||||
|
# ひとつの値だけからなるタプルは、その値自体とは区別されます。
|
||||||
|
(1,) == 1 # => false
|
||||||
|
(1) == 1 # => true
|
||||||
|
|
||||||
|
# 値の交換もタプルを使えば簡単です。
|
||||||
|
e, d = d, e # => (5,4) # d is now 5 and e is now 4
|
||||||
|
|
||||||
|
|
||||||
|
# 辞書 (Dict) は、値から値への変換の集合です。
|
||||||
|
empty_dict = Dict() # => Dict{Any,Any}()
|
||||||
|
|
||||||
|
# 辞書型リテラルは次のとおりです。
|
||||||
|
filled_dict = ["one"=> 1, "two"=> 2, "three"=> 3]
|
||||||
|
# => Dict{ASCIIString,Int64}
|
||||||
|
|
||||||
|
# [] を使ったアクセスができます。
|
||||||
|
filled_dict["one"] # => 1
|
||||||
|
|
||||||
|
# すべての鍵(添字)は keys で得られます。
|
||||||
|
keys(filled_dict)
|
||||||
|
# => KeyIterator{Dict{ASCIIString,Int64}}(["three"=>3,"one"=>1,"two"=>2])
|
||||||
|
# 必ずしも辞書に追加した順番には並んでいないことに注意してください。
|
||||||
|
|
||||||
|
# 同様に、values はすべての値を返します。
|
||||||
|
values(filled_dict)
|
||||||
|
# => ValueIterator{Dict{ASCIIString,Int64}}(["three"=>3,"one"=>1,"two"=>2])
|
||||||
|
# 鍵と同様に、必ずしも辞書に追加した順番には並んでいないことに注意してください。
|
||||||
|
|
||||||
|
# in や haskey を使うことで、要素や鍵が辞書の中にあるかを調べられます。
|
||||||
|
in(("one", 1), filled_dict) # => true
|
||||||
|
in(("two", 3), filled_dict) # => false
|
||||||
|
haskey(filled_dict, "one") # => true
|
||||||
|
haskey(filled_dict, 1) # => false
|
||||||
|
|
||||||
|
# 存在しない鍵を問い合わせると、エラーが発生します。
|
||||||
|
try
|
||||||
|
filled_dict["four"] # => ERROR: key not found: four in getindex at dict.jl:489
|
||||||
|
catch e
|
||||||
|
println(e)
|
||||||
|
end
|
||||||
|
|
||||||
|
# get 関数を使い、鍵がなかった場合のデフォルト値を与えておくことで、
|
||||||
|
# このエラーを回避できます。
|
||||||
|
get(filled_dict,"one",4) # => 1
|
||||||
|
get(filled_dict,"four",4) # => 4
|
||||||
|
|
||||||
|
# 集合 (Set) は一意な値の、順序付けられていない集まりです。
|
||||||
|
empty_set = Set() # => Set{Any}()
|
||||||
|
# 集合の初期化
|
||||||
|
filled_set = Set(1,2,2,3,4) # => Set{Int64}(1,2,3,4)
|
||||||
|
|
||||||
|
# 集合への追加
|
||||||
|
push!(filled_set,5) # => Set{Int64}(5,4,2,3,1)
|
||||||
|
|
||||||
|
# in で、値が既に存在するかを調べられます。
|
||||||
|
in(2, filled_set) # => true
|
||||||
|
in(10, filled_set) # => false
|
||||||
|
|
||||||
|
# 積集合や和集合、差集合を得る関数も用意されています。
|
||||||
|
other_set = Set(3, 4, 5, 6) # => Set{Int64}(6,4,5,3)
|
||||||
|
intersect(filled_set, other_set) # => Set{Int64}(3,4,5)
|
||||||
|
union(filled_set, other_set) # => Set{Int64}(1,2,3,4,5,6)
|
||||||
|
setdiff(Set(1,2,3,4),Set(2,3,5)) # => Set{Int64}(1,4)
|
||||||
|
|
||||||
|
|
||||||
|
####################################################
|
||||||
|
## 3. 制御構文
|
||||||
|
####################################################
|
||||||
|
|
||||||
|
# まずは変数を作ります。
|
||||||
|
some_var = 5
|
||||||
|
|
||||||
|
# if 構文です。Julia ではインデントに意味はありません。
|
||||||
|
if some_var > 10
|
||||||
|
println("some_var is totally bigger than 10.")
|
||||||
|
elseif some_var < 10 # elseif 節は省略可能です。
|
||||||
|
println("some_var is smaller than 10.")
|
||||||
|
else # else 節も省略可能です。
|
||||||
|
println("some_var is indeed 10.")
|
||||||
|
end
|
||||||
|
# => "some var is smaller than 10" と出力されます。
|
||||||
|
|
||||||
|
# for ループによって、反復可能なオブジェクトを走査できます。
|
||||||
|
# 反復可能なオブジェクトの型として、
|
||||||
|
# Range, Array, Set, Dict, String などがあります。
|
||||||
|
for animal=["dog", "cat", "mouse"]
|
||||||
|
println("$animal is a mammal")
|
||||||
|
# $ を使うことで文字列に変数の値を埋め込めます。
|
||||||
|
# You can use $ to interpolate variables or expression into strings
|
||||||
|
end
|
||||||
|
# prints:
|
||||||
|
# dog is a mammal
|
||||||
|
# cat is a mammal
|
||||||
|
# mouse is a mammal
|
||||||
|
|
||||||
|
# for = の代わりに for in を使うこともできます
|
||||||
|
for animal in ["dog", "cat", "mouse"]
|
||||||
|
println("$animal is a mammal")
|
||||||
|
end
|
||||||
|
# prints:
|
||||||
|
# dog is a mammal
|
||||||
|
# cat is a mammal
|
||||||
|
# mouse is a mammal
|
||||||
|
|
||||||
|
# 辞書ではタプルが返ってきます。
|
||||||
|
for a in ["dog"=>"mammal","cat"=>"mammal","mouse"=>"mammal"]
|
||||||
|
println("$(a[1]) is a $(a[2])")
|
||||||
|
end
|
||||||
|
# prints:
|
||||||
|
# dog is a mammal
|
||||||
|
# cat is a mammal
|
||||||
|
# mouse is a mammal
|
||||||
|
|
||||||
|
# タプルのアンパック代入もできます。
|
||||||
|
for (k,v) in ["dog"=>"mammal","cat"=>"mammal","mouse"=>"mammal"]
|
||||||
|
println("$k is a $v")
|
||||||
|
end
|
||||||
|
# prints:
|
||||||
|
# dog is a mammal
|
||||||
|
# cat is a mammal
|
||||||
|
# mouse is a mammal
|
||||||
|
|
||||||
|
# while ループは、条件式がtrue となる限り実行され続けます。
|
||||||
|
x = 0
|
||||||
|
while x < 4
|
||||||
|
println(x)
|
||||||
|
x += 1 # Shorthand for x = x + 1
|
||||||
|
end
|
||||||
|
# prints:
|
||||||
|
# 0
|
||||||
|
# 1
|
||||||
|
# 2
|
||||||
|
# 3
|
||||||
|
|
||||||
|
# 例外は try/catch で捕捉できます。
|
||||||
|
try
|
||||||
|
error("help")
|
||||||
|
catch e
|
||||||
|
println("caught it $e")
|
||||||
|
end
|
||||||
|
# => caught it ErrorException("help")
|
||||||
|
|
||||||
|
|
||||||
|
####################################################
|
||||||
|
## 4. 関数
|
||||||
|
####################################################
|
||||||
|
|
||||||
|
# function キーワードを次のように使うことで、新しい関数を定義できます。
|
||||||
|
#function name(arglist)
|
||||||
|
# body...
|
||||||
|
#end
|
||||||
|
function add(x, y)
|
||||||
|
println("x is $x and y is $y")
|
||||||
|
|
||||||
|
# 最後に評価された式の値が、関数全体の返り値となります。
|
||||||
|
x + y
|
||||||
|
end
|
||||||
|
|
||||||
|
add(5, 6) # => 11 after printing out "x is 5 and y is 6"
|
||||||
|
|
||||||
|
# 可変長引数関数も定義できます。
|
||||||
|
function varargs(args...)
|
||||||
|
return args
|
||||||
|
# return キーワードを使うことで、好きな位置で関数から抜けられます。
|
||||||
|
end
|
||||||
|
# => varargs (generic function with 1 method)
|
||||||
|
|
||||||
|
varargs(1,2,3) # => (1,2,3)
|
||||||
|
|
||||||
|
# ... はsplat と呼ばれます
|
||||||
|
# (訳注:「ピシャッという音(名詞)」「衝撃で平らにする(動詞)」)
|
||||||
|
# 今回は関数定義で使いましたが、関数呼び出しに使うこともできます。
|
||||||
|
# その場合、配列やタプルの要素を開いて、複数の引数へと割り当てることとなります。
|
||||||
|
Set([1,2,3]) # => Set{Array{Int64,1}}([1,2,3]) # 「整数の配列」の集合
|
||||||
|
Set([1,2,3]...) # => Set{Int64}(1,2,3) # 整数の集合
|
||||||
|
|
||||||
|
x = (1,2,3) # => (1,2,3)
|
||||||
|
Set(x) # => Set{(Int64,Int64,Int64)}((1,2,3)) # タプルの集合
|
||||||
|
Set(x...) # => Set{Int64}(2,3,1)
|
||||||
|
|
||||||
|
|
||||||
|
# 引数に初期値を与えることで、オプション引数をもった関数を定義できます。
|
||||||
|
function defaults(a,b,x=5,y=6)
|
||||||
|
return "$a $b and $x $y"
|
||||||
|
end
|
||||||
|
|
||||||
|
defaults('h','g') # => "h g and 5 6"
|
||||||
|
defaults('h','g','j') # => "h g and j 6"
|
||||||
|
defaults('h','g','j','k') # => "h g and j k"
|
||||||
|
try
|
||||||
|
defaults('h') # => ERROR: no method defaults(Char,)
|
||||||
|
defaults() # => ERROR: no methods defaults()
|
||||||
|
catch e
|
||||||
|
println(e)
|
||||||
|
end
|
||||||
|
|
||||||
|
# キーワード引数を持った関数も作れます。
|
||||||
|
function keyword_args(;k1=4,name2="hello") # ; が必要なことに注意
|
||||||
|
return ["k1"=>k1,"name2"=>name2]
|
||||||
|
end
|
||||||
|
|
||||||
|
keyword_args(name2="ness") # => ["name2"=>"ness","k1"=>4]
|
||||||
|
keyword_args(k1="mine") # => ["k1"=>"mine","name2"=>"hello"]
|
||||||
|
keyword_args() # => ["name2"=>"hello","k1"=>4]
|
||||||
|
|
||||||
|
# もちろん、これらを組み合わせることもできます。
|
||||||
|
function all_the_args(normal_arg, optional_positional_arg=2; keyword_arg="foo")
|
||||||
|
println("normal arg: $normal_arg")
|
||||||
|
println("optional arg: $optional_positional_arg")
|
||||||
|
println("keyword arg: $keyword_arg")
|
||||||
|
end
|
||||||
|
|
||||||
|
all_the_args(1, 3, keyword_arg=4)
|
||||||
|
# prints:
|
||||||
|
# normal arg: 1
|
||||||
|
# optional arg: 3
|
||||||
|
# keyword arg: 4
|
||||||
|
|
||||||
|
# Julia では関数は第一級関数として、値として扱われます。
|
||||||
|
function create_adder(x)
|
||||||
|
adder = function (y)
|
||||||
|
return x + y
|
||||||
|
end
|
||||||
|
return adder
|
||||||
|
end
|
||||||
|
|
||||||
|
# ラムダ式によって無名関数をつくれます。
|
||||||
|
(x -> x > 2)(3) # => true
|
||||||
|
|
||||||
|
# 先ほどの create_adder と同じもの
|
||||||
|
function create_adder(x)
|
||||||
|
y -> x + y
|
||||||
|
end
|
||||||
|
|
||||||
|
# 中の関数に名前をつけても構いません。
|
||||||
|
function create_adder(x)
|
||||||
|
function adder(y)
|
||||||
|
x + y
|
||||||
|
end
|
||||||
|
adder
|
||||||
|
end
|
||||||
|
|
||||||
|
add_10 = create_adder(10)
|
||||||
|
add_10(3) # => 13
|
||||||
|
|
||||||
|
|
||||||
|
# いくつかの高階関数が定義されています。
|
||||||
|
map(add_10, [1,2,3]) # => [11, 12, 13]
|
||||||
|
filter(x -> x > 5, [3, 4, 5, 6, 7]) # => [6, 7]
|
||||||
|
|
||||||
|
# map の代わりとしてリスト内包表記も使えます。
|
||||||
|
[add_10(i) for i=[1, 2, 3]] # => [11, 12, 13]
|
||||||
|
[add_10(i) for i in [1, 2, 3]] # => [11, 12, 13]
|
||||||
|
|
||||||
|
####################################################
|
||||||
|
## 5. 型
|
||||||
|
####################################################
|
||||||
|
|
||||||
|
# Julia ではすべての値にひとつの型がついています。
|
||||||
|
# 変数に、ではなくて値に、です。
|
||||||
|
# typeof 関数を使うことで、値が持つ型を取得できます。
|
||||||
|
typeof(5) # => Int64
|
||||||
|
|
||||||
|
# 型自身もまた、第一級の値であり、型を持っています。
|
||||||
|
typeof(Int64) # => DataType
|
||||||
|
typeof(DataType) # => DataType
|
||||||
|
# DataType は型を表現する型であり、DataType 自身もDataType 型の値です。
|
||||||
|
|
||||||
|
# 型はドキュメント化や最適化、関数ディスパッチのために使われます。
|
||||||
|
# 静的な型チェックは行われません。
|
||||||
|
|
||||||
|
# 自分で新しい型を定義することもできます。
|
||||||
|
# 他の言語で言う、構造体やレコードに近いものになっています。
|
||||||
|
# 型定義には type キーワードを使います。
|
||||||
|
# type Name
|
||||||
|
# field::OptionalType
|
||||||
|
# ...
|
||||||
|
# end
|
||||||
|
type Tiger
|
||||||
|
taillength::Float64
|
||||||
|
coatcolor # 型注釈を省略した場合、自動的に :: Any として扱われます。
|
||||||
|
end
|
||||||
|
|
||||||
|
# 型を定義すると、その型のプロパティすべてを、定義した順番に
|
||||||
|
# 引数として持つデフォルトコンストラクタが自動的に作られます。
|
||||||
|
tigger = Tiger(3.5,"orange") # => Tiger(3.5,"orange")
|
||||||
|
|
||||||
|
# 型名がそのままコンストラクタ名(関数名)となります。
|
||||||
|
sherekhan = typeof(tigger)(5.6,"fire") # => Tiger(5.6,"fire")
|
||||||
|
|
||||||
|
# このような、構造体スタイルの型は、具体型(concrete type)と呼ばれます。
|
||||||
|
# 具体型はインスタンス化可能ですが、派生型(subtype)を持つことができません。
|
||||||
|
# 具体型の他には抽象型(abstract type)があります。
|
||||||
|
|
||||||
|
# abstract Name
|
||||||
|
abstract Cat # 型の階層図の途中の一点を指し示す名前となります。
|
||||||
|
|
||||||
|
# 抽象型はインスタンス化できませんが、派生型を持つことができます。
|
||||||
|
# 例えば、 Number は以下の派生型を持つ抽象型です。
|
||||||
|
subtypes(Number) # => 6-element Array{Any,1}:
|
||||||
|
# Complex{Float16}
|
||||||
|
# Complex{Float32}
|
||||||
|
# Complex{Float64}
|
||||||
|
# Complex{T<:Real}
|
||||||
|
# ImaginaryUnit
|
||||||
|
# Real
|
||||||
|
subtypes(Cat) # => 0-element Array{Any,1}
|
||||||
|
|
||||||
|
# すべての型は、直接的にはただひとつの基本型(supertype) を持ちます。
|
||||||
|
# super 関数でこれを取得可能です。
|
||||||
|
typeof(5) # => Int64
|
||||||
|
super(Int64) # => Signed
|
||||||
|
super(Signed) # => Real
|
||||||
|
super(Real) # => Number
|
||||||
|
super(Number) # => Any
|
||||||
|
super(super(Signed)) # => Number
|
||||||
|
super(Any) # => Any
|
||||||
|
# Int64 を除き、これらはすべて抽象型です。
|
||||||
|
|
||||||
|
# <: は派生形を表す演算子です。
|
||||||
|
# これを使うことで派生型を定義できます。
|
||||||
|
type Lion <: Cat # Lion は 抽象型 Cat の派生型
|
||||||
|
mane_color
|
||||||
|
roar::String
|
||||||
|
end
|
||||||
|
|
||||||
|
# 型名と同じ名前の関数を定義し、既に存在するコンストラクタを呼び出して、
|
||||||
|
# 必要とする型の値を返すことによって、
|
||||||
|
# デフォルトコンストラクタ以外のコンストラクタを作ることができます。
|
||||||
|
|
||||||
|
Lion(roar::String) = Lion("green",roar)
|
||||||
|
# 型定義の外側で定義されたコンストラクタなので、外部コンストラクタと呼ばれます。
|
||||||
|
|
||||||
|
type Panther <: Cat # Panther も Cat の派生型
|
||||||
|
eye_color
|
||||||
|
Panther() = new("green")
|
||||||
|
# Panther は内部コンストラクタとしてこれのみを持ち、
|
||||||
|
# デフォルトコンストラクタを持たない
|
||||||
|
end
|
||||||
|
# 内部コンストラクタを使うことで、どのような値が作られるのかをコントロールすることができます。
|
||||||
|
# 出来る限り、外部コンストラクタを使うべきです。
|
||||||
|
|
||||||
|
####################################################
|
||||||
|
## 6. 多重ディスパッチ
|
||||||
|
####################################################
|
||||||
|
|
||||||
|
# Julia では、すべての名前付きの関数は総称的関数(generic function) です。
|
||||||
|
# これは、関数はいくつかの細かいメソッドの集合である、という意味です。
|
||||||
|
# 例えば先の Lion 型のコンストラクタ Lion は、Lion という関数の1つのメソッドです。
|
||||||
|
|
||||||
|
# コンストラクタ以外の例をみるために、新たに meow 関数を作りましょう。
|
||||||
|
|
||||||
|
# Lion, Panther, Tiger 型それぞれに対する meow 関数のメソッド定義
|
||||||
|
function meow(animal::Lion)
|
||||||
|
animal.roar # 型のプロパティには . でアクセスできます。
|
||||||
|
end
|
||||||
|
|
||||||
|
function meow(animal::Panther)
|
||||||
|
"grrr"
|
||||||
|
end
|
||||||
|
|
||||||
|
function meow(animal::Tiger)
|
||||||
|
"rawwwr"
|
||||||
|
end
|
||||||
|
|
||||||
|
# meow 関数の実行
|
||||||
|
meow(tigger) # => "rawwr"
|
||||||
|
meow(Lion("brown","ROAAR")) # => "ROAAR"
|
||||||
|
meow(Panther()) # => "grrr"
|
||||||
|
|
||||||
|
# 型の階層関係を見てみましょう
|
||||||
|
issubtype(Tiger,Cat) # => false
|
||||||
|
issubtype(Lion,Cat) # => true
|
||||||
|
issubtype(Panther,Cat) # => true
|
||||||
|
|
||||||
|
# 抽象型 Cat の派生型を引数にとる関数
|
||||||
|
function pet_cat(cat::Cat)
|
||||||
|
println("The cat says $(meow(cat))")
|
||||||
|
end
|
||||||
|
|
||||||
|
pet_cat(Lion("42")) # => prints "The cat says 42"
|
||||||
|
try
|
||||||
|
pet_cat(tigger) # => ERROR: no method pet_cat(Tiger,)
|
||||||
|
catch e
|
||||||
|
println(e)
|
||||||
|
end
|
||||||
|
|
||||||
|
# オブジェクト指向言語では、一般的にシングルディスパッチが用いられます。
|
||||||
|
# つまり、関数に複数あるメソッドのうちにどれが呼ばれるかは、
|
||||||
|
# その第一引数(もしくは、 . や -> の前にある値の型)によってのみ決定されます。
|
||||||
|
# 一方でJulia では、すべての引数の型が、このメソッド決定に寄与します。
|
||||||
|
|
||||||
|
# 多変数関数を定義して、この辺りを見て行きましょう。
|
||||||
|
function fight(t::Tiger,c::Cat)
|
||||||
|
println("The $(t.coatcolor) tiger wins!")
|
||||||
|
end
|
||||||
|
# => fight (generic function with 1 method)
|
||||||
|
|
||||||
|
fight(tigger,Panther()) # => prints The orange tiger wins!
|
||||||
|
fight(tigger,Lion("ROAR")) # => prints The orange tiger wins!
|
||||||
|
|
||||||
|
# 第二引数の Cat が実際は Lion だった時に、挙動が変わるようにします。
|
||||||
|
fight(t::Tiger,l::Lion) = println("The $(l.mane_color)-maned lion wins!")
|
||||||
|
# => fight (generic function with 2 methods)
|
||||||
|
|
||||||
|
fight(tigger,Panther()) # => prints The orange tiger wins!
|
||||||
|
fight(tigger,Lion("ROAR")) # => prints The green-maned lion wins!
|
||||||
|
|
||||||
|
# 別に Tiger だけが戦う必要もないですね。
|
||||||
|
fight(l::Lion,c::Cat) = println("The victorious cat says $(meow(c))")
|
||||||
|
# => fight (generic function with 3 methods)
|
||||||
|
|
||||||
|
fight(Lion("balooga!"),Panther()) # => prints The victorious cat says grrr
|
||||||
|
try
|
||||||
|
fight(Panther(),Lion("RAWR")) # => ERROR: no method fight(Panther,Lion)
|
||||||
|
catch
|
||||||
|
end
|
||||||
|
|
||||||
|
# 第一引数にも Cat を許しましょう。
|
||||||
|
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)
|
||||||
|
|
||||||
|
# 警告が出ましたが、これは次の対戦で何が起きるのかが不明瞭だからです。
|
||||||
|
fight(Lion("RAR"),Lion("brown","rarrr")) # => prints The victorious cat says rarrr
|
||||||
|
# Julia のバージョンによっては、結果が違うかもしれません。
|
||||||
|
|
||||||
|
fight(l::Lion,l2::Lion) = println("The lions come to a tie")
|
||||||
|
fight(Lion("RAR"),Lion("brown","rarrr")) # => prints The lions come to a tie
|
||||||
|
|
||||||
|
|
||||||
|
# Julia が生成する LLVM 内部表現や、アセンブリを調べることもできます。
|
||||||
|
|
||||||
|
square_area(l) = l * l # square_area (generic function with 1 method)
|
||||||
|
|
||||||
|
square_area(5) #25
|
||||||
|
|
||||||
|
# square_area に整数を渡すと何が起きる?
|
||||||
|
code_native(square_area, (Int32,))
|
||||||
|
# .section __TEXT,__text,regular,pure_instructions
|
||||||
|
# Filename: none
|
||||||
|
# Source line: 1 # Prologue
|
||||||
|
# push RBP
|
||||||
|
# mov RBP, RSP
|
||||||
|
# Source line: 1
|
||||||
|
# movsxd RAX, EDI # l を取得
|
||||||
|
# imul RAX, RAX # l*l を計算して RAX に入れる
|
||||||
|
# pop RBP # Base Pointer を元に戻す
|
||||||
|
# ret # 終了。RAX の中身が結果
|
||||||
|
|
||||||
|
code_native(square_area, (Float32,))
|
||||||
|
# .section __TEXT,__text,regular,pure_instructions
|
||||||
|
# Filename: none
|
||||||
|
# Source line: 1
|
||||||
|
# push RBP
|
||||||
|
# mov RBP, RSP
|
||||||
|
# Source line: 1
|
||||||
|
# vmulss XMM0, XMM0, XMM0 # 単精度浮動小数点数演算 (AVX)
|
||||||
|
# pop RBP
|
||||||
|
# ret
|
||||||
|
|
||||||
|
code_native(square_area, (Float64,))
|
||||||
|
# .section __TEXT,__text,regular,pure_instructions
|
||||||
|
# Filename: none
|
||||||
|
# Source line: 1
|
||||||
|
# push RBP
|
||||||
|
# mov RBP, RSP
|
||||||
|
# Source line: 1
|
||||||
|
# vmulsd XMM0, XMM0, XMM0 # 倍精度浮動小数点数演算 (AVX)
|
||||||
|
# pop RBP
|
||||||
|
# ret
|
||||||
|
#
|
||||||
|
|
||||||
|
# Julia では、浮動小数点数と整数との演算では
|
||||||
|
# 自動的に浮動小数点数用の命令が生成されることに注意してください。
|
||||||
|
# 円の面積を計算してみましょう。
|
||||||
|
circle_area(r) = pi * r * r # circle_area (generic function with 1 method)
|
||||||
|
circle_area(5) # 78.53981633974483
|
||||||
|
|
||||||
|
code_native(circle_area, (Int32,))
|
||||||
|
# .section __TEXT,__text,regular,pure_instructions
|
||||||
|
# Filename: none
|
||||||
|
# Source line: 1
|
||||||
|
# push RBP
|
||||||
|
# mov RBP, RSP
|
||||||
|
# Source line: 1
|
||||||
|
# vcvtsi2sd XMM0, XMM0, EDI # Load integer (r) from memory
|
||||||
|
# movabs RAX, 4593140240 # Load pi
|
||||||
|
# vmulsd XMM1, XMM0, QWORD PTR [RAX] # pi * r
|
||||||
|
# vmulsd XMM0, XMM0, XMM1 # (pi * r) * r
|
||||||
|
# pop RBP
|
||||||
|
# ret
|
||||||
|
#
|
||||||
|
|
||||||
|
code_native(circle_area, (Float64,))
|
||||||
|
# .section __TEXT,__text,regular,pure_instructions
|
||||||
|
# Filename: none
|
||||||
|
# Source line: 1
|
||||||
|
# push RBP
|
||||||
|
# mov RBP, RSP
|
||||||
|
# movabs RAX, 4593140496
|
||||||
|
# Source line: 1
|
||||||
|
# vmulsd XMM1, XMM0, QWORD PTR [RAX]
|
||||||
|
# vmulsd XMM0, XMM1, XMM0
|
||||||
|
# pop RBP
|
||||||
|
# ret
|
||||||
|
#
|
||||||
|
```
|
||||||
|
|
||||||
|
## より勉強するために
|
||||||
|
|
||||||
|
[公式ドキュメント](http://docs.julialang.org/en/latest/manual/) (英語)にはより詳細な解説が記されています。
|
||||||
|
|
||||||
|
Julia に関して助けが必要ならば、[メーリングリスト](https://groups.google.com/forum/#!forum/julia-users) が役に立ちます。
|
||||||
|
みんな非常に親密に教えてくれます。
|
||||||
|
|
590
pt-br/c++-pt.html.markdown
Normal file
590
pt-br/c++-pt.html.markdown
Normal file
@ -0,0 +1,590 @@
|
|||||||
|
---
|
||||||
|
language: c++
|
||||||
|
filename: learncpp.cpp
|
||||||
|
contributors:
|
||||||
|
- ["Steven Basart", "http://github.com/xksteven"]
|
||||||
|
- ["Matt Kline", "https://github.com/mrkline"]
|
||||||
|
translators:
|
||||||
|
- ["Miguel Araújo", "https://github.com/miguelarauj1o"]
|
||||||
|
lang: pt-br
|
||||||
|
---
|
||||||
|
|
||||||
|
C++ é uma linguagem de programação de sistemas que,
|
||||||
|
[de acordo com seu inventor Bjarne Stroustrup](http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2014/Keynote),
|
||||||
|
foi concebida para
|
||||||
|
|
||||||
|
- ser um "C melhor"
|
||||||
|
- suportar abstração de dados
|
||||||
|
- suportar programação orientada a objetos
|
||||||
|
- suportar programação genérica
|
||||||
|
|
||||||
|
Embora sua sintaxe pode ser mais difícil ou complexa do que as linguagens mais
|
||||||
|
recentes, C++ é amplamente utilizado porque compila para instruções nativas que
|
||||||
|
podem ser executadas diretamente pelo processador e oferece um controlo rígido sobre hardware (como C), enquanto oferece recursos de alto nível, como os
|
||||||
|
genéricos, exceções e classes. Esta combinação de velocidade e funcionalidade
|
||||||
|
faz C++ uma das linguagens de programação mais utilizadas.
|
||||||
|
|
||||||
|
```c++
|
||||||
|
//////////////////
|
||||||
|
// Comparação com C
|
||||||
|
//////////////////
|
||||||
|
|
||||||
|
// C ++ é quase um super conjunto de C e compartilha sua sintaxe básica para
|
||||||
|
// declarações de variáveis, tipos primitivos, e funções. No entanto, C++ varia
|
||||||
|
// em algumas das seguintes maneiras:
|
||||||
|
|
||||||
|
// A função main() em C++ deve retornar um int, embora void main() é aceita
|
||||||
|
// pela maioria dos compiladores (gcc, bumbum, etc.)
|
||||||
|
// Este valor serve como o status de saída do programa.
|
||||||
|
// Veja http://en.wikipedia.org/wiki/Exit_status para mais informações.
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
// Argumentos de linha de comando são passados em pelo argc e argv da mesma
|
||||||
|
// forma que eles estão em C.
|
||||||
|
// argc indica o número de argumentos,
|
||||||
|
// e argv é um array de strings, feito C (char*) representado os argumentos
|
||||||
|
// O primeiro argumento é o nome pelo qual o programa foi chamado.
|
||||||
|
// argc e argv pode ser omitido se você não se importa com argumentos,
|
||||||
|
// dando a assinatura da função de int main()
|
||||||
|
|
||||||
|
// Uma saída de status de 0 indica sucesso.
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Em C++, caracteres literais são um byte.
|
||||||
|
sizeof('c') == 1
|
||||||
|
|
||||||
|
// Em C, caracteres literais são do mesmo tamanho que ints.
|
||||||
|
sizeof('c') == sizeof(10)
|
||||||
|
|
||||||
|
// C++ tem prototipagem estrita
|
||||||
|
void func(); // função que não aceita argumentos
|
||||||
|
|
||||||
|
// Em C
|
||||||
|
void func(); // função que pode aceitar qualquer número de argumentos
|
||||||
|
|
||||||
|
// Use nullptr em vez de NULL em C++
|
||||||
|
int* ip = nullptr;
|
||||||
|
|
||||||
|
// Cabeçalhos padrão C estão disponíveis em C++,
|
||||||
|
// mas são prefixados com "c" e não têm sufixo .h
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
printf("Hello, world!\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////
|
||||||
|
// Sobrecarga de função
|
||||||
|
///////////////////////
|
||||||
|
|
||||||
|
// C++ suporta sobrecarga de função
|
||||||
|
// desde que cada função tenha parâmetros diferentes.
|
||||||
|
|
||||||
|
void print(char const* myString)
|
||||||
|
{
|
||||||
|
printf("String %s\n", myString);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print(int myInt)
|
||||||
|
{
|
||||||
|
printf("My int is %d", myInt);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
print("Hello"); // Funciona para void print(const char*)
|
||||||
|
print(15); // Funciona para void print(int)
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////
|
||||||
|
// Parâmetros padrão de função
|
||||||
|
/////////////////////////////
|
||||||
|
|
||||||
|
// Você pode fornecer argumentos padrões para uma função se eles não são
|
||||||
|
// fornecidos pelo chamador.
|
||||||
|
|
||||||
|
void doSomethingWithInts(int a = 1, int b = 4)
|
||||||
|
{
|
||||||
|
// Faça alguma coisa com os ints aqui
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
doSomethingWithInts(); // a = 1, b = 4
|
||||||
|
doSomethingWithInts(20); // a = 20, b = 4
|
||||||
|
doSomethingWithInts(20, 5); // a = 20, b = 5
|
||||||
|
}
|
||||||
|
|
||||||
|
// Argumentos padrões devem estar no final da lista de argumentos.
|
||||||
|
|
||||||
|
void invalidDeclaration(int a = 1, int b) // Erro!
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/////////////
|
||||||
|
// Namespaces (nome de espaços)
|
||||||
|
/////////////
|
||||||
|
|
||||||
|
// Namespaces fornecem escopos distintos para variável, função e outras
|
||||||
|
// declarações. Namespaces podem estar aninhados.
|
||||||
|
|
||||||
|
namespace First {
|
||||||
|
namespace Nested {
|
||||||
|
void foo()
|
||||||
|
{
|
||||||
|
printf("This is First::Nested::foo\n");
|
||||||
|
}
|
||||||
|
} // Fim do namespace aninhado
|
||||||
|
} // Fim do namespace First
|
||||||
|
|
||||||
|
namespace Second {
|
||||||
|
void foo()
|
||||||
|
{
|
||||||
|
printf("This is Second::foo\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void foo()
|
||||||
|
{
|
||||||
|
printf("This is global foo\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// Assuma que tudo é do namespace "Second" a menos que especificado de
|
||||||
|
// outra forma.
|
||||||
|
using namespace Second;
|
||||||
|
|
||||||
|
foo(); // imprime "This is Second::foo"
|
||||||
|
First::Nested::foo(); // imprime "This is First::Nested::foo"
|
||||||
|
::foo(); // imprime "This is global foo"
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////
|
||||||
|
// Entrada/Saída
|
||||||
|
///////////////
|
||||||
|
|
||||||
|
// C ++ usa a entrada e saída de fluxos (streams)
|
||||||
|
// cin, cout, and cerr representa stdin, stdout, and stderr.
|
||||||
|
// << É o operador de inserção e >> é o operador de extração.
|
||||||
|
|
||||||
|
#include <iostream> // Inclusão para o I/O streams
|
||||||
|
|
||||||
|
using namespace std; // Streams estão no namespace std (biblioteca padrão)
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
int myInt;
|
||||||
|
|
||||||
|
// Imprime na saída padrão (ou terminal/tela)
|
||||||
|
cout << "Enter your favorite number:\n";
|
||||||
|
// Pega a entrada
|
||||||
|
cin >> myInt;
|
||||||
|
|
||||||
|
// cout também pode ser formatado
|
||||||
|
cout << "Your favorite number is " << myInt << "\n";
|
||||||
|
// imprime "Your favorite number is <myInt>"
|
||||||
|
|
||||||
|
cerr << "Usado para mensagens de erro";
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////
|
||||||
|
// Strings
|
||||||
|
//////////
|
||||||
|
|
||||||
|
// Strings em C++ são objetos e têm muitas funções de membro
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
using namespace std; // Strings também estão no namespace std (bib. padrão)
|
||||||
|
|
||||||
|
string myString = "Hello";
|
||||||
|
string myOtherString = " World";
|
||||||
|
|
||||||
|
// + é usado para concatenação.
|
||||||
|
cout << myString + myOtherString; // "Hello World"
|
||||||
|
|
||||||
|
cout << myString + " You"; // "Hello You"
|
||||||
|
|
||||||
|
// Em C++, strings são mutáveis e têm valores semânticos.
|
||||||
|
myString.append(" Dog");
|
||||||
|
cout << myString; // "Hello Dog"
|
||||||
|
|
||||||
|
|
||||||
|
/////////////
|
||||||
|
// Referência
|
||||||
|
/////////////
|
||||||
|
|
||||||
|
// Além de indicadores como os de C, C++ têm _referências_. Esses são tipos de
|
||||||
|
// ponteiro que não pode ser reatribuída uma vez definidos e não pode ser nulo.
|
||||||
|
// Eles também têm a mesma sintaxe que a própria variável: Não * é necessário
|
||||||
|
// para _dereferencing_ e & (endereço de) não é usado para atribuição.
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
string foo = "I am foo";
|
||||||
|
string bar = "I am bar";
|
||||||
|
|
||||||
|
|
||||||
|
string& fooRef = foo; // Isso cria uma referência para foo.
|
||||||
|
fooRef += ". Hi!"; // Modifica foo através da referência
|
||||||
|
cout << fooRef; // Imprime "I am foo. Hi!"
|
||||||
|
|
||||||
|
// Não realocar "fooRef". Este é o mesmo que "foo = bar", e foo == "I am bar"
|
||||||
|
// depois desta linha.
|
||||||
|
|
||||||
|
fooRef = bar;
|
||||||
|
|
||||||
|
const string& barRef = bar; // Cria uma referência const para bar.
|
||||||
|
// Como C, valores const (e ponteiros e referências) não podem ser modificado.
|
||||||
|
barRef += ". Hi!"; // Erro, referência const não pode ser modificada.
|
||||||
|
|
||||||
|
//////////////////////////////////////////
|
||||||
|
// Classes e programação orientada a objeto
|
||||||
|
//////////////////////////////////////////
|
||||||
|
|
||||||
|
// Primeiro exemplo de classes
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
// Declara a classe.
|
||||||
|
// As classes são geralmente declarado no cabeçalho arquivos (.h ou .hpp).
|
||||||
|
class Dog {
|
||||||
|
// Variáveis de membro e funções são privadas por padrão.
|
||||||
|
std::string name;
|
||||||
|
int weight;
|
||||||
|
|
||||||
|
// Todos os membros a seguir este são públicos até que "private:" ou
|
||||||
|
// "protected:" é encontrado.
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Construtor padrão
|
||||||
|
Dog();
|
||||||
|
|
||||||
|
// Declarações de função Membro (implementações a seguir)
|
||||||
|
// Note que usamos std :: string aqui em vez de colocar
|
||||||
|
// using namespace std;
|
||||||
|
// acima.
|
||||||
|
// Nunca coloque uma declaração "using namespace" em um cabeçalho.
|
||||||
|
void setName(const std::string& dogsName);
|
||||||
|
|
||||||
|
void setWeight(int dogsWeight);
|
||||||
|
|
||||||
|
// Funções que não modificam o estado do objecto devem ser marcadas como
|
||||||
|
// const. Isso permite que você chamá-los se for dada uma referência const
|
||||||
|
// para o objeto. Além disso, observe as funções devem ser explicitamente
|
||||||
|
// declarados como _virtual_, a fim de ser substituídas em classes
|
||||||
|
// derivadas. As funções não são virtuais por padrão por razões de
|
||||||
|
// performance.
|
||||||
|
|
||||||
|
virtual void print() const;
|
||||||
|
|
||||||
|
// As funções também podem ser definidas no interior do corpo da classe.
|
||||||
|
// Funções definidas como tal são automaticamente embutidas.
|
||||||
|
void bark() const { std::cout << name << " barks!\n" }
|
||||||
|
|
||||||
|
// Junto com os construtores, C++ fornece destruidores.
|
||||||
|
// Estes são chamados quando um objeto é excluído ou fica fora do escopo.
|
||||||
|
// Isto permite paradigmas poderosos, como RAII
|
||||||
|
// (veja abaixo)
|
||||||
|
// Destruidores devem ser virtual para permitir que as classes de ser
|
||||||
|
// derivada desta.
|
||||||
|
virtual ~Dog();
|
||||||
|
|
||||||
|
}; // Um ponto e vírgula deve seguir a definição de classe.
|
||||||
|
|
||||||
|
// Funções membro da classe geralmente são implementados em arquivos .cpp.
|
||||||
|
void Dog::Dog()
|
||||||
|
{
|
||||||
|
std::cout << "A dog has been constructed\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Objetos (como strings) devem ser passados por referência
|
||||||
|
// se você está modificando-os ou referência const se você não é.
|
||||||
|
void Dog::setName(const std::string& dogsName)
|
||||||
|
{
|
||||||
|
name = dogsName;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Dog::setWeight(int dogsWeight)
|
||||||
|
{
|
||||||
|
weight = dogsWeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Observe que "virtual" só é necessária na declaração, não a definição.
|
||||||
|
void Dog::print() const
|
||||||
|
{
|
||||||
|
std::cout << "Dog is " << name << " and weighs " << weight << "kg\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
void Dog::~Dog()
|
||||||
|
{
|
||||||
|
cout << "Goodbye " << name << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
Dog myDog; // imprime "A dog has been constructed"
|
||||||
|
myDog.setName("Barkley");
|
||||||
|
myDog.setWeight(10);
|
||||||
|
myDog.printDog(); // imprime "Dog is Barkley and weighs 10 kg"
|
||||||
|
return 0;
|
||||||
|
} // imprime "Goodbye Barkley"
|
||||||
|
|
||||||
|
// herança:
|
||||||
|
|
||||||
|
// Essa classe herda tudo público e protegido da classe Dog
|
||||||
|
class OwnedDog : public Dog {
|
||||||
|
|
||||||
|
void setOwner(const std::string& dogsOwner)
|
||||||
|
|
||||||
|
// Substituir o comportamento da função de impressão de todas OwnedDogs.
|
||||||
|
// Ver http://en.wikipedia.org/wiki/Polymorphism_(computer_science)#Subtyping
|
||||||
|
// Para uma introdução mais geral, se você não estiver familiarizado com o
|
||||||
|
// polimorfismo subtipo. A palavra-chave override é opcional, mas torna-se
|
||||||
|
// na verdade você está substituindo o método em uma classe base.
|
||||||
|
void print() const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string owner;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Enquanto isso, no arquivo .cpp correspondente:
|
||||||
|
|
||||||
|
void OwnedDog::setOwner(const std::string& dogsOwner)
|
||||||
|
{
|
||||||
|
owner = dogsOwner;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OwnedDog::print() const
|
||||||
|
{
|
||||||
|
Dog::print(); // Chame a função de impressão na classe Dog base de
|
||||||
|
std::cout << "Dog is owned by " << owner << "\n";
|
||||||
|
// Prints "Dog is <name> and weights <weight>"
|
||||||
|
// "Dog is owned by <owner>"
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////
|
||||||
|
// Inicialização e Sobrecarga de Operadores
|
||||||
|
//////////////////////////////////////////
|
||||||
|
|
||||||
|
// Em C ++, você pode sobrecarregar o comportamento dos operadores, tais como
|
||||||
|
// +, -, *, /, etc. Isto é feito através da definição de uma função que é
|
||||||
|
// chamado sempre que o operador é usado.
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
class Point {
|
||||||
|
public:
|
||||||
|
// Variáveis membro pode ser dado valores padrão desta maneira.
|
||||||
|
double x = 0;
|
||||||
|
double y = 0;
|
||||||
|
|
||||||
|
// Define um construtor padrão que não faz nada
|
||||||
|
// mas inicializar o Point para o valor padrão (0, 0)
|
||||||
|
Point() { };
|
||||||
|
|
||||||
|
// A sintaxe a seguir é conhecido como uma lista de inicialização
|
||||||
|
// e é a maneira correta de inicializar os valores de membro de classe
|
||||||
|
Point (double a, double b) :
|
||||||
|
x(a),
|
||||||
|
y(b)
|
||||||
|
{ /* Não fazer nada, exceto inicializar os valores */ }
|
||||||
|
|
||||||
|
// Sobrecarrega o operador +.
|
||||||
|
Point operator+(const Point& rhs) const;
|
||||||
|
|
||||||
|
// Sobrecarregar o operador +=.
|
||||||
|
Point& operator+=(const Point& rhs);
|
||||||
|
|
||||||
|
// Ele também faria sentido para adicionar os operadores - e -=,
|
||||||
|
// mas vamos pular para sermos breves.
|
||||||
|
};
|
||||||
|
|
||||||
|
Point Point::operator+(const Point& rhs) const
|
||||||
|
{
|
||||||
|
// Criar um novo ponto que é a soma de um e rhs.
|
||||||
|
return Point(x + rhs.x, y + rhs.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
Point& Point::operator+=(const Point& rhs)
|
||||||
|
{
|
||||||
|
x += rhs.x;
|
||||||
|
y += rhs.y;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main () {
|
||||||
|
Point up (0,1);
|
||||||
|
Point right (1,0);
|
||||||
|
// Isto chama que o operador ponto +
|
||||||
|
// Ressalte-se a chamadas (função)+ com direito como seu parâmetro...
|
||||||
|
Point result = up + right;
|
||||||
|
// Imprime "Result is upright (1,1)"
|
||||||
|
cout << "Result is upright (" << result.x << ',' << result.y << ")\n";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////
|
||||||
|
// Tratamento de Exceções
|
||||||
|
/////////////////////////
|
||||||
|
|
||||||
|
// A biblioteca padrão fornece alguns tipos de exceção
|
||||||
|
// (see http://en.cppreference.com/w/cpp/error/exception)
|
||||||
|
// mas qualquer tipo pode ser jogado como uma exceção
|
||||||
|
#include <exception>
|
||||||
|
|
||||||
|
// Todas as exceções lançadas dentro do bloco try pode ser capturado por
|
||||||
|
// manipuladores de captura subseqüentes
|
||||||
|
try {
|
||||||
|
// Não aloca exceções no heap usando _new_.
|
||||||
|
throw std::exception("A problem occurred");
|
||||||
|
}
|
||||||
|
// Capturar exceções por referência const se eles são objetos
|
||||||
|
catch (const std::exception& ex)
|
||||||
|
{
|
||||||
|
std::cout << ex.what();
|
||||||
|
// Captura qualquer exceção não capturada pelos blocos _catch_ anteriores
|
||||||
|
} catch (...)
|
||||||
|
{
|
||||||
|
std::cout << "Exceção desconhecida encontrada";
|
||||||
|
throw; // Re-lança a exceção
|
||||||
|
}
|
||||||
|
|
||||||
|
///////
|
||||||
|
// RAII
|
||||||
|
///////
|
||||||
|
|
||||||
|
// RAII significa alocação de recursos é de inicialização.
|
||||||
|
// Muitas vezes, é considerado o paradigma mais poderoso em C++, e é o
|
||||||
|
// conceito simples que um construtor para um objeto adquire recursos daquele
|
||||||
|
// objeto e o destruidor liberá-los.
|
||||||
|
|
||||||
|
// Para entender como isso é útil,
|
||||||
|
// Considere uma função que usa um identificador de arquivo C:
|
||||||
|
void doSomethingWithAFile(const char* filename)
|
||||||
|
{
|
||||||
|
// Para começar, assuma que nada pode falhar.
|
||||||
|
|
||||||
|
FILE* fh = fopen(filename, "r"); // Abra o arquivo em modo de leitura.
|
||||||
|
|
||||||
|
doSomethingWithTheFile(fh);
|
||||||
|
doSomethingElseWithIt(fh);
|
||||||
|
|
||||||
|
fclose(fh); // Feche o arquivo.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Infelizmente, as coisas são levemente complicadas para tratamento de erros.
|
||||||
|
// Suponha que fopen pode falhar, e que doSomethingWithTheFile e
|
||||||
|
// doSomethingElseWithIt retornam códigos de erro se eles falharem. (As
|
||||||
|
// exceções são a forma preferida de lidar com o fracasso, mas alguns
|
||||||
|
// programadores, especialmente aqueles com um conhecimento em C, discordam
|
||||||
|
// sobre a utilidade de exceções). Agora temos que verificar cada chamada para
|
||||||
|
// o fracasso e fechar o identificador de arquivo se ocorreu um problema.
|
||||||
|
|
||||||
|
bool doSomethingWithAFile(const char* filename)
|
||||||
|
{
|
||||||
|
FILE* fh = fopen(filename, "r"); // Abra o arquivo em modo de leitura
|
||||||
|
if (fh == nullptr) // O ponteiro retornado é nulo em caso de falha.
|
||||||
|
reuturn false; // Relate o fracasso para o chamador.
|
||||||
|
|
||||||
|
// Suponha cada função retorne false, se falhar
|
||||||
|
if (!doSomethingWithTheFile(fh)) {
|
||||||
|
fclose(fh); // Feche o identificador de arquivo para que ele não vaze.
|
||||||
|
return false; // Propague o erro.
|
||||||
|
}
|
||||||
|
if (!doSomethingElseWithIt(fh)) {
|
||||||
|
fclose(fh); // Feche o identificador de arquivo para que ele não vaze.
|
||||||
|
return false; // Propague o erro.
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fh); // Feche o identificador de arquivo para que ele não vaze.
|
||||||
|
return true; // Indica sucesso
|
||||||
|
}
|
||||||
|
|
||||||
|
// Programadores C frequentemente limpam isso um pouco usando Goto:
|
||||||
|
bool doSomethingWithAFile(const char* filename)
|
||||||
|
{
|
||||||
|
FILE* fh = fopen(filename, "r");
|
||||||
|
if (fh == nullptr)
|
||||||
|
reuturn false;
|
||||||
|
|
||||||
|
if (!doSomethingWithTheFile(fh))
|
||||||
|
goto failure;
|
||||||
|
|
||||||
|
if (!doSomethingElseWithIt(fh))
|
||||||
|
goto failure;
|
||||||
|
|
||||||
|
fclose(fh); // Close the file
|
||||||
|
return true; // Indica sucesso
|
||||||
|
|
||||||
|
failure:
|
||||||
|
fclose(fh);
|
||||||
|
return false; // Propague o erro.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Se as funções indicam erros usando exceções,
|
||||||
|
// as coisas são um pouco mais limpo, mas ainda abaixo do ideal.
|
||||||
|
void doSomethingWithAFile(const char* filename)
|
||||||
|
{
|
||||||
|
FILE* fh = fopen(filename, "r"); // Abra o arquivo em modo de leitura.
|
||||||
|
if (fh == nullptr)
|
||||||
|
throw std::exception("Não pode abrir o arquivo.");
|
||||||
|
|
||||||
|
try {
|
||||||
|
doSomethingWithTheFile(fh);
|
||||||
|
doSomethingElseWithIt(fh);
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
fclose(fh); // Certifique-se de fechar o arquivo se ocorrer um erro.
|
||||||
|
throw; // Em seguida, re-lance a exceção.
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fh); // Feche o arquivo
|
||||||
|
// Tudo ocorreu com sucesso!
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compare isso com o uso de C++ classe fluxo de arquivo (fstream) fstream usa
|
||||||
|
// seu destruidor para fechar o arquivo. Lembre-se de cima que destruidores são
|
||||||
|
// automaticamente chamado sempre que um objeto cai fora do âmbito.
|
||||||
|
void doSomethingWithAFile(const std::string& filename)
|
||||||
|
{
|
||||||
|
// ifstream é curto para o fluxo de arquivo de entrada
|
||||||
|
std::ifstream fh(filename); // Abra o arquivo
|
||||||
|
|
||||||
|
// faça alguma coisa com o arquivo
|
||||||
|
doSomethingWithTheFile(fh);
|
||||||
|
doSomethingElseWithIt(fh);
|
||||||
|
|
||||||
|
} // O arquivo é automaticamente fechado aqui pelo destructor
|
||||||
|
|
||||||
|
// Isto tem _grandes_ vantagens:
|
||||||
|
// 1. Não importa o que aconteça,
|
||||||
|
// o recurso (neste caso, o identificador de ficheiro) irá ser limpo.
|
||||||
|
// Depois de escrever o destruidor corretamente,
|
||||||
|
// É _impossível_ esquecer de fechar e vazar o recurso
|
||||||
|
// 2. Nota-se que o código é muito mais limpo.
|
||||||
|
// As alças destructor fecham o arquivo por trás das cenas
|
||||||
|
// sem que você precise se preocupar com isso.
|
||||||
|
// 3. O código é seguro de exceção.
|
||||||
|
// Uma exceção pode ser jogado em qualquer lugar na função e a limpeza
|
||||||
|
// irá ainda ocorrer.
|
||||||
|
|
||||||
|
// Todos códigos C++ usam RAII extensivamente para todos os recursos.
|
||||||
|
// Outros exemplos incluem
|
||||||
|
// - Memória usa unique_ptr e shared_ptr
|
||||||
|
// - Contentores - a lista da biblioteca ligada padrão,
|
||||||
|
// vetor (i.e. array de autodimensionamento), mapas hash, e assim por diante
|
||||||
|
// tudo é automaticamente destruído quando eles saem de escopo
|
||||||
|
// - Mutex usa lock_guard e unique_lock
|
||||||
|
```
|
||||||
|
Leitura Adicional:
|
||||||
|
|
||||||
|
Uma referência atualizada da linguagem pode ser encontrada em
|
||||||
|
<http://cppreference.com/w/cpp>
|
||||||
|
|
||||||
|
Uma fonte adicional pode ser encontrada em <http://cplusplus.com>
|
622
pt-br/common-lisp-pt.html.markdown
Normal file
622
pt-br/common-lisp-pt.html.markdown
Normal file
@ -0,0 +1,622 @@
|
|||||||
|
---
|
||||||
|
language: "Common Lisp"
|
||||||
|
filename: commonlisp-pt.lisp
|
||||||
|
contributors:
|
||||||
|
- ["Paul Nathan", "https://github.com/pnathan"]
|
||||||
|
translators:
|
||||||
|
- ["Édipo Luis Féderle", "https://github.com/edipofederle"]
|
||||||
|
lang: pt-br
|
||||||
|
---
|
||||||
|
|
||||||
|
ANSI Common Lisp é uma linguagem de uso geral, multi-paradigma, designada
|
||||||
|
para uma variedade de aplicações na indústria. É frequentemente citada
|
||||||
|
como uma linguagem de programação programável.
|
||||||
|
|
||||||
|
|
||||||
|
O ponto inicial clássico é [Practical Common Lisp e livremente disponível](http://www.gigamonkeys.com/book/)
|
||||||
|
|
||||||
|
Outro livro recente e popular é o
|
||||||
|
[Land of Lisp](http://landoflisp.com/).
|
||||||
|
|
||||||
|
|
||||||
|
```common_lisp
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;;; 0. Sintaxe
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
;;; "Form" Geral
|
||||||
|
|
||||||
|
|
||||||
|
;; Lisp tem dois pedaços fundamentais de sintaxe: o ATOM e S-expression.
|
||||||
|
;; Tipicamente, S-expressions agrupadas são chamadas de `forms`.
|
||||||
|
|
||||||
|
|
||||||
|
10 ; um atom; é avaliado para ele mesmo
|
||||||
|
|
||||||
|
:THING ;Outro atom; avaliado para o símbolo :thing.
|
||||||
|
|
||||||
|
t ; outro atom, denotado true.
|
||||||
|
|
||||||
|
(+ 1 2 3 4) ; uma s-expression
|
||||||
|
|
||||||
|
'(4 :foo t) ;outra s-expression
|
||||||
|
|
||||||
|
|
||||||
|
;;; Comentários
|
||||||
|
|
||||||
|
;; Comentários de uma única linha começam com ponto e vírgula; usar dois para
|
||||||
|
;; comentários normais, três para comentários de seção, e quadro para comentários
|
||||||
|
;; em nível de arquivo.
|
||||||
|
|
||||||
|
#| Bloco de comentário
|
||||||
|
pode abranger várias linhas e...
|
||||||
|
#|
|
||||||
|
eles podem ser aninhados
|
||||||
|
|#
|
||||||
|
|#
|
||||||
|
|
||||||
|
;;; Ambiente
|
||||||
|
|
||||||
|
;; Existe uma variedade de implementações; a maioria segue o padrão.
|
||||||
|
;; CLISP é um bom ponto de partida.
|
||||||
|
|
||||||
|
;; Bibliotecas são gerenciadas através do Quicklisp.org's Quicklisp sistema.
|
||||||
|
|
||||||
|
;; Common Lisp é normalmente desenvolvido com um editor de texto e um REPL
|
||||||
|
;; (Read Evaluate Print Loop) rodando ao mesmo tempo. O REPL permite exploração
|
||||||
|
;; interativa do programa como ele é "ao vivo" no sistema.
|
||||||
|
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;;; 1. Tipos Primitivos e Operadores
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
;;; Símbolos
|
||||||
|
|
||||||
|
'foo ; => FOO Perceba que um símbolo é automáticamente convertido para maiúscula.
|
||||||
|
|
||||||
|
;; Intern manualmente cria um símbolo a partir de uma string.
|
||||||
|
|
||||||
|
(intern "AAAA") ; => AAAA
|
||||||
|
|
||||||
|
(intern "aaa") ; => |aaa|
|
||||||
|
|
||||||
|
;;; Números
|
||||||
|
9999999999999999999999 ; inteiro
|
||||||
|
#b111 ; binário => 7
|
||||||
|
#o111 ; octal => 73
|
||||||
|
#x111 ; hexadecimal => 273
|
||||||
|
3.14159s0 ; single
|
||||||
|
3.14159d0 ; double
|
||||||
|
1/2 ; ratios
|
||||||
|
#C(1 2) ; números complexos
|
||||||
|
|
||||||
|
|
||||||
|
;; Funções são escritas como (f x y z ...)
|
||||||
|
;; onde f é uma função e x, y, z, ... são operadores
|
||||||
|
;; Se você quiser criar uma lista literal de dados, use ' para evitar
|
||||||
|
;; que a lista seja avaliada - literalmente, "quote" os dados.
|
||||||
|
'(+ 1 2) ; => (+ 1 2)
|
||||||
|
;; Você também pode chamar uma função manualmente:
|
||||||
|
(funcall #'+ 1 2 3) ; => 6
|
||||||
|
;; O mesmo para operações aritiméticas
|
||||||
|
(+ 1 1) ; => 2
|
||||||
|
(- 8 1) ; => 7
|
||||||
|
(* 10 2) ; => 20
|
||||||
|
(expt 2 3) ; => 8
|
||||||
|
(mod 5 2) ; => 1
|
||||||
|
(/ 35 5) ; => 7
|
||||||
|
(/ 1 3) ; => 1/3
|
||||||
|
(+ #C(1 2) #C(6 -4)) ; => #C(7 -2)
|
||||||
|
|
||||||
|
;;; Booleans
|
||||||
|
t ; para true (qualquer valor não nil é true)
|
||||||
|
nil ; para false - e para lista vazia
|
||||||
|
(not nil) ; => t
|
||||||
|
(and 0 t) ; => t
|
||||||
|
(or 0 nil) ; => 0
|
||||||
|
|
||||||
|
;;; Caracteres
|
||||||
|
#\A ; => #\A
|
||||||
|
#\λ ; => #\GREEK_SMALL_LETTER_LAMDA
|
||||||
|
#\u03BB ; => #\GREEK_SMALL_LETTER_LAMDA
|
||||||
|
|
||||||
|
;;; String são arrays de caracteres com tamanho fixo.
|
||||||
|
"Hello, world!"
|
||||||
|
"Benjamin \"Bugsy\" Siegel" ; barra é um escape de caracter
|
||||||
|
|
||||||
|
;; String podem ser concatenadas também!
|
||||||
|
(concatenate 'string "Hello " "world!") ; => "Hello world!"
|
||||||
|
|
||||||
|
;; Uma String pode ser tratada como uma sequência de caracteres
|
||||||
|
(elt "Apple" 0) ; => #\A
|
||||||
|
|
||||||
|
;; format pode ser usado para formatar strings
|
||||||
|
(format nil "~a can be ~a" "strings" "formatted")
|
||||||
|
|
||||||
|
;; Impimir é bastante fácil; ~% indica nova linha
|
||||||
|
(format t "Common Lisp is groovy. Dude.~%")
|
||||||
|
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; 2. Variáveis
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; Você pode criar uma global (escopo dinâmico) usando defparameter
|
||||||
|
;; um nome de variável pode conter qualquer caracter, exceto: ()",'`;#|\
|
||||||
|
|
||||||
|
;; Variáveis de escopo dinâmico devem ter asteriscos em seus nomes!
|
||||||
|
|
||||||
|
(defparameter *some-var* 5)
|
||||||
|
*some-var* ; => 5
|
||||||
|
|
||||||
|
;; Você pode usar caracteres unicode também.
|
||||||
|
(defparameter *AΛB* nil)
|
||||||
|
|
||||||
|
|
||||||
|
;; Acessando uma variável anteriormente não ligada é um
|
||||||
|
;; comportamento não definido (mas possível). Não faça isso.
|
||||||
|
|
||||||
|
;; Ligação local: `me` é vinculado com "dance with you" somente dentro
|
||||||
|
;; de (let ... ). Let permite retornar o valor do último `form` no form let.
|
||||||
|
|
||||||
|
(let ((me "dance with you"))
|
||||||
|
me)
|
||||||
|
;; => "dance with you"
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; 3. Estruturas e Coleções
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
;; Estruturas
|
||||||
|
(defstruct dog name breed age)
|
||||||
|
(defparameter *rover*
|
||||||
|
(make-dog :name "rover"
|
||||||
|
:breed "collie"
|
||||||
|
:age 5))
|
||||||
|
*rover* ; => #S(DOG :NAME "rover" :BREED "collie" :AGE 5)
|
||||||
|
|
||||||
|
(dog-p *rover*) ; => t ;; ewww)
|
||||||
|
(dog-name *rover*) ; => "rover"
|
||||||
|
|
||||||
|
;; Dog-p, make-dog, e dog-name foram todas criadas por defstruct!
|
||||||
|
|
||||||
|
;;; Pares
|
||||||
|
;; `cons' constroi pares, `car' and `cdr' extrai o primeiro
|
||||||
|
;; e o segundo elemento
|
||||||
|
(cons 'SUBJECT 'VERB) ; => '(SUBJECT . VERB)
|
||||||
|
(car (cons 'SUBJECT 'VERB)) ; => SUBJECT
|
||||||
|
(cdr (cons 'SUBJECT 'VERB)) ; => VERB
|
||||||
|
|
||||||
|
;;; Listas
|
||||||
|
|
||||||
|
;; Listas são estruturas de dados do tipo listas encadeadas, criadas com `cons'
|
||||||
|
;; pares e terminam `nil' (ou '()) para marcar o final da lista
|
||||||
|
(cons 1 (cons 2 (cons 3 nil))) ; => '(1 2 3)
|
||||||
|
;; `list' é um construtor conveniente para listas
|
||||||
|
(list 1 2 3) ; => '(1 2 3)
|
||||||
|
;; e a quote (') também pode ser usado para um valor de lista literal
|
||||||
|
'(1 2 3) ; => '(1 2 3)
|
||||||
|
|
||||||
|
;; Ainda pode-se usar `cons' para adicionar um item no começo da lista.
|
||||||
|
(cons 4 '(1 2 3)) ; => '(4 1 2 3)
|
||||||
|
|
||||||
|
;; Use `append' para - surpreendentemente - juntar duas listas
|
||||||
|
(append '(1 2) '(3 4)) ; => '(1 2 3 4)
|
||||||
|
|
||||||
|
;; Ou use concatenate -
|
||||||
|
|
||||||
|
(concatenate 'list '(1 2) '(3 4))
|
||||||
|
|
||||||
|
;; Listas são um tipo muito central, então existe uma grande variedade de
|
||||||
|
;; funcionalidades para eles, alguns exemplos:
|
||||||
|
(mapcar #'1+ '(1 2 3)) ; => '(2 3 4)
|
||||||
|
(mapcar #'+ '(1 2 3) '(10 20 30)) ; => '(11 22 33)
|
||||||
|
(remove-if-not #'evenp '(1 2 3 4)) ; => '(2 4)
|
||||||
|
(every #'evenp '(1 2 3 4)) ; => nil
|
||||||
|
(some #'oddp '(1 2 3 4)) ; => T
|
||||||
|
(butlast '(subject verb object)) ; => (SUBJECT VERB)
|
||||||
|
|
||||||
|
|
||||||
|
;;; Vetores
|
||||||
|
|
||||||
|
;; Vector's literais são arrays de tamanho fixo.
|
||||||
|
#(1 2 3) ; => #(1 2 3)
|
||||||
|
|
||||||
|
;; Use concatenate para juntar dois vectors
|
||||||
|
(concatenate 'vector #(1 2 3) #(4 5 6)) ; => #(1 2 3 4 5 6)
|
||||||
|
|
||||||
|
;;; Arrays
|
||||||
|
|
||||||
|
;; Ambos vetores e strings são um caso especial de arrays.
|
||||||
|
|
||||||
|
;; 2D arrays
|
||||||
|
|
||||||
|
(make-array (list 2 2))
|
||||||
|
|
||||||
|
;; (make-array '(2 2)) também funciona.
|
||||||
|
|
||||||
|
; => #2A((0 0) (0 0))
|
||||||
|
|
||||||
|
(make-array (list 2 2 2))
|
||||||
|
|
||||||
|
; => #3A(((0 0) (0 0)) ((0 0) (0 0)))
|
||||||
|
|
||||||
|
;; Cuidado - os valores de inicialição padrões são
|
||||||
|
;; definidos pela implementção. Aqui vai como defini-lós.
|
||||||
|
|
||||||
|
(make-array '(2) :initial-element 'unset)
|
||||||
|
|
||||||
|
; => #(UNSET UNSET)
|
||||||
|
|
||||||
|
;; E, para acessar o element em 1,1,1 -
|
||||||
|
(aref (make-array (list 2 2 2)) 1 1 1)
|
||||||
|
|
||||||
|
; => 0
|
||||||
|
|
||||||
|
;;; Vetores Ajustáveis
|
||||||
|
|
||||||
|
;; Vetores ajustáveis tem a mesma representação impressa que os vectores
|
||||||
|
;; de tamanho fixo
|
||||||
|
(defparameter *adjvec* (make-array '(3) :initial-contents '(1 2 3)
|
||||||
|
:adjustable t :fill-pointer t))
|
||||||
|
|
||||||
|
*adjvec* ; => #(1 2 3)
|
||||||
|
|
||||||
|
;; Adicionando novo elemento
|
||||||
|
(vector-push-extend 4 *adjvec*) ; => 3
|
||||||
|
|
||||||
|
*adjvec* ; => #(1 2 3 4)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;;; Ingenuamente, conjuntos são apenas listas:
|
||||||
|
|
||||||
|
(set-difference '(1 2 3 4) '(4 5 6 7)) ; => (3 2 1)
|
||||||
|
(intersection '(1 2 3 4) '(4 5 6 7)) ; => 4
|
||||||
|
(union '(1 2 3 4) '(4 5 6 7)) ; => (3 2 1 4 5 6 7)
|
||||||
|
(adjoin 4 '(1 2 3 4)) ; => (1 2 3 4)
|
||||||
|
|
||||||
|
;; Mas você irá querer usar uma estrutura de dados melhor que uma lista encadeada.
|
||||||
|
;; para performance.
|
||||||
|
|
||||||
|
;;; Dicionários são implementados como hash tables
|
||||||
|
|
||||||
|
;; Cria um hash table
|
||||||
|
(defparameter *m* (make-hash-table))
|
||||||
|
|
||||||
|
;; seta um valor
|
||||||
|
(setf (gethash 'a *m*) 1)
|
||||||
|
|
||||||
|
;; Recupera um valor
|
||||||
|
(gethash 'a *m*) ; => 1, t
|
||||||
|
|
||||||
|
;; Detalhe - Common Lisp tem multiplos valores de retorno possíveis. gethash
|
||||||
|
;; retorna t no segundo valor se alguma coisa foi encontrada, e nil se não.
|
||||||
|
|
||||||
|
;; Recuperando um valor não presente retorna nil
|
||||||
|
(gethash 'd *m*) ;=> nil, nil
|
||||||
|
|
||||||
|
;; Você pode fornecer um valor padrão para uma valores não encontrados
|
||||||
|
(gethash 'd *m* :not-found) ; => :NOT-FOUND
|
||||||
|
|
||||||
|
;; Vamos tratas múltiplos valores de rotorno aqui.
|
||||||
|
|
||||||
|
(multiple-value-bind
|
||||||
|
(a b)
|
||||||
|
(gethash 'd *m*)
|
||||||
|
(list a b))
|
||||||
|
; => (NIL NIL)
|
||||||
|
|
||||||
|
(multiple-value-bind
|
||||||
|
(a b)
|
||||||
|
(gethash 'a *m*)
|
||||||
|
(list a b))
|
||||||
|
; => (1 T)
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; 3. Funções
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
;; Use `lambda' para criar funções anônimas
|
||||||
|
;; Uma função sempre retorna um valor da última expressão avaliada.
|
||||||
|
;; A representação exata impressão de uma função varia de acordo ...
|
||||||
|
|
||||||
|
(lambda () "Hello World") ; => #<FUNCTION (LAMBDA ()) {1004E7818B}>
|
||||||
|
|
||||||
|
;; Use funcall para chamar uma função lambda.
|
||||||
|
(funcall (lambda () "Hello World")) ; => "Hello World"
|
||||||
|
|
||||||
|
;; Ou Apply
|
||||||
|
(apply (lambda () "Hello World") nil) ; => "Hello World"
|
||||||
|
|
||||||
|
;; "De-anonymize" a função
|
||||||
|
(defun hello-world ()
|
||||||
|
"Hello World")
|
||||||
|
(hello-world) ; => "Hello World"
|
||||||
|
|
||||||
|
;; O () acima é a lista de argumentos da função.
|
||||||
|
(defun hello (name)
|
||||||
|
(format nil "Hello, ~a " name))
|
||||||
|
|
||||||
|
(hello "Steve") ; => "Hello, Steve"
|
||||||
|
|
||||||
|
;; Funções podem ter argumentos opcionais; eles são nil por padrão
|
||||||
|
|
||||||
|
(defun hello (name &optional from)
|
||||||
|
(if from
|
||||||
|
(format t "Hello, ~a, from ~a" name from)
|
||||||
|
(format t "Hello, ~a" name)))
|
||||||
|
|
||||||
|
(hello "Jim" "Alpacas") ;; => Hello, Jim, from Alpacas
|
||||||
|
|
||||||
|
;; E os padrões podem ser configurados...
|
||||||
|
(defun hello (name &optional (from "The world"))
|
||||||
|
(format t "Hello, ~a, from ~a" name from))
|
||||||
|
|
||||||
|
(hello "Steve")
|
||||||
|
; => Hello, Steve, from The world
|
||||||
|
|
||||||
|
(hello "Steve" "the alpacas")
|
||||||
|
; => Hello, Steve, from the alpacas
|
||||||
|
|
||||||
|
|
||||||
|
;; E é claro, palavras-chaves são permitidas também... frequentemente mais
|
||||||
|
;; flexivel que &optional.
|
||||||
|
|
||||||
|
(defun generalized-greeter (name &key (from "the world") (honorific "Mx"))
|
||||||
|
(format t "Hello, ~a ~a, from ~a" honorific name from))
|
||||||
|
|
||||||
|
(generalized-greeter "Jim") ; => Hello, Mx Jim, from the world
|
||||||
|
|
||||||
|
(generalized-greeter "Jim" :from "the alpacas you met last summer" :honorific "Mr")
|
||||||
|
; => Hello, Mr Jim, from the alpacas you met last summer
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; 4. Igualdade
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
;; Common Lisp tem um sistema sofisticado de igualdade. Alguns são cobertos aqui.
|
||||||
|
|
||||||
|
;; Para número use `='
|
||||||
|
(= 3 3.0) ; => t
|
||||||
|
(= 2 1) ; => nil
|
||||||
|
|
||||||
|
;; para identidade de objeto (aproximadamente) use `eql`
|
||||||
|
(eql 3 3) ; => t
|
||||||
|
(eql 3 3.0) ; => nil
|
||||||
|
(eql (list 3) (list 3)) ; => nil
|
||||||
|
|
||||||
|
;; para listas, strings, e para pedaços de vetores use `equal'
|
||||||
|
(equal (list 'a 'b) (list 'a 'b)) ; => t
|
||||||
|
(equal (list 'a 'b) (list 'b 'a)) ; => nil
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; 5. Fluxo de Controle
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
;;; Condicionais
|
||||||
|
|
||||||
|
(if t ; testa a expressão
|
||||||
|
"this is true" ; então expressão
|
||||||
|
"this is false") ; senão expressão
|
||||||
|
; => "this is true"
|
||||||
|
|
||||||
|
;; Em condicionais, todos valores não nulos são tratados como true
|
||||||
|
(member 'Groucho '(Harpo Groucho Zeppo)) ; => '(GROUCHO ZEPPO)
|
||||||
|
(if (member 'Groucho '(Harpo Groucho Zeppo))
|
||||||
|
'yep
|
||||||
|
'nope)
|
||||||
|
; => 'YEP
|
||||||
|
|
||||||
|
;; `cond' encadeia uma série de testes para selecionar um resultado
|
||||||
|
(cond ((> 2 2) (error "wrong!"))
|
||||||
|
((< 2 2) (error "wrong again!"))
|
||||||
|
(t 'ok)) ; => 'OK
|
||||||
|
|
||||||
|
;; Typecase é um condicional que escolhe uma de seus cláusulas com base do tipo
|
||||||
|
;; do seu valor
|
||||||
|
|
||||||
|
(typecase 1
|
||||||
|
(string :string)
|
||||||
|
(integer :int))
|
||||||
|
|
||||||
|
; => :int
|
||||||
|
|
||||||
|
;;; Interação
|
||||||
|
|
||||||
|
;; Claro que recursão é suportada:
|
||||||
|
|
||||||
|
(defun walker (n)
|
||||||
|
(if (zerop n)
|
||||||
|
:walked
|
||||||
|
(walker (1- n))))
|
||||||
|
|
||||||
|
(walker 5) ; => :walked
|
||||||
|
|
||||||
|
;; Na maioria das vezes, nós usamos DOTLISO ou LOOP
|
||||||
|
|
||||||
|
(dolist (i '(1 2 3 4))
|
||||||
|
(format t "~a" i))
|
||||||
|
|
||||||
|
; => 1234
|
||||||
|
|
||||||
|
(loop for i from 0 below 10
|
||||||
|
collect i)
|
||||||
|
|
||||||
|
; => (0 1 2 3 4 5 6 7 8 9)
|
||||||
|
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; 6. Mutação
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
;; Use `setf' para atribuir um novo valor para uma variável existente. Isso foi
|
||||||
|
;; demonstrado anteriormente no exemplo da hash table.
|
||||||
|
|
||||||
|
(let ((variable 10))
|
||||||
|
(setf variable 2))
|
||||||
|
; => 2
|
||||||
|
|
||||||
|
|
||||||
|
;; Um bom estilo Lisp é para minimizar funções destrutivas e para evitar
|
||||||
|
;; mutação quando razoável.
|
||||||
|
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; 7. Classes e Objetos
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
;; Sem clases Animal, vamos usar os veículos de transporte de tração
|
||||||
|
;; humana mecânicos.
|
||||||
|
|
||||||
|
(defclass human-powered-conveyance ()
|
||||||
|
((velocity
|
||||||
|
:accessor velocity
|
||||||
|
:initarg :velocity)
|
||||||
|
(average-efficiency
|
||||||
|
:accessor average-efficiency
|
||||||
|
:initarg :average-efficiency))
|
||||||
|
(:documentation "A human powered conveyance"))
|
||||||
|
|
||||||
|
;; defcalss, seguido do nome, seguido por uma list de superclass,
|
||||||
|
;; seguido por um uma 'slot list', seguido por qualidades opcionais como
|
||||||
|
;; :documentation
|
||||||
|
|
||||||
|
;; Quando nenhuma lista de superclasse é setada, uma lista padrão para
|
||||||
|
;; para o objeto padrão é usada. Isso *pode* ser mudado, mas não até você
|
||||||
|
;; saber o que está fazendo. Olhe em Art of the Metaobject Protocol
|
||||||
|
;; para maiores informações.
|
||||||
|
|
||||||
|
(defclass bicycle (human-powered-conveyance)
|
||||||
|
((wheel-size
|
||||||
|
:accessor wheel-size
|
||||||
|
:initarg :wheel-size
|
||||||
|
:documentation "Diameter of the wheel.")
|
||||||
|
(height
|
||||||
|
:accessor height
|
||||||
|
:initarg :height)))
|
||||||
|
|
||||||
|
(defclass recumbent (bicycle)
|
||||||
|
((chain-type
|
||||||
|
:accessor chain-type
|
||||||
|
:initarg :chain-type)))
|
||||||
|
|
||||||
|
(defclass unicycle (human-powered-conveyance) nil)
|
||||||
|
|
||||||
|
(defclass canoe (human-powered-conveyance)
|
||||||
|
((number-of-rowers
|
||||||
|
:accessor number-of-rowers
|
||||||
|
:initarg :number-of-rowers)))
|
||||||
|
|
||||||
|
|
||||||
|
;; Chamando DESCRIBE na classe human-powered-conveyance no REPL dá:
|
||||||
|
|
||||||
|
(describe 'human-powered-conveyance)
|
||||||
|
|
||||||
|
; COMMON-LISP-USER::HUMAN-POWERED-CONVEYANCE
|
||||||
|
; [symbol]
|
||||||
|
;
|
||||||
|
; HUMAN-POWERED-CONVEYANCE names the standard-class #<STANDARD-CLASS
|
||||||
|
; HUMAN-POWERED-CONVEYANCE>:
|
||||||
|
; Documentation:
|
||||||
|
; A human powered conveyance
|
||||||
|
; Direct superclasses: STANDARD-OBJECT
|
||||||
|
; Direct subclasses: UNICYCLE, BICYCLE, CANOE
|
||||||
|
; Not yet finalized.
|
||||||
|
; Direct slots:
|
||||||
|
; VELOCITY
|
||||||
|
; Readers: VELOCITY
|
||||||
|
; Writers: (SETF VELOCITY)
|
||||||
|
; AVERAGE-EFFICIENCY
|
||||||
|
; Readers: AVERAGE-EFFICIENCY
|
||||||
|
; Writers: (SETF AVERAGE-EFFICIENCY)
|
||||||
|
|
||||||
|
;; Note o comportamento reflexivo disponível para você! Common Lisp é
|
||||||
|
;; projetada para ser um sistema interativo.
|
||||||
|
|
||||||
|
;; Para definir um métpdo, vamos encontrar o que nossa cirunferência da
|
||||||
|
;; roda da bicicleta usando a equação: C = d * pi
|
||||||
|
|
||||||
|
(defmethod circumference ((object bicycle))
|
||||||
|
(* pi (wheel-size object)))
|
||||||
|
|
||||||
|
;; pi já é definido para a gente em Lisp!
|
||||||
|
|
||||||
|
;; Vamos supor que nós descobrimos que o valor da eficiência do número
|
||||||
|
;; de remadores em uma canoa é aproximadamente logarítmica. Isso provavelmente
|
||||||
|
;; deve ser definido no construtor / inicializador.
|
||||||
|
|
||||||
|
;; Veja como initializar sua instância após Common Lisp ter construído isso:
|
||||||
|
|
||||||
|
(defmethod initialize-instance :after ((object canoe) &rest args)
|
||||||
|
(setf (average-efficiency object) (log (1+ (number-of-rowers object)))))
|
||||||
|
|
||||||
|
;; Em seguida, para a construção de uma ocorrência e verificar a eficiência média ...
|
||||||
|
|
||||||
|
(average-efficiency (make-instance 'canoe :number-of-rowers 15))
|
||||||
|
; => 2.7725887
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; 8. Macros
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
;; Macros permitem que você estenda a sintaxe da lingaugem
|
||||||
|
|
||||||
|
;; Common Lisp não vem com um loop WHILE - vamos adicionar um.
|
||||||
|
;; Se obedecermos nossos instintos 'assembler', acabamos com:
|
||||||
|
|
||||||
|
(defmacro while (condition &body body)
|
||||||
|
"Enquanto `condition` é verdadeiro, `body` é executado.
|
||||||
|
|
||||||
|
`condition` é testado antes de cada execução do `body`"
|
||||||
|
(let ((block-name (gensym)))
|
||||||
|
`(tagbody
|
||||||
|
(unless ,condition
|
||||||
|
(go ,block-name))
|
||||||
|
(progn
|
||||||
|
,@body)
|
||||||
|
,block-name)))
|
||||||
|
|
||||||
|
;; Vamos dar uma olhada em uma versão alto nível disto:
|
||||||
|
|
||||||
|
|
||||||
|
(defmacro while (condition &body body)
|
||||||
|
"Enquanto `condition` for verdadeira, `body` é executado.
|
||||||
|
|
||||||
|
`condition` é testado antes de cada execução do `body`"
|
||||||
|
`(loop while ,condition
|
||||||
|
do
|
||||||
|
(progn
|
||||||
|
,@body)))
|
||||||
|
|
||||||
|
;; Entretanto, com um compilador moderno, isso não é preciso; o LOOP
|
||||||
|
;; 'form' compila igual e é bem mais fácil de ler.
|
||||||
|
|
||||||
|
;; Noteq ue ``` é usado , bem como `,` e `@`. ``` é um operador 'quote-type'
|
||||||
|
;; conhecido como 'quasiquote'; isso permite o uso de `,` . `,` permite "unquoting"
|
||||||
|
;; e variáveis. @ interpolará listas.
|
||||||
|
|
||||||
|
;; Gensym cria um símbolo único garantido que não existe em outras posições
|
||||||
|
;; o sistema. Isto é porque macros são expandidas em tempo de compilação e
|
||||||
|
;; variáveis declaradas na macro podem colidir com as variáveis usadas na
|
||||||
|
;; código regular.
|
||||||
|
|
||||||
|
;; Veja Practical Common Lisp para maiores informações sobre macros.
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Leitura Adicional
|
||||||
|
|
||||||
|
[Continua em frente com Practical Common Lisp book.](http://www.gigamonkeys.com/book/)
|
||||||
|
|
||||||
|
|
||||||
|
## Créditos
|
||||||
|
|
||||||
|
Muitos agradecimentos ao pessoal de Schema por fornecer um grande ponto de partida
|
||||||
|
o que facilitou muito a migração para Common Lisp.
|
||||||
|
|
||||||
|
- [Paul Khuong](https://github.com/pkhuong) pelas grandes revisões.
|
176
pt-br/hy-pt.html.markdown
Normal file
176
pt-br/hy-pt.html.markdown
Normal file
@ -0,0 +1,176 @@
|
|||||||
|
---
|
||||||
|
language: hy
|
||||||
|
filename: learnhy.hy
|
||||||
|
contributors:
|
||||||
|
- ["Abhishek L", "http://twitter.com/abhishekl"]
|
||||||
|
translators:
|
||||||
|
- ["Miguel Araújo", "https://github.com/miguelarauj1o"]
|
||||||
|
lang: pt-br
|
||||||
|
---
|
||||||
|
|
||||||
|
Hy é um dialeto de Lisp escrito sobre Python. Isto é possível convertendo
|
||||||
|
código Hy em árvore sintática abstrata python (ast). Portanto, isto permite
|
||||||
|
hy chamar código python nativo e vice-versa.
|
||||||
|
|
||||||
|
Este tutorial funciona para hy ≥ 0.9.12
|
||||||
|
|
||||||
|
```clojure
|
||||||
|
;; Isso dá uma introdução básica em hy, como uma preliminar para o link abaixo
|
||||||
|
;; http://try-hy.appspot.com
|
||||||
|
;;
|
||||||
|
; Comentários em ponto-e-vírgula, como em outros LISPS
|
||||||
|
|
||||||
|
;; s-noções básicas de expressão
|
||||||
|
; programas Lisp são feitos de expressões simbólicas ou sexps que se assemelham
|
||||||
|
(some-function args)
|
||||||
|
; agora o essencial "Olá mundo"
|
||||||
|
(print "hello world")
|
||||||
|
|
||||||
|
;; Tipos de dados simples
|
||||||
|
; Todos os tipos de dados simples são exatamente semelhantes aos seus homólogos
|
||||||
|
; em python que
|
||||||
|
42 ; => 42
|
||||||
|
3.14 ; => 3.14
|
||||||
|
True ; => True
|
||||||
|
4+10j ; => (4+10j) um número complexo
|
||||||
|
|
||||||
|
; Vamos começar com um pouco de aritmética muito simples
|
||||||
|
(+ 4 1) ;=> 5
|
||||||
|
; o operador é aplicado a todos os argumentos, como outros lisps
|
||||||
|
(+ 4 1 2 3) ;=> 10
|
||||||
|
(- 2 1) ;=> 1
|
||||||
|
(* 4 2) ;=> 8
|
||||||
|
(/ 4 1) ;=> 4
|
||||||
|
(% 4 2) ;=> 0 o operador módulo
|
||||||
|
; exponenciação é representado pelo operador ** como python
|
||||||
|
(** 3 2) ;=> 9
|
||||||
|
; formas aninhadas vão fazer a coisa esperada
|
||||||
|
(+ 2 (* 4 2)) ;=> 10
|
||||||
|
; também operadores lógicos e ou não e igual etc. faz como esperado
|
||||||
|
(= 5 4) ;=> False
|
||||||
|
(not (= 5 4)) ;=> True
|
||||||
|
|
||||||
|
;; variáveis
|
||||||
|
; variáveis são definidas usando SETV, nomes de variáveis podem usar utf-8, exceto
|
||||||
|
; for ()[]{}",'`;#|
|
||||||
|
(setv a 42)
|
||||||
|
(setv π 3.14159)
|
||||||
|
(def *foo* 42)
|
||||||
|
;; outros tipos de dados de armazenamento
|
||||||
|
; strings, lists, tuples & dicts
|
||||||
|
; estes são exatamente os mesmos tipos de armazenamento de python
|
||||||
|
"hello world" ;=> "hello world"
|
||||||
|
; operações de string funcionam semelhante em python
|
||||||
|
(+ "hello " "world") ;=> "hello world"
|
||||||
|
; Listas são criadas usando [], a indexação começa em 0
|
||||||
|
(setv mylist [1 2 3 4])
|
||||||
|
; tuplas são estruturas de dados imutáveis
|
||||||
|
(setv mytuple (, 1 2))
|
||||||
|
; dicionários são pares de valores-chave
|
||||||
|
(setv dict1 {"key1" 42 "key2" 21})
|
||||||
|
; :nome pode ser utilizado para definir palavras-chave em hy que podem ser utilizados para as chaves
|
||||||
|
(setv dict2 {:key1 41 :key2 20})
|
||||||
|
; usar 'get' para obter o elemento em um índice/key
|
||||||
|
(get mylist 1) ;=> 2
|
||||||
|
(get dict1 "key1") ;=> 42
|
||||||
|
; Alternativamente, se foram utilizadas palavras-chave que podem ser chamadas diretamente
|
||||||
|
(:key1 dict2) ;=> 41
|
||||||
|
|
||||||
|
;; funções e outras estruturas de programa
|
||||||
|
; funções são definidas usando defn, o último sexp é devolvido por padrão
|
||||||
|
(defn greet [name]
|
||||||
|
"A simple greeting" ; uma docstring opcional
|
||||||
|
(print "hello " name))
|
||||||
|
|
||||||
|
(greet "bilbo") ;=> "hello bilbo"
|
||||||
|
|
||||||
|
; funções podem ter argumentos opcionais, bem como argumentos-chave
|
||||||
|
(defn foolists [arg1 &optional [arg2 2]]
|
||||||
|
[arg1 arg2])
|
||||||
|
|
||||||
|
(foolists 3) ;=> [3 2]
|
||||||
|
(foolists 10 3) ;=> [10 3]
|
||||||
|
|
||||||
|
; funções anônimas são criados usando construtores 'fn' ou 'lambda'
|
||||||
|
; que são semelhantes para 'defn'
|
||||||
|
(map (fn [x] (* x x)) [1 2 3 4]) ;=> [1 4 9 16]
|
||||||
|
|
||||||
|
;; operações de sequência
|
||||||
|
; hy tem algumas utils embutidas para operações de sequência, etc.
|
||||||
|
; recuperar o primeiro elemento usando 'first' ou 'car'
|
||||||
|
(setv mylist [1 2 3 4])
|
||||||
|
(setv mydict {"a" 1 "b" 2})
|
||||||
|
(first mylist) ;=> 1
|
||||||
|
|
||||||
|
; corte listas usando 'slice'
|
||||||
|
(slice mylist 1 3) ;=> [2 3]
|
||||||
|
|
||||||
|
; obter elementos de uma lista ou dict usando 'get'
|
||||||
|
(get mylist 1) ;=> 2
|
||||||
|
(get mydict "b") ;=> 2
|
||||||
|
; lista de indexação começa a partir de 0, igual em python
|
||||||
|
; assoc pode definir elementos em chaves/índices
|
||||||
|
(assoc mylist 2 10) ; faz mylist [1 2 10 4]
|
||||||
|
(assoc mydict "c" 3) ; faz mydict {"a" 1 "b" 2 "c" 3}
|
||||||
|
; há toda uma série de outras funções essenciais que torna o trabalho com
|
||||||
|
; sequências uma diversão
|
||||||
|
|
||||||
|
;; Python interop
|
||||||
|
;; importação funciona exatamente como em python
|
||||||
|
(import datetime)
|
||||||
|
(import [functools [partial reduce]]) ; importa fun1 e fun2 do module1
|
||||||
|
(import [matplotlib.pyplot :as plt]) ; fazendo uma importação em foo como em bar
|
||||||
|
; todos os métodos de python embutidas etc. são acessíveis a partir hy
|
||||||
|
; a.foo(arg) is called as (.foo a arg)
|
||||||
|
(.split (.strip "hello world ")) ;=> ["hello" "world"]
|
||||||
|
|
||||||
|
;; Condicionais
|
||||||
|
; (if condition (body-if-true) (body-if-false)
|
||||||
|
(if (= passcode "moria")
|
||||||
|
(print "welcome")
|
||||||
|
(print "Speak friend, and Enter!"))
|
||||||
|
|
||||||
|
; aninhe múltiplas cláusulas 'if else if' com cond
|
||||||
|
(cond
|
||||||
|
[(= someval 42)
|
||||||
|
(print "Life, universe and everything else!")]
|
||||||
|
[(> someval 42)
|
||||||
|
(print "val too large")]
|
||||||
|
[(< someval 42)
|
||||||
|
(print "val too small")])
|
||||||
|
|
||||||
|
; declarações de grupo com 'do', essas são executadas sequencialmente
|
||||||
|
; formas como defn tem um 'do' implícito
|
||||||
|
(do
|
||||||
|
(setv someval 10)
|
||||||
|
(print "someval is set to " someval)) ;=> 10
|
||||||
|
|
||||||
|
; criar ligações lexicais com 'let', todas as variáveis definidas desta forma
|
||||||
|
; tem escopo local
|
||||||
|
(let [[nemesis {"superman" "lex luther"
|
||||||
|
"sherlock" "moriarty"
|
||||||
|
"seinfeld" "newman"}]]
|
||||||
|
(for [(, h v) (.items nemesis)]
|
||||||
|
(print (.format "{0}'s nemesis was {1}" h v))))
|
||||||
|
|
||||||
|
;; classes
|
||||||
|
; classes são definidas da seguinte maneira
|
||||||
|
(defclass Wizard [object]
|
||||||
|
[[--init-- (fn [self spell]
|
||||||
|
(setv self.spell spell) ; init a mágica attr
|
||||||
|
None)]
|
||||||
|
[get-spell (fn [self]
|
||||||
|
self.spell)]])
|
||||||
|
|
||||||
|
;; acesse hylang.org
|
||||||
|
```
|
||||||
|
|
||||||
|
### Outras Leituras
|
||||||
|
|
||||||
|
Este tutorial é apenas uma introdução básica para hy/lisp/python.
|
||||||
|
|
||||||
|
Docs Hy: [http://hy.readthedocs.org](http://hy.readthedocs.org)
|
||||||
|
|
||||||
|
Repo Hy no Github: [http://github.com/hylang/hy](http://github.com/hylang/hy)
|
||||||
|
|
||||||
|
Acesso ao freenode irc com #hy, hashtag no twitter: #hylang
|
133
pt-br/xml-pt.html.markdown
Normal file
133
pt-br/xml-pt.html.markdown
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
---
|
||||||
|
language: xml
|
||||||
|
filename: learnxml.xml
|
||||||
|
contributors:
|
||||||
|
- ["João Farias", "https://github.com/JoaoGFarias"]
|
||||||
|
translators:
|
||||||
|
- ["Miguel Araújo", "https://github.com/miguelarauj1o"]
|
||||||
|
lang: pt-br
|
||||||
|
---
|
||||||
|
|
||||||
|
XML é uma linguagem de marcação projetada para armazenar e transportar dados.
|
||||||
|
|
||||||
|
Ao contrário de HTML, XML não especifica como exibir ou formatar os dados,
|
||||||
|
basta carregá-lo.
|
||||||
|
|
||||||
|
* Sintaxe XML
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<!-- Comentários em XML são feitos desta forma -->
|
||||||
|
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<livraria>
|
||||||
|
<livro category="COZINHA">
|
||||||
|
<titulo lang="en">Everyday Italian</titulo>
|
||||||
|
<autor>Giada De Laurentiis</autor>
|
||||||
|
<year>2005</year>
|
||||||
|
<preco>30.00</preco>
|
||||||
|
</livro>
|
||||||
|
<livro category="CRIANÇAS">
|
||||||
|
<titulo lang="en">Harry Potter</titulo>
|
||||||
|
<autor>J K. Rowling</autor>
|
||||||
|
<year>2005</year>
|
||||||
|
<preco>29.99</preco>
|
||||||
|
</livro>
|
||||||
|
<livro category="WEB">
|
||||||
|
<titulo lang="en">Learning XML</titulo>
|
||||||
|
<autor>Erik T. Ray</autor>
|
||||||
|
<year>2003</year>
|
||||||
|
<preco>39.95</preco>
|
||||||
|
</livro>
|
||||||
|
</livraria>
|
||||||
|
|
||||||
|
<!-- Um típico arquivo XML é mostrado acima.
|
||||||
|
Ele começa com uma declaração, informando alguns metadados (opcional).
|
||||||
|
|
||||||
|
XML usa uma estrutura de árvore. Acima, o nó raiz é "Livraria", que tem
|
||||||
|
três nós filhos, todos os 'Livros'. Esses nós tem mais nós filhos,
|
||||||
|
e assim por diante...
|
||||||
|
|
||||||
|
Nós são criados usando tags abre/fecha, filhos são justamente os nós que
|
||||||
|
estão entre estes nós. -->
|
||||||
|
|
||||||
|
|
||||||
|
<!-- XML traz dois tipos de dados:
|
||||||
|
1 - Atributos -> Isso é metadados sobre um nó.
|
||||||
|
Normalmente, o parser XML usa esta informação para armazenar os dados
|
||||||
|
corretamente. Caracteriza-se por aparecer em parênteses dentro da tag
|
||||||
|
de abertura.
|
||||||
|
2 - Elementos -> É dados puros.
|
||||||
|
Isso é o que o analisador irá recuperar a partir do arquivo XML.
|
||||||
|
Elementos aparecem entre as tags de abertura e fechamento,
|
||||||
|
sem parênteses. -->
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Abaixo, um elemento com dois atributos -->
|
||||||
|
<arquivo type="gif" id="4293">computer.gif</arquivo>
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
* Documento bem formatado x Validação
|
||||||
|
|
||||||
|
Um documento XML é bem formatado se estiver sintaticamente correto.No entanto,
|
||||||
|
é possível injetar mais restrições no documento, utilizando definições de
|
||||||
|
documentos, tais como DTD e XML Schema.
|
||||||
|
|
||||||
|
Um documento XML que segue uma definição de documento é chamado válido, sobre
|
||||||
|
esse documento.
|
||||||
|
|
||||||
|
Com esta ferramenta, você pode verificar os dados XML fora da lógica da aplicação.
|
||||||
|
|
||||||
|
```xml
|
||||||
|
|
||||||
|
<!-- Abaixo, você pode ver uma versão simplificada do documento livraria,
|
||||||
|
com a adição de definição DTD.-->
|
||||||
|
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE note SYSTEM "livraria.dtd">
|
||||||
|
<livraria>
|
||||||
|
<livro category="COOKING">
|
||||||
|
<titulo >Everyday Italian</titulo>
|
||||||
|
<preco>30.00</preco>
|
||||||
|
</livro>
|
||||||
|
</livraria>
|
||||||
|
|
||||||
|
<!-- Este DTD poderia ser algo como:-->
|
||||||
|
|
||||||
|
<!DOCTYPE note
|
||||||
|
[
|
||||||
|
<!ELEMENT livraria (livro+)>
|
||||||
|
<!ELEMENT livro (titulo,preco)>
|
||||||
|
<!ATTLIST livro category CDATA "Literature">
|
||||||
|
<!ELEMENT titulo (#PCDATA)>
|
||||||
|
<!ELEMENT preco (#PCDATA)>
|
||||||
|
]>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- O DTD começa com uma declaração.
|
||||||
|
Na sequência, o nó raiz é declarado, o que requer uma ou mais crianças nós
|
||||||
|
'Livro'. Cada 'Livro' deve conter exatamente um 'titulo' e um 'preco' e um
|
||||||
|
atributo chamado "categoria", com "Literatura", como o valor padrão.
|
||||||
|
Os nós "título" e "preço" contêm um conjunto de dados de caráter analisados.-->
|
||||||
|
|
||||||
|
<!-- O DTD poderia ser declarado dentro do próprio arquivo XML .-->
|
||||||
|
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<!DOCTYPE note
|
||||||
|
[
|
||||||
|
<!ELEMENT livraria (livro+)>
|
||||||
|
<!ELEMENT livro (titulo,preco)>
|
||||||
|
<!ATTLIST livro category CDATA "Literature">
|
||||||
|
<!ELEMENT titulo (#PCDATA)>
|
||||||
|
<!ELEMENT preco (#PCDATA)>
|
||||||
|
]>
|
||||||
|
|
||||||
|
<livraria>
|
||||||
|
<livro category="COOKING">
|
||||||
|
<titulo >Everyday Italian</titulo>
|
||||||
|
<preco>30.00</preco>
|
||||||
|
</livro>
|
||||||
|
</livraria>
|
||||||
|
```
|
83
ru-ru/brainfuck-ru.html.markdown
Normal file
83
ru-ru/brainfuck-ru.html.markdown
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
---
|
||||||
|
language: brainfuck
|
||||||
|
contributors:
|
||||||
|
- ["Prajit Ramachandran", "http://prajitr.github.io/"]
|
||||||
|
- ["Mathias Bynens", "http://mathiasbynens.be/"]
|
||||||
|
translators:
|
||||||
|
- ["Dmitry Bessonov", "https://github.com/TheDmitry"]
|
||||||
|
lang: ru-ru
|
||||||
|
---
|
||||||
|
|
||||||
|
Brainfuck (пишется маленькими буквами, кроме начала предложения) - это очень
|
||||||
|
маленький Тьюринг-полный язык программирования лишь с 8 командами.
|
||||||
|
|
||||||
|
```
|
||||||
|
Любой символ, кроме "><+-.,[]", игнорируется, за исключением кавычек.
|
||||||
|
|
||||||
|
Brainfuck представлен массивом из 30000 ячеек, инициализированных нулями,
|
||||||
|
и указателем с позицией в текущей ячейке.
|
||||||
|
|
||||||
|
Всего восемь команд:
|
||||||
|
+ : Увеличивает значение на единицу в текущей ячейке.
|
||||||
|
- : Уменьшает значение на единицу в текущей ячейке.
|
||||||
|
> : Смещает указатель данных на следующую ячейку (ячейку справа).
|
||||||
|
< : Смещает указатель данных на предыдущую ячейку (ячейку слева).
|
||||||
|
. : Печатает ASCII символ из текущей ячейки (напр. 65 = 'A').
|
||||||
|
, : Записывает один входной символ в текущую ячейку.
|
||||||
|
[ : Если значение в текущей ячейке равно нулю, то пропустить все команды
|
||||||
|
до соответствующей ] . В противном случае, перейти к следующей инструкции.
|
||||||
|
] : Если значение в текущей ячейке равно нулю, то перейти к следующей инструкции.
|
||||||
|
В противном случае, вернуться назад к соответствующей [ .
|
||||||
|
|
||||||
|
[ и ] образуют цикл while. Естественно, они должны быть сбалансированы.
|
||||||
|
|
||||||
|
Давайте рассмотрим некоторые базовые brainfuck-программы.
|
||||||
|
|
||||||
|
++++++ [ > ++++++++++ < - ] > +++++ .
|
||||||
|
|
||||||
|
Эта программа выводит букву 'A'. Сначала программа увеличивает значение
|
||||||
|
ячейки №1 до 6. Ячейка №1 будет использоваться циклом. Затем программа входит
|
||||||
|
в цикл ([) и переходит к ячейке №2. Ячейка №2 увеличивается до 10, переходим
|
||||||
|
назад к ячейке №1 и уменьшаем ячейку №1. Этот цикл проходит 6 раз (ячейка №1
|
||||||
|
уменьшается до нуля, и с этого места пропускает инструкции до соответствующей ]
|
||||||
|
и идет дальше).
|
||||||
|
|
||||||
|
В этот момент мы находимся в ячейке №1, которая имеет значение 0, значение
|
||||||
|
ячейки №2 пока 60. Мы переходим на ячейку №2, увеличиваем 5 раз, до значения 65,
|
||||||
|
и затем выводим значение ячейки №2. Код 65 является символом 'A' в кодировке ASCII,
|
||||||
|
так что 'A' выводится на терминал.
|
||||||
|
|
||||||
|
|
||||||
|
, [ > + < - ] > .
|
||||||
|
|
||||||
|
Данная программа считывает символ из пользовательского ввода и копирует символ
|
||||||
|
в ячейку №1. Затем мы начинаем цикл. Переходим к ячейке №2, увеличиваем значение
|
||||||
|
ячейки №2, идем назад к ячейке №1 и уменьшаем значение ячейки №1. Это продолжается
|
||||||
|
до тех пор, пока ячейка №1 не равна 0, а ячейка №2 сохраняет старое значение
|
||||||
|
ячейки №1. Мы завершаем цикл на ячейке №1, поэтому переходим в ячейку №2 и
|
||||||
|
затем выводим символ ASCII.
|
||||||
|
|
||||||
|
Также имейте в виду, что пробелы здесь исключительно для читабельности. Вы можете
|
||||||
|
легко написать и так:
|
||||||
|
|
||||||
|
,[>+<-]>.
|
||||||
|
|
||||||
|
Попытайтесь разгадать, что следующая программа делает:
|
||||||
|
|
||||||
|
,>,< [ > [ >+ >+ << -] >> [- << + >>] <<< -] >>
|
||||||
|
|
||||||
|
Программа принимает два числа на вход и умножает их.
|
||||||
|
|
||||||
|
Суть в том, что программа сначала читает два ввода. Затем начинается внешний цикл,
|
||||||
|
сохраняя ячейку №1. Затем программа перемещается в ячейку №2, и начинается
|
||||||
|
внутренний цикл с сохранением ячейки №2, увеличивая ячейку №3. Однако появляется
|
||||||
|
проблема: В конце внутреннего цикла ячейка №2 равна нулю. В этом случае,
|
||||||
|
внутренний цикл не будет работать уже в следующий раз. Чтобы решить эту проблему,
|
||||||
|
мы также увеличим ячейку №4, а затем копируем ячейку №4 в ячейку №2.
|
||||||
|
Итак, ячейка №3 - результат.
|
||||||
|
```
|
||||||
|
|
||||||
|
Это и есть brainfuck. Не так уж сложно, правда? Забавы ради, вы можете написать
|
||||||
|
свою собственную brainfuck-программу или интерпретатор на другом языке.
|
||||||
|
Интерпретатор достаточно легко реализовать, но если вы мазохист, попробуйте
|
||||||
|
написать brainfuck-интерпретатор... на языке brainfuck.
|
516
ru-ru/javascript-ru.html.markdown
Normal file
516
ru-ru/javascript-ru.html.markdown
Normal file
@ -0,0 +1,516 @@
|
|||||||
|
---
|
||||||
|
language: javascript
|
||||||
|
contributors:
|
||||||
|
- ["Adam Brenecki", "http://adam.brenecki.id.au"]
|
||||||
|
- ["Ariel Krakowski", "http://www.learneroo.com"]
|
||||||
|
filename: javascript-ru.js
|
||||||
|
translators:
|
||||||
|
- ["Alexey Gonchar", "http://github.com/finico"]
|
||||||
|
- ["Andre Polykanine", "https://github.com/Oire"]
|
||||||
|
lang: ru-ru
|
||||||
|
---
|
||||||
|
|
||||||
|
JavaScript был создан в 1995 году Бренданом Айком, работавшим в компании Netscape.
|
||||||
|
Изначально он был задуман как простой язык сценариев для веб-сайтов, дополняющий
|
||||||
|
Java для более сложных веб-приложений, но его тесная интеграция с веб-страницами
|
||||||
|
и встроенная поддержка браузерами привели к тому, что он стал более распространённым,
|
||||||
|
чем Java в веб-интерфейсах.
|
||||||
|
|
||||||
|
JavaScript не ограничивается только веб-браузером: например, Node.js, программная
|
||||||
|
платформа, позволяющая выполнять JavaScript, основанная на движке V8 от браузера
|
||||||
|
Google Chrome, становится все более популярной.
|
||||||
|
|
||||||
|
```js
|
||||||
|
// Си-подобные комментарии. Однострочные комментарии начинаются с двух символов слэш,
|
||||||
|
/* а многострочные комментарии начинаются с звёздочка-слэш
|
||||||
|
и заканчиваются символами слэш-звёздочка */
|
||||||
|
|
||||||
|
// Инструкции могут заканчиваться точкой с запятой ;
|
||||||
|
doStuff();
|
||||||
|
|
||||||
|
// ... но она необязательна, так как точки с запятой автоматически вставляются
|
||||||
|
// везде, где есть символ новой строки, за некоторыми исключениями.
|
||||||
|
doStuff()
|
||||||
|
|
||||||
|
// Так как эти исключения могут привести к неожиданным результатам, мы будем всегда
|
||||||
|
// использовать точку с запятой в этом руководстве.
|
||||||
|
|
||||||
|
///////////////////////////////////
|
||||||
|
// 1. Числа, Строки и Операторы
|
||||||
|
|
||||||
|
// В JavaScript только один тип числа (64-bit IEEE 754 double).
|
||||||
|
// Он имеет 52-битную мантиссу, которой достаточно для хранения целых чисел
|
||||||
|
// с точностью вплоть до 9✕10¹⁵.
|
||||||
|
3; // = 3
|
||||||
|
1.5; // = 1.5
|
||||||
|
|
||||||
|
// Некоторые простые арифметические операции работают так, как вы ожидаете.
|
||||||
|
1 + 1; // = 2
|
||||||
|
0.1 + 0.2; // = 0.30000000000000004 (а некоторые - нет)
|
||||||
|
8 - 1; // = 7
|
||||||
|
10 * 2; // = 20
|
||||||
|
35 / 5; // = 7
|
||||||
|
|
||||||
|
// Включая деление с остатком.
|
||||||
|
5 / 2; // = 2.5
|
||||||
|
|
||||||
|
// Побитовые операции также имеются; когда вы проводите такую операцию,
|
||||||
|
// ваше число с плавающей запятой переводится в целое со знаком
|
||||||
|
// длиной *до* 32 разрядов.
|
||||||
|
1 << 2; // = 4
|
||||||
|
|
||||||
|
// Приоритет в выражениях можно явно задать скобками.
|
||||||
|
(1 + 3) * 2; // = 8
|
||||||
|
|
||||||
|
// Есть три специальных значения, которые не являются реальными числами:
|
||||||
|
Infinity; // "бесконечность", например, результат деления на 0
|
||||||
|
-Infinity; // "минус бесконечность", результат деления отрицательного числа на 0
|
||||||
|
NaN; // "не число", например, результат деления 0/0
|
||||||
|
|
||||||
|
// Существует также логический тип.
|
||||||
|
true;
|
||||||
|
false;
|
||||||
|
|
||||||
|
// Строки создаются при помощи двойных или одинарных кавычек.
|
||||||
|
'абв';
|
||||||
|
"Привет, мир!";
|
||||||
|
|
||||||
|
// Для логического отрицания используется восклицательный знак.
|
||||||
|
!true; // = false
|
||||||
|
!false; // = true
|
||||||
|
|
||||||
|
// Строгое равенство ===
|
||||||
|
1 === 1; // = true
|
||||||
|
2 === 1; // = false
|
||||||
|
|
||||||
|
// Строгое неравенство !==
|
||||||
|
1 !== 1; // = false
|
||||||
|
2 !== 1; // = true
|
||||||
|
|
||||||
|
// Другие операторы сравнения
|
||||||
|
1 < 10; // = true
|
||||||
|
1 > 10; // = false
|
||||||
|
2 <= 2; // = true
|
||||||
|
2 >= 2; // = true
|
||||||
|
|
||||||
|
// Строки объединяются при помощи оператора +
|
||||||
|
"привет, " + "мир!"; // = "Привет, мир!"
|
||||||
|
|
||||||
|
// и сравниваются при помощи < и >
|
||||||
|
"a" < "b"; // = true
|
||||||
|
|
||||||
|
// Проверка равенства с приведением типов осуществляется двойным символом равно
|
||||||
|
"5" == 5; // = true
|
||||||
|
null == undefined; // = true
|
||||||
|
|
||||||
|
// ...если только не использовать ===
|
||||||
|
"5" === 5; // = false
|
||||||
|
null === undefined; // = false
|
||||||
|
|
||||||
|
// ...приведение типов может привести к странному поведению...
|
||||||
|
13 + !0; // 14
|
||||||
|
"13" + !0; // '13true'
|
||||||
|
|
||||||
|
// Вы можете получить доступ к любому символу строки, используя метод charAt
|
||||||
|
"Это строка".charAt(0); // = 'Э'
|
||||||
|
|
||||||
|
// ...или используйте метод substring, чтобы получить более крупные части
|
||||||
|
"Привет, мир".substring(0, 6); // = "Привет"
|
||||||
|
|
||||||
|
// length - это свойство, для его получения не нужно использовать ()
|
||||||
|
"Привет".length; // = 6
|
||||||
|
|
||||||
|
// Также есть null и undefined
|
||||||
|
null; // Намеренное отсутствие значения
|
||||||
|
undefined; // используется для обозначения переменных, не имеющих
|
||||||
|
// присвоенного значения (хотя непосредственно undefined
|
||||||
|
// является значением)
|
||||||
|
|
||||||
|
// false, null, undefined, NaN, 0 и "" — это ложь; всё остальное - истина.
|
||||||
|
// Следует отметить, что 0 — это ложь, а "0" — истина, несмотря на то, что
|
||||||
|
// 0 == "0".
|
||||||
|
|
||||||
|
///////////////////////////////////
|
||||||
|
// 2. Переменные, Массивы и Объекты
|
||||||
|
|
||||||
|
// Переменные объявляются при помощи ключевого слова var. JavaScript — язык с
|
||||||
|
// динамической типизацией, поэтому не нужно явно указывать тип. Для присваивания
|
||||||
|
// значения переменной используется символ =
|
||||||
|
var someVar = 5;
|
||||||
|
|
||||||
|
// если вы пропустите слово var, вы не получите сообщение об ошибке, ...
|
||||||
|
someOtherVar = 10;
|
||||||
|
|
||||||
|
// ...но ваша переменная будет создана в глобальном контексте, а не в текущем,
|
||||||
|
// где вы ее объявили.
|
||||||
|
|
||||||
|
// Переменным, объявленным без присвоения, устанавливается значение undefined.
|
||||||
|
var someThirdVar; // = undefined
|
||||||
|
|
||||||
|
// У математических операций есть сокращённые формы:
|
||||||
|
someVar += 5; // как someVar = someVar + 5; someVar теперь имеет значение 10
|
||||||
|
someVar *= 10; // теперь someVar имеет значение 100
|
||||||
|
|
||||||
|
// Ещё более краткая запись увеличения и уменьшения на единицу:
|
||||||
|
someVar++; // теперь someVar имеет значение 101
|
||||||
|
someVar--; // вернулись к 100
|
||||||
|
|
||||||
|
// Массивы — это нумерованные списки, содержащие значения любого типа.
|
||||||
|
var myArray = ["Привет", 45, true];
|
||||||
|
|
||||||
|
// Их элементы могут быть доступны при помощи синтаксиса с квадратными скобками.
|
||||||
|
// Индексы массивов начинаются с нуля.
|
||||||
|
myArray[1]; // = 45
|
||||||
|
|
||||||
|
// Массивы можно изменять, как и их длину,
|
||||||
|
myArray.push("Мир");
|
||||||
|
myArray.length; // = 4
|
||||||
|
|
||||||
|
// добавлять и редактировать определённый элемент
|
||||||
|
myArray[3] = "Привет";
|
||||||
|
|
||||||
|
// Объекты в JavaScript похожи на словари или ассоциативные массивы в других
|
||||||
|
// языках: неупорядоченный набор пар ключ-значение.
|
||||||
|
var myObj = {key1: "Привет", key2: "Мир"};
|
||||||
|
|
||||||
|
// Ключи — это строки, но кавычки необязательны, если строка удовлетворяет
|
||||||
|
// ограничениям для имён переменных. Значения могут быть любых типов.
|
||||||
|
var myObj = {myKey: "myValue", "my other key": 4};
|
||||||
|
|
||||||
|
// Атрибуты объектов можно также получить, используя квадратные скобки
|
||||||
|
myObj["my other key"]; // = 4
|
||||||
|
|
||||||
|
// или через точку, при условии, что ключ является допустимым идентификатором.
|
||||||
|
myObj.myKey; // = "myValue"
|
||||||
|
|
||||||
|
// Объекты изменяемы; можно изменять значения и добавлять новые ключи.
|
||||||
|
myObj.myThirdKey = true;
|
||||||
|
|
||||||
|
// Если вы попытаетесь получить доступ к несуществующему значению,
|
||||||
|
// вы получите undefined.
|
||||||
|
myObj.myFourthKey; // = undefined
|
||||||
|
|
||||||
|
///////////////////////////////////
|
||||||
|
// 3. Логика и управляющие конструкции.
|
||||||
|
|
||||||
|
// Синтаксис для этого раздела почти такой же, как в Java.
|
||||||
|
|
||||||
|
// Условная конструкция работает, как и следовало ожидать,
|
||||||
|
var count = 1;
|
||||||
|
if (count == 3) {
|
||||||
|
// выполняется, если count равен 3
|
||||||
|
} else if (count == 4) {
|
||||||
|
// выполняется, если count равен 4
|
||||||
|
} else {
|
||||||
|
// выполняется, если не 3 и не 4
|
||||||
|
}
|
||||||
|
|
||||||
|
// ...как и цикл while.
|
||||||
|
while (true){
|
||||||
|
// Бесконечный цикл!
|
||||||
|
}
|
||||||
|
|
||||||
|
// Цикл do-while такой же, как while, но он всегда выполняется хотя бы раз.
|
||||||
|
var input
|
||||||
|
do {
|
||||||
|
input = getInput();
|
||||||
|
} while (!isValid(input))
|
||||||
|
|
||||||
|
// цикл for такой же, как в C и Java:
|
||||||
|
// инициализация; условие; шаг.
|
||||||
|
for (var i = 0; i < 5; i++) {
|
||||||
|
// выполнится 5 раз
|
||||||
|
}
|
||||||
|
|
||||||
|
// && — это логическое И, || — это логическое ИЛИ
|
||||||
|
if (house.size == "big" && house.color == "blue") {
|
||||||
|
house.contains = "bear";
|
||||||
|
}
|
||||||
|
if (color == "red" || color == "blue") {
|
||||||
|
// цвет красный или синий
|
||||||
|
}
|
||||||
|
|
||||||
|
// && и || используют сокращённое вычисление, что полезно
|
||||||
|
// для задания значений по умолчанию.
|
||||||
|
var name = otherName || "default";
|
||||||
|
|
||||||
|
// Оператор switch выполняет проверку на равенство при помощи ===
|
||||||
|
// используйте break, чтобы прервать выполнение после каждого case,
|
||||||
|
// или выполнение пойдёт далее даже после правильного варианта.
|
||||||
|
grade = 4;
|
||||||
|
switch (grade) {
|
||||||
|
case 5:
|
||||||
|
console.log("Отлично");
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
console.log("Хорошо");
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
console.log("Можете и лучше");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
console.log("Ой-вей!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////
|
||||||
|
// 4. Функции, Область видимости и Замыкания
|
||||||
|
|
||||||
|
// Функции в JavaScript объявляются при помощи ключевого слова function.
|
||||||
|
function myFunction(thing) {
|
||||||
|
return thing.toUpperCase();
|
||||||
|
}
|
||||||
|
myFunction("foo"); // = "FOO"
|
||||||
|
|
||||||
|
// Обратите внимание, что значение, которое будет возвращено, должно начинаться
|
||||||
|
// на той же строке, что и ключевое слово return, в противном случае вы будете
|
||||||
|
// всегда возвращать undefined по причине автоматической вставки точки с запятой.
|
||||||
|
// Следите за этим при использовании стиля форматирования Allman.
|
||||||
|
function myFunction()
|
||||||
|
{
|
||||||
|
return // <- здесь точка с запятой вставится автоматически
|
||||||
|
{
|
||||||
|
thisIsAn: 'object literal'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
myFunction(); // = undefined
|
||||||
|
|
||||||
|
// В JavaScript функции — это объекты первого класса, поэтому они могут быть
|
||||||
|
// присвоены различным именам переменных и передаваться другим функциям
|
||||||
|
// в качестве аргументов, например, когда назначается обработчик события:
|
||||||
|
function myFunction() {
|
||||||
|
// этот код будет вызван через 5 секунд
|
||||||
|
}
|
||||||
|
setTimeout(myFunction, 5000);
|
||||||
|
// Примечание: setTimeout не является частью языка, но реализован в браузерах и Node.js
|
||||||
|
|
||||||
|
// Функции не обязательно должны иметь имя при объявлении — вы можете написать
|
||||||
|
// анонимное определение функции непосредственно в аргументе другой функции.
|
||||||
|
setTimeout(function() {
|
||||||
|
// этот код будет вызван через 5 секунд
|
||||||
|
}, 5000);
|
||||||
|
|
||||||
|
// В JavaScript есть область видимости; функции имеют свою область
|
||||||
|
// видимости, а другие блоки — нет.
|
||||||
|
if (true) {
|
||||||
|
var i = 5;
|
||||||
|
}
|
||||||
|
i; // = 5, а не undefined, как ожидалось бы в языках с блочной областью видимости
|
||||||
|
|
||||||
|
// Это привело к общепринятому шаблону "самозапускающихся анонимных функций",
|
||||||
|
// которые препятствуют проникновению переменных в глобальную область видимости
|
||||||
|
(function() {
|
||||||
|
var temporary = 5;
|
||||||
|
// Мы можем получить доступ к глобальной области для записи в «глобальный объект»,
|
||||||
|
// который в веб-браузере всегда window. Глобальный объект может иметь другое
|
||||||
|
// имя в таких платформах, как Node.js
|
||||||
|
window.permanent = 10;
|
||||||
|
})();
|
||||||
|
temporary; // вызовет сообщение об ошибке с типом ReferenceError
|
||||||
|
permanent; // = 10
|
||||||
|
|
||||||
|
// Одной из самых мощных возможностей JavaScript являются замыкания. Если функция
|
||||||
|
// определена внутри другой функции, то внутренняя функция имеет доступ к
|
||||||
|
// переменным внешней функции даже после того, как контекст выполнения выйдет из
|
||||||
|
// внешней функции.
|
||||||
|
function sayHelloInFiveSeconds(name) {
|
||||||
|
var prompt = "Привет, " + name + "!";
|
||||||
|
// Внутренние функции по умолчанию помещаются в локальную область видимости,
|
||||||
|
// как если бы они были объявлены с помощью var.
|
||||||
|
function inner() {
|
||||||
|
alert(prompt);
|
||||||
|
}
|
||||||
|
setTimeout(inner, 5000);
|
||||||
|
// setTimeout асинхронна, поэтому функция sayHelloInFiveSeconds сразу выйдет,
|
||||||
|
// после чего setTimeout вызовет функцию inner. Однако поскольку функция inner
|
||||||
|
// «замкнута» вокруг sayHelloInFiveSeconds, она по-прежнему имеет доступ к переменной prompt
|
||||||
|
// на то время, когда она наконец будет вызвана.
|
||||||
|
}
|
||||||
|
sayHelloInFiveSeconds("Адам"); // Через 5 с откроется окно «Привет, Адам!»
|
||||||
|
|
||||||
|
///////////////////////////////////
|
||||||
|
// 5. Подробнее об объектах; конструкторы и прототипы
|
||||||
|
|
||||||
|
// Объекты могут содержать в себе функции.
|
||||||
|
var myObj = {
|
||||||
|
myFunc: function() {
|
||||||
|
return "Привет, мир!";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
myObj.myFunc(); // = "Привет, мир!"
|
||||||
|
|
||||||
|
// Когда вызываются функции, прикреплённые к объекту, они могут получить доступ
|
||||||
|
// к этому объекту с помощью ключевого слова this.
|
||||||
|
myObj = {
|
||||||
|
myString: "Привет, мир!",
|
||||||
|
myFunc: function() {
|
||||||
|
return this.myString;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
myObj.myFunc(); // = "Привет, мир!"
|
||||||
|
|
||||||
|
// Значение this зависит от того, как функция вызывается,
|
||||||
|
// а не от того, где она определена. Таким образом, наша функция не работает,
|
||||||
|
// если она вызывается не в контексте объекта.
|
||||||
|
var myFunc = myObj.myFunc;
|
||||||
|
myFunc(); // = undefined
|
||||||
|
|
||||||
|
// И наоборот, функция может быть присвоена объекту и получать доступ к нему
|
||||||
|
// через this, даже если она не была прикреплена к нему при объявлении.
|
||||||
|
var myOtherFunc = function() {
|
||||||
|
}
|
||||||
|
myObj.myOtherFunc = myOtherFunc;
|
||||||
|
myObj.myOtherFunc(); // = "ПРИВЕТ, МИР!"
|
||||||
|
|
||||||
|
// Мы можем также указать контекст для выполнения функции при её вызове,
|
||||||
|
// используя call или apply.
|
||||||
|
var anotherFunc = function(s) {
|
||||||
|
return this.myString + s;
|
||||||
|
}
|
||||||
|
anotherFunc.call(myObj, " И привет, Луна!"); // = "Привет, мир! И привет, Луна!"
|
||||||
|
|
||||||
|
// Функция apply почти такая же, но принимает в качестве списка аргументов массив.
|
||||||
|
anotherFunc.apply(myObj, [" И привет, Солнце!"]); // = "Привет, мир! И привет, Солнце!"
|
||||||
|
|
||||||
|
// Это полезно при работе с функцией, которая принимает последовательность
|
||||||
|
// аргументов, а вы хотите передать массив.
|
||||||
|
Math.min(42, 6, 27); // = 6
|
||||||
|
Math.min([42, 6, 27]); // = NaN (Ой-ой!)
|
||||||
|
Math.min.apply(Math, [42, 6, 27]); // = 6
|
||||||
|
|
||||||
|
// Но call и apply — только временные. Когда мы хотим связать функцию с объектом,
|
||||||
|
// мы можем использовать bind.
|
||||||
|
var boundFunc = anotherFunc.bind(myObj);
|
||||||
|
boundFunc(" И привет, Сатурн!"); // = "Привет, мир! И привет, Сатурн!"
|
||||||
|
|
||||||
|
// Bind также может использоваться для частичного применения (каррирования) функции
|
||||||
|
var product = function(a, b) { return a * b; }
|
||||||
|
var doubler = product.bind(this, 2);
|
||||||
|
doubler(8); // = 16
|
||||||
|
|
||||||
|
// Когда вы вызываете функцию с помощью ключевого слова new, создается новый объект,
|
||||||
|
// доступный функции при помощи this. Такие функции называют конструкторами.
|
||||||
|
var MyConstructor = function() {
|
||||||
|
this.myNumber = 5;
|
||||||
|
}
|
||||||
|
myNewObj = new MyConstructor(); // = {myNumber: 5}
|
||||||
|
myNewObj.myNumber; // = 5
|
||||||
|
|
||||||
|
// У каждого объекта в JavaScript есть прототип. Когда вы хотите получить
|
||||||
|
// доступ к свойству объекта, которое не существует в этом объекте, интерпретатор
|
||||||
|
// будет искать это свойство в прототипе.
|
||||||
|
|
||||||
|
// Некоторые реализации языка позволяют получить доступ к прототипу объекта
|
||||||
|
// через «магическое» свойство __proto__. Несмотря на то, что это может быть полезно
|
||||||
|
// для понимания прототипов, это не часть стандарта; мы увидим стандартные способы
|
||||||
|
// использования прототипов позже.
|
||||||
|
var myObj = {
|
||||||
|
myString: "Привет, мир!"
|
||||||
|
};
|
||||||
|
var myPrototype = {
|
||||||
|
meaningOfLife: 42,
|
||||||
|
myFunc: function() {
|
||||||
|
return this.myString.toLowerCase()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
myObj.__proto__ = myPrototype;
|
||||||
|
myObj.meaningOfLife; // = 42
|
||||||
|
|
||||||
|
// Для функций это тоже работает.
|
||||||
|
myObj.myFunc(); // = "Привет, мир!"
|
||||||
|
|
||||||
|
// Если интерпретатор не найдёт свойство в прототипе, то продожит поиск
|
||||||
|
// в прототипе прототипа и так далее.
|
||||||
|
myPrototype.__proto__ = {
|
||||||
|
myBoolean: true
|
||||||
|
};
|
||||||
|
myObj.myBoolean; // = true
|
||||||
|
|
||||||
|
// Здесь не участвует копирование; каждый объект хранит ссылку на свой прототип.
|
||||||
|
// Это означает, что мы можем изменить прототип, и наши изменения будут отражены везде.
|
||||||
|
myPrototype.meaningOfLife = 43;
|
||||||
|
myObj.meaningOfLife; // = 43
|
||||||
|
|
||||||
|
// Мы упомянули, что свойство __proto__ нестандартно, и нет никакого стандартного
|
||||||
|
// способа, чтобы изменить прототип существующего объекта. Однако есть два
|
||||||
|
// способа создать новый объект с заданным прототипом.
|
||||||
|
|
||||||
|
// Первый способ — это Object.create, который появился в JavaScript недавно,
|
||||||
|
// а потому доступен ещё не во всех реализациях языка.
|
||||||
|
var myObj = Object.create(myPrototype);
|
||||||
|
myObj.meaningOfLife; // = 43
|
||||||
|
|
||||||
|
// Второй способ, который работает везде, имеет дело с конструкторами.
|
||||||
|
// У конструкторов есть свойство с именем prototype. Это *не* прототип
|
||||||
|
// функции-конструктора; напротив, это прототип для новых объектов, которые
|
||||||
|
// будут созданы с помощью этого конструктора и ключевого слова new.
|
||||||
|
MyConstructor.prototype = {
|
||||||
|
myNumber: 5,
|
||||||
|
getMyNumber: function() {
|
||||||
|
return this.myNumber;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var myNewObj2 = new MyConstructor();
|
||||||
|
myNewObj2.getMyNumber(); // = 5
|
||||||
|
myNewObj2.myNumber = 6
|
||||||
|
myNewObj2.getMyNumber(); // = 6
|
||||||
|
|
||||||
|
// У встроенных типов, таких, как строки и числа, также есть конструкторы, которые
|
||||||
|
// создают эквивалентные объекты-обёртки.
|
||||||
|
var myNumber = 12;
|
||||||
|
var myNumberObj = new Number(12);
|
||||||
|
myNumber == myNumberObj; // = true
|
||||||
|
|
||||||
|
// За исключением того, что они не в точности равны.
|
||||||
|
typeof myNumber; // = 'number'
|
||||||
|
typeof myNumberObj; // = 'object'
|
||||||
|
myNumber === myNumberObj; // = false
|
||||||
|
if (0) {
|
||||||
|
// Этот код не выполнится, потому что 0 - это ложь.
|
||||||
|
}
|
||||||
|
if (Number(0)) {
|
||||||
|
// Этот код *выполнится*, потому что Number(0) истинно.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Впрочем, объекты-обёртки и встроенные типы имеют общие прототипы,
|
||||||
|
// поэтому вы можете расширить функционал строк, например:
|
||||||
|
String.prototype.firstCharacter = function() {
|
||||||
|
return this.charAt(0);
|
||||||
|
}
|
||||||
|
"abc".firstCharacter(); // = "a"
|
||||||
|
|
||||||
|
// Это часто используется в т.н. полифилах, которые реализуют новые возможности
|
||||||
|
// JavaScript в старой реализации языка, так что они могут быть использованы в
|
||||||
|
// старых средах, таких, как устаревшие браузеры.
|
||||||
|
|
||||||
|
// Например, мы упомянули, что Object.create доступен не во всех реализациях, но
|
||||||
|
// мы сможем использовать его с помощью такого полифила:
|
||||||
|
if (Object.create === undefined) { // не перезаписываем метод, если он существует
|
||||||
|
Object.create = function(proto) {
|
||||||
|
// создаём временный конструктор с правильным прототипом
|
||||||
|
var Constructor = function(){};
|
||||||
|
Constructor.prototype = proto;
|
||||||
|
// затем используем его для создания нового,
|
||||||
|
// правильно прототипированного объекта
|
||||||
|
return new Constructor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Что ещё почитать
|
||||||
|
|
||||||
|
[Современный учебник JavaScript (Илья Кантор)](http://learn.javascript.ru) —
|
||||||
|
качественный учебник по JavaScript на русском языке.
|
||||||
|
|
||||||
|
[Mozilla Developer Network](https://developer.mozilla.org/ru/docs/Web/JavaScript) —
|
||||||
|
предоставляет отличную документацию для JavaScript, как он используется в браузерах.
|
||||||
|
Кроме того, это вики, поэтому, если вы знаете больше, вы можете помочь другим,
|
||||||
|
делясь своими знаниями.
|
||||||
|
|
||||||
|
[JavaScript Garden](http://bonsaiden.github.io/JavaScript-Garden/ru/) — это
|
||||||
|
подробное руководство по всем неинтуитивным особенностей языка.
|
||||||
|
|
||||||
|
[Stack Overflow](http://stackoverflow.com/questions/tagged/javascript) — можно
|
||||||
|
найти ответ почти на любой ваш вопрос, а если его нет, то задать вопрос самому.
|
@ -7,9 +7,13 @@ filename: learnrust.rs
|
|||||||
|
|
||||||
Rust is an in-development programming language developed by Mozilla Research.
|
Rust is an in-development programming language developed by Mozilla Research.
|
||||||
It is relatively unique among systems languages in that it can assert memory
|
It is relatively unique among systems languages in that it can assert memory
|
||||||
safety *at compile time*. Rust’s first alpha release occurred in January
|
safety *at compile time* without resorting to garbage collection. Rust’s first
|
||||||
2012, and development moves so quickly that at the moment the use of stable
|
release, 0.1, occurred in January 2012, and development moves so quickly that at
|
||||||
releases is discouraged, and instead one should use nightly builds.
|
the moment the use of stable releases is discouraged, and instead one should use
|
||||||
|
nightly builds. On January 9 2015, Rust 1.0 Alpha was released, and the rate of
|
||||||
|
changes to the Rust compiler that break existing code has dropped significantly
|
||||||
|
since. However, a complete guarantee of backward compatibility will not exist
|
||||||
|
until the final 1.0 release.
|
||||||
|
|
||||||
Although Rust is a relatively low-level language, Rust has some functional
|
Although Rust is a relatively low-level language, Rust has some functional
|
||||||
concepts that are generally found in higher-level languages. This makes
|
concepts that are generally found in higher-level languages. This makes
|
||||||
@ -24,7 +28,8 @@ Rust not only fast, but also easy and efficient to code in.
|
|||||||
///////////////
|
///////////////
|
||||||
|
|
||||||
// Functions
|
// Functions
|
||||||
fn add2(x: int, y: int) -> int {
|
// `i32` is the type for 32-bit signed integers
|
||||||
|
fn add2(x: i32, y: i32) -> i32 {
|
||||||
// Implicit return (no semicolon)
|
// Implicit return (no semicolon)
|
||||||
x + y
|
x + y
|
||||||
}
|
}
|
||||||
@ -34,71 +39,90 @@ fn main() {
|
|||||||
// Numbers //
|
// Numbers //
|
||||||
|
|
||||||
// Immutable bindings
|
// Immutable bindings
|
||||||
let x: int = 1;
|
let x: i32 = 1;
|
||||||
|
|
||||||
// Integer/float suffixes
|
// Integer/float suffixes
|
||||||
let y: int = 13i;
|
let y: i32 = 13i32;
|
||||||
let f: f64 = 1.3f64;
|
let f: f64 = 1.3f64;
|
||||||
|
|
||||||
// Type inference
|
// Type inference
|
||||||
let implicit_x = 1i;
|
// Most of the time, the Rust compiler can infer what type a variable is, so
|
||||||
let implicit_f = 1.3f64;
|
// you don’t have to write an explicit type annotation.
|
||||||
|
// Throughout this tutorial, types are explicitly annotated in many places,
|
||||||
|
// but only for demonstrative purposes. Type inference can handle this for
|
||||||
|
// you most of the time.
|
||||||
|
let implicit_x = 1;
|
||||||
|
let implicit_f = 1.3;
|
||||||
|
|
||||||
// Maths
|
// Arithmetic
|
||||||
let sum = x + y + 13i;
|
let sum = x + y + 13;
|
||||||
|
|
||||||
// Mutable variable
|
// Mutable variable
|
||||||
let mut mutable = 1;
|
let mut mutable = 1;
|
||||||
|
mutable = 4;
|
||||||
mutable += 2;
|
mutable += 2;
|
||||||
|
|
||||||
// Strings //
|
// Strings //
|
||||||
|
|
||||||
// String literals
|
// String literals
|
||||||
let x: &'static str = "hello world!";
|
let x: &str = "hello world!";
|
||||||
|
|
||||||
// Printing
|
// Printing
|
||||||
println!("{} {}", f, x); // 1.3 hello world
|
println!("{} {}", f, x); // 1.3 hello world
|
||||||
|
|
||||||
// A `String` - a heap-allocated string
|
// A `String` – a heap-allocated string
|
||||||
let s: String = "hello world".to_string();
|
let s: String = "hello world".to_string();
|
||||||
|
|
||||||
// A string slice - an immutable view into another string
|
// A string slice – an immutable view into another string
|
||||||
// This is basically an immutable pointer to a string - it doesn’t
|
// This is basically an immutable pointer to a string – it doesn’t
|
||||||
// actually contain the characters of a string, just a pointer to
|
// actually contain the contents of a string, just a pointer to
|
||||||
// something that does (in this case, `s`)
|
// something that does (in this case, `s`)
|
||||||
let s_slice: &str = s.as_slice();
|
let s_slice: &str = &*s;
|
||||||
|
|
||||||
println!("{} {}", s, s_slice); // hello world hello world
|
println!("{} {}", s, s_slice); // hello world hello world
|
||||||
|
|
||||||
// Vectors/arrays //
|
// Vectors/arrays //
|
||||||
|
|
||||||
// A fixed-size array
|
// A fixed-size array
|
||||||
let four_ints: [int, ..4] = [1, 2, 3, 4];
|
let four_ints: [i32; 4] = [1, 2, 3, 4];
|
||||||
|
|
||||||
// A dynamically-sized vector
|
// A dynamic array (vector)
|
||||||
let mut vector: Vec<int> = vec![1, 2, 3, 4];
|
let mut vector: Vec<i32> = vec![1, 2, 3, 4];
|
||||||
vector.push(5);
|
vector.push(5);
|
||||||
|
|
||||||
// A slice - an immutable view into a vector or array
|
// A slice – an immutable view into a vector or array
|
||||||
// This is much like a string slice, but for vectors
|
// This is much like a string slice, but for vectors
|
||||||
let slice: &[int] = vector.as_slice();
|
let slice: &[i32] = &*vector;
|
||||||
|
|
||||||
println!("{} {}", vector, slice); // [1, 2, 3, 4, 5] [1, 2, 3, 4, 5]
|
// Use `{:?}` to print something debug-style
|
||||||
|
println!("{:?} {:?}", vector, slice); // [1, 2, 3, 4, 5] [1, 2, 3, 4, 5]
|
||||||
|
|
||||||
|
// Tuples //
|
||||||
|
|
||||||
|
// A tuple is a fixed-size set of values of possibly different types
|
||||||
|
let x: (i32, &str, f64) = (1, "hello", 3.4);
|
||||||
|
|
||||||
|
// Destructuring `let`
|
||||||
|
let (a, b, c) = x;
|
||||||
|
println!("{} {} {}", a, b, c); // 1 hello 3.4
|
||||||
|
|
||||||
|
// Indexing
|
||||||
|
println!("{}", x.1); // hello
|
||||||
|
|
||||||
//////////////
|
//////////////
|
||||||
// 2. Types //
|
// 2. Types //
|
||||||
//////////////
|
//////////////
|
||||||
|
|
||||||
// Struct
|
// Struct
|
||||||
struct Point {
|
struct Point {
|
||||||
x: int,
|
x: i32,
|
||||||
y: int,
|
y: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
let origin: Point = Point { x: 0, y: 0 };
|
let origin: Point = Point { x: 0, y: 0 };
|
||||||
|
|
||||||
// Tuple struct
|
// A struct with unnamed fields, called a ‘tuple struct’
|
||||||
struct Point2(int, int);
|
struct Point2(i32, i32);
|
||||||
|
|
||||||
let origin2 = Point2(0, 0);
|
let origin2 = Point2(0, 0);
|
||||||
|
|
||||||
@ -110,16 +134,16 @@ fn main() {
|
|||||||
Down,
|
Down,
|
||||||
}
|
}
|
||||||
|
|
||||||
let up = Up;
|
let up = Direction::Up;
|
||||||
|
|
||||||
// Enum with fields
|
// Enum with fields
|
||||||
enum OptionalInt {
|
enum OptionalI32 {
|
||||||
AnInt(int),
|
AnI32(i32),
|
||||||
Nothing,
|
Nothing,
|
||||||
}
|
}
|
||||||
|
|
||||||
let two: OptionalInt = AnInt(2);
|
let two: OptionalI32 = OptionalI32::AnI32(2);
|
||||||
let nothing: OptionalInt = Nothing;
|
let nothing = OptionalI32::Nothing;
|
||||||
|
|
||||||
// Generics //
|
// Generics //
|
||||||
|
|
||||||
@ -140,10 +164,10 @@ fn main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let a_foo = Foo { bar: 1i };
|
let a_foo = Foo { bar: 1 };
|
||||||
println!("{}", a_foo.get_bar()); // 1
|
println!("{}", a_foo.get_bar()); // 1
|
||||||
|
|
||||||
// Traits (interfaces) //
|
// Traits (known as interfaces or typeclasses in other languages) //
|
||||||
|
|
||||||
trait Frobnicate<T> {
|
trait Frobnicate<T> {
|
||||||
fn frobnicate(self) -> Option<T>;
|
fn frobnicate(self) -> Option<T>;
|
||||||
@ -155,30 +179,31 @@ fn main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("{}", a_foo.frobnicate()); // Some(1)
|
let another_foo = Foo { bar: 1 };
|
||||||
|
println!("{:?}", another_foo.frobnicate()); // Some(1)
|
||||||
|
|
||||||
/////////////////////////
|
/////////////////////////
|
||||||
// 3. Pattern matching //
|
// 3. Pattern matching //
|
||||||
/////////////////////////
|
/////////////////////////
|
||||||
|
|
||||||
let foo = AnInt(1);
|
let foo = OptionalI32::AnI32(1);
|
||||||
match foo {
|
match foo {
|
||||||
AnInt(n) => println!("it’s an int: {}", n),
|
OptionalI32::AnI32(n) => println!("it’s an i32: {}", n),
|
||||||
Nothing => println!("it’s nothing!"),
|
OptionalI32::Nothing => println!("it’s nothing!"),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Advanced pattern matching
|
// Advanced pattern matching
|
||||||
struct FooBar { x: int, y: OptionalInt }
|
struct FooBar { x: i32, y: OptionalI32 }
|
||||||
let bar = FooBar { x: 15, y: AnInt(32) };
|
let bar = FooBar { x: 15, y: OptionalI32::AnI32(32) };
|
||||||
|
|
||||||
match bar {
|
match bar {
|
||||||
FooBar { x: 0, y: AnInt(0) } =>
|
FooBar { x: 0, y: OptionalI32::AnI32(0) } =>
|
||||||
println!("The numbers are zero!"),
|
println!("The numbers are zero!"),
|
||||||
FooBar { x: n, y: AnInt(m) } if n == m =>
|
FooBar { x: n, y: OptionalI32::AnI32(m) } if n == m =>
|
||||||
println!("The numbers are the same"),
|
println!("The numbers are the same"),
|
||||||
FooBar { x: n, y: AnInt(m) } =>
|
FooBar { x: n, y: OptionalI32::AnI32(m) } =>
|
||||||
println!("Different numbers: {} {}", n, m),
|
println!("Different numbers: {} {}", n, m),
|
||||||
FooBar { x: _, y: Nothing } =>
|
FooBar { x: _, y: OptionalI32::Nothing } =>
|
||||||
println!("The second number is Nothing!"),
|
println!("The second number is Nothing!"),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,19 +212,20 @@ fn main() {
|
|||||||
/////////////////////
|
/////////////////////
|
||||||
|
|
||||||
// `for` loops/iteration
|
// `for` loops/iteration
|
||||||
let array = [1i, 2, 3];
|
let array = [1, 2, 3];
|
||||||
for i in array.iter() {
|
for i in array.iter() {
|
||||||
println!("{}", i);
|
println!("{}", i);
|
||||||
}
|
}
|
||||||
|
|
||||||
for i in range(0u, 10) {
|
// Ranges
|
||||||
|
for i in 0u32..10 {
|
||||||
print!("{} ", i);
|
print!("{} ", i);
|
||||||
}
|
}
|
||||||
println!("");
|
println!("");
|
||||||
// prints `0 1 2 3 4 5 6 7 8 9 `
|
// prints `0 1 2 3 4 5 6 7 8 9 `
|
||||||
|
|
||||||
// `if`
|
// `if`
|
||||||
if 1i == 1 {
|
if 1 == 1 {
|
||||||
println!("Maths is working!");
|
println!("Maths is working!");
|
||||||
} else {
|
} else {
|
||||||
println!("Oh no...");
|
println!("Oh no...");
|
||||||
@ -213,7 +239,7 @@ fn main() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// `while` loop
|
// `while` loop
|
||||||
while 1i == 1 {
|
while 1 == 1 {
|
||||||
println!("The universe is operating normally.");
|
println!("The universe is operating normally.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -225,40 +251,49 @@ fn main() {
|
|||||||
/////////////////////////////////
|
/////////////////////////////////
|
||||||
// 5. Memory safety & pointers //
|
// 5. Memory safety & pointers //
|
||||||
/////////////////////////////////
|
/////////////////////////////////
|
||||||
|
|
||||||
// Owned pointer - only one thing can ‘own’ this pointer at a time
|
// Owned pointer – only one thing can ‘own’ this pointer at a time
|
||||||
let mut mine: Box<int> = box 3;
|
// This means that when the `Box` leaves its scope, it can be automatically deallocated safely.
|
||||||
|
let mut mine: Box<i32> = Box::new(3);
|
||||||
*mine = 5; // dereference
|
*mine = 5; // dereference
|
||||||
|
// Here, `now_its_mine` takes ownership of `mine`. In other words, `mine` is moved.
|
||||||
let mut now_its_mine = mine;
|
let mut now_its_mine = mine;
|
||||||
*now_its_mine += 2;
|
*now_its_mine += 2;
|
||||||
println!("{}", now_its_mine); // 7
|
|
||||||
// println!("{}", mine); // this would error
|
|
||||||
|
|
||||||
// Reference - an immutable pointer that refers to other data
|
println!("{}", now_its_mine); // 7
|
||||||
let mut var = 4i;
|
// println!("{}", mine); // this would not compile because `now_its_mine` now owns the pointer
|
||||||
|
|
||||||
|
// Reference – an immutable pointer that refers to other data
|
||||||
|
// When a reference is taken to a value, we say that the value has been ‘borrowed’.
|
||||||
|
// While a value is borrowed immutably, it cannot be mutated or moved.
|
||||||
|
// A borrow lasts until the end of the scope it was created in.
|
||||||
|
let mut var = 4;
|
||||||
var = 3;
|
var = 3;
|
||||||
let ref_var: &int = &var;
|
let ref_var: &i32 = &var;
|
||||||
|
|
||||||
println!("{}", var); // Unlike `box`, `var` can still be used
|
println!("{}", var); // Unlike `box`, `var` can still be used
|
||||||
println!("{}", *ref_var);
|
println!("{}", *ref_var);
|
||||||
// var = 5; // this would error
|
// var = 5; // this would not compile because `var` is borrowed
|
||||||
// *ref_var = 6; // this would too
|
// *ref_var = 6; // this would too, because `ref_var` is an immutable reference
|
||||||
|
|
||||||
// Mutable reference
|
// Mutable reference
|
||||||
let mut var2 = 4i;
|
// While a value is mutably borrowed, it cannot be accessed at all.
|
||||||
let ref_var2: &mut int = &mut var2;
|
let mut var2 = 4;
|
||||||
|
let ref_var2: &mut i32 = &mut var2;
|
||||||
*ref_var2 += 2;
|
*ref_var2 += 2;
|
||||||
|
|
||||||
println!("{}", *ref_var2); // 6
|
println!("{}", *ref_var2); // 6
|
||||||
// var2 = 2; // this would error
|
// var2 = 2; // this would not compile because `var2` is borrowed
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Further reading
|
## Further reading
|
||||||
|
|
||||||
There’s a lot more to Rust—this is just the basics of Rust so you can
|
There’s a lot more to Rust—this is just the basics of Rust so you can understand
|
||||||
understand the most important things. To learn more about Rust, read [The Rust
|
the most important things. To learn more about Rust, read [The Rust Programming
|
||||||
Guide](http://doc.rust-lang.org/guide.html) and check out the
|
Language](http://doc.rust-lang.org/book/index.html) and check out the
|
||||||
[/r/rust](http://reddit.com/r/rust) subreddit. The folks on the #rust channel
|
[/r/rust](http://reddit.com/r/rust) subreddit. The folks on the #rust channel on
|
||||||
on irc.mozilla.org are also always keen to help newcomers.
|
irc.mozilla.org are also always keen to help newcomers.
|
||||||
|
|
||||||
You can also try out features of Rust with an online compiler at the official
|
You can also try out features of Rust with an online compiler at the official
|
||||||
[Rust playpen](http://play.rust-lang.org) or on the main
|
[Rust playpen](http://play.rust-lang.org) or on the main
|
||||||
|
@ -481,7 +481,7 @@ extension Int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
println(7.customProperty) // "This is 7"
|
println(7.customProperty) // "This is 7"
|
||||||
println(14.multiplyBy(2)) // 42
|
println(14.multiplyBy(3)) // 42
|
||||||
|
|
||||||
// Generics: Similar to Java and C#. Use the `where` keyword to specify the
|
// Generics: Similar to Java and C#. Use the `where` keyword to specify the
|
||||||
// requirements of the generics.
|
// requirements of the generics.
|
||||||
|
824
tr-tr/csharp-tr.html.markdown
Normal file
824
tr-tr/csharp-tr.html.markdown
Normal file
@ -0,0 +1,824 @@
|
|||||||
|
---
|
||||||
|
language: c#
|
||||||
|
contributors:
|
||||||
|
- ["Irfan Charania", "https://github.com/irfancharania"]
|
||||||
|
- ["Max Yankov", "https://github.com/golergka"]
|
||||||
|
- ["Melvyn Laïly", "http://x2a.yt"]
|
||||||
|
- ["Shaun McCarthy", "http://www.shaunmccarthy.com"]
|
||||||
|
translators:
|
||||||
|
- ["Melih Mucuk", "http://melihmucuk.com"]
|
||||||
|
lang: tr-tr
|
||||||
|
filename: LearnCSharp.cs
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
C# zarif ve tip güvenli nesne yönelimli bir dil olup geliştiricilerin .NET framework üzerinde çalışan güçlü ve güvenli uygulamalar geliştirmesini sağlar.
|
||||||
|
|
||||||
|
[Yazım yanlışları ve öneriler için bana ulaşabilirsiniz](mailto:melihmucuk@gmail.com)
|
||||||
|
|
||||||
|
[Daha fazlasını okuyun.](http://msdn.microsoft.com/en-us/library/vstudio/z1zx9t92.aspx)
|
||||||
|
|
||||||
|
```c#
|
||||||
|
// Tek satırlık yorumlar // ile başlar
|
||||||
|
/*
|
||||||
|
Birden fazla satırlı yorumlar buna benzer
|
||||||
|
*/
|
||||||
|
/// <summary>
|
||||||
|
/// Bu bir XML dokümantasyon yorumu
|
||||||
|
/// </summary>
|
||||||
|
|
||||||
|
// Uygulamanın kullanacağı ad alanlarını belirtin
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Data.Entity;
|
||||||
|
using System.Dynamic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Linq.Expressions;
|
||||||
|
using System.Net;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
// Kodu düzenlemek için paketler içinde alan tanımlayın
|
||||||
|
namespace Learning
|
||||||
|
{
|
||||||
|
// Her .cs dosyası, dosya ile aynı isimde en az bir sınıf içermeli
|
||||||
|
// bu kurala uymak zorunda değilsiniz ancak mantıklı olan yol budur.
|
||||||
|
public class LearnCSharp
|
||||||
|
{
|
||||||
|
// TEMEL SÖZ DİZİMİ - daha önce Java ya da C++ kullandıysanız İLGİNÇ ÖZELLİKLER'e geçin
|
||||||
|
public static void Syntax()
|
||||||
|
{
|
||||||
|
// Satırları yazdırmak için Console.WriteLine kullanın
|
||||||
|
Console.WriteLine("Merhaba Dünya");
|
||||||
|
Console.WriteLine(
|
||||||
|
"Integer: " + 10 +
|
||||||
|
" Double: " + 3.14 +
|
||||||
|
" Boolean: " + true);
|
||||||
|
|
||||||
|
// Yeni satıra geçmeden yazdırmak için Console.Write kullanın
|
||||||
|
Console.Write("Merhaba ");
|
||||||
|
Console.Write("Dünya");
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////
|
||||||
|
// Tipler & Değişkenler
|
||||||
|
//
|
||||||
|
// Bir değişken tanımlamak için <tip> <isim> kullanın
|
||||||
|
///////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Sbyte - Signed 8-bit integer
|
||||||
|
// (-128 <= sbyte <= 127)
|
||||||
|
sbyte fooSbyte = 100;
|
||||||
|
|
||||||
|
// Byte - Unsigned 8-bit integer
|
||||||
|
// (0 <= byte <= 255)
|
||||||
|
byte fooByte = 100;
|
||||||
|
|
||||||
|
// Short - 16-bit integer
|
||||||
|
// Signed - (-32,768 <= short <= 32,767)
|
||||||
|
// Unsigned - (0 <= ushort <= 65,535)
|
||||||
|
short fooShort = 10000;
|
||||||
|
ushort fooUshort = 10000;
|
||||||
|
|
||||||
|
// Integer - 32-bit integer
|
||||||
|
int fooInt = 1; // (-2,147,483,648 <= int <= 2,147,483,647)
|
||||||
|
uint fooUint = 1; // (0 <= uint <= 4,294,967,295)
|
||||||
|
|
||||||
|
// Long - 64-bit integer
|
||||||
|
long fooLong = 100000L; // (-9,223,372,036,854,775,808 <= long <= 9,223,372,036,854,775,807)
|
||||||
|
ulong fooUlong = 100000L; // (0 <= ulong <= 18,446,744,073,709,551,615)
|
||||||
|
// Sayılar boyutlarına göre ön tanımlı olarak int ya da uint olabilir.
|
||||||
|
// L, değişken değerinin long ya da ulong tipinde olduğunu belirtmek için kullanılır.
|
||||||
|
|
||||||
|
// Double - Çift hassasiyetli 64-bit IEEE 754 kayan sayı
|
||||||
|
double fooDouble = 123.4; // Hassasiyet: 15-16 basamak
|
||||||
|
|
||||||
|
// Float - Tek hassasiyetli 32-bit IEEE 754 kayan sayı
|
||||||
|
float fooFloat = 234.5f; // Hassasiyet: 7 basamak
|
||||||
|
// f, değişken değerinin float tipinde olduğunu belirtmek için kullanılır.
|
||||||
|
|
||||||
|
// Decimal - 128-bit veri tiğinde ve diğer kayan sayı veri tiplerinden daha hassastır,
|
||||||
|
// finansal ve mali hesaplamalar için uygundur.
|
||||||
|
decimal fooDecimal = 150.3m;
|
||||||
|
|
||||||
|
// Boolean - true & false
|
||||||
|
bool fooBoolean = true; // veya false
|
||||||
|
|
||||||
|
// Char - 16-bitlik tek bir unicode karakter
|
||||||
|
char fooChar = 'A';
|
||||||
|
|
||||||
|
// Strings -- Önceki baz tiplerinin hepsi değer tipiyken,
|
||||||
|
// string bir referans tipidir. Null değer atayabilirsiniz
|
||||||
|
string fooString = "\"escape\" quotes and add \n (new lines) and \t (tabs)";
|
||||||
|
Console.WriteLine(fooString);
|
||||||
|
|
||||||
|
// İndeks numarası kullanarak bir string'in bütün karakterlerine erişilebilirsiniz:
|
||||||
|
char charFromString = fooString[1]; // => 'e'
|
||||||
|
// String'ler değiştirilemez: fooString[1] = 'X' işlemini yapamazsınız;
|
||||||
|
|
||||||
|
// String'leri geçerli kültür değeri ve büyük küçük harf duyarlılığı olmadan karşılaştırma
|
||||||
|
string.Compare(fooString, "x", StringComparison.CurrentCultureIgnoreCase);
|
||||||
|
|
||||||
|
// sprintf baz alınarak formatlama
|
||||||
|
string fooFs = string.Format("Check Check, {0} {1}, {0} {1:0.0}", 1, 2);
|
||||||
|
|
||||||
|
// Tarihler & Formatlama
|
||||||
|
DateTime fooDate = DateTime.Now;
|
||||||
|
Console.WriteLine(fooDate.ToString("hh:mm, dd MMM yyyy"));
|
||||||
|
|
||||||
|
// Bir string'i iki satıra bölmek için @ sembolü kullanabilirsiniz. " işaretinden kaçmak için "" kullanın
|
||||||
|
string bazString = @"Here's some stuff
|
||||||
|
on a new line! ""Wow!"", the masses cried";
|
||||||
|
|
||||||
|
// Bir değişkeni değiştirilemez yapmak için const ya da read-only kullanın.
|
||||||
|
// const değerleri derleme sırasında hesaplanır
|
||||||
|
const int HOURS_I_WORK_PER_WEEK = 9001;
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////
|
||||||
|
// Veri Yapıları
|
||||||
|
///////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Diziler - Sıfır indeksli
|
||||||
|
// Dizi boyutuna tanımlama sırasında karar verilmelidir.
|
||||||
|
// Dizi tanımlama formatı şöyledir:
|
||||||
|
// <veri tipi>[] <değişken ismi> = new <veri tipi>[<dizi boyutu>];
|
||||||
|
int[] intArray = new int[10];
|
||||||
|
|
||||||
|
// Bir diğer dizi tanımlama formatı şöyledir:
|
||||||
|
int[] y = { 9000, 1000, 1337 };
|
||||||
|
|
||||||
|
// Bir diziyi indeksleme - Bir elemente erişme
|
||||||
|
Console.WriteLine("intArray @ 0: " + intArray[0]);
|
||||||
|
// Diziler değiştirilebilir.
|
||||||
|
intArray[1] = 1;
|
||||||
|
|
||||||
|
// Listeler
|
||||||
|
// Listeler daha esnek oldukları için dizilerden daha sık kullanılırlar.
|
||||||
|
// Bir liste tanımlama formatı şöyledir:
|
||||||
|
// List<veri tipi> <değişken ismi> = new List<veri tipi>();
|
||||||
|
List<int> intList = new List<int>();
|
||||||
|
List<string> stringList = new List<string>();
|
||||||
|
List<int> z = new List<int> { 9000, 1000, 1337 }; // tanımlama
|
||||||
|
// <> işareti generic ifadeler içindir - Güzel özellikler sekmesini inceleyin
|
||||||
|
|
||||||
|
// Listelerin varsayılan bir değeri yoktur;
|
||||||
|
// İndekse erişmeden önce değer eklenmiş olmalıdır
|
||||||
|
intList.Add(1);
|
||||||
|
Console.WriteLine("intList @ 0: " + intList[0]);
|
||||||
|
|
||||||
|
// Diğer veri yapıları için şunlara bakın:
|
||||||
|
// Stack/Queue (Yığın/Kuyruk)
|
||||||
|
// Dictionary (hash map'in uygulanması) (Sözlük)
|
||||||
|
// HashSet (karma seti)
|
||||||
|
// Read-only Collections (Değiştirilemez koleksiyonlar)
|
||||||
|
// Tuple (.Net 4+) (tüp)
|
||||||
|
|
||||||
|
///////////////////////////////////////
|
||||||
|
// Operatörler
|
||||||
|
///////////////////////////////////////
|
||||||
|
Console.WriteLine("\n->Operators");
|
||||||
|
|
||||||
|
int i1 = 1, i2 = 2; // Birden çok tanımlamanın kısa yolu
|
||||||
|
|
||||||
|
// Aritmetik basittir
|
||||||
|
Console.WriteLine(i1 + i2 - i1 * 3 / 7); // => 3
|
||||||
|
|
||||||
|
// Mod
|
||||||
|
Console.WriteLine("11%3 = " + (11 % 3)); // => 2
|
||||||
|
|
||||||
|
// Karşılaştırma operatörleri
|
||||||
|
Console.WriteLine("3 == 2? " + (3 == 2)); // => false
|
||||||
|
Console.WriteLine("3 != 2? " + (3 != 2)); // => true
|
||||||
|
Console.WriteLine("3 > 2? " + (3 > 2)); // => true
|
||||||
|
Console.WriteLine("3 < 2? " + (3 < 2)); // => false
|
||||||
|
Console.WriteLine("2 <= 2? " + (2 <= 2)); // => true
|
||||||
|
Console.WriteLine("2 >= 2? " + (2 >= 2)); // => true
|
||||||
|
|
||||||
|
// Bit düzeyi operatörleri!
|
||||||
|
/*
|
||||||
|
~ Tekli bit tamamlayıcısı
|
||||||
|
<< Sola kaydırma Signed left shift
|
||||||
|
>> Sağa kaydırma Signed right shift
|
||||||
|
& Bit düzeyi AND
|
||||||
|
^ Bit düzeyi harici OR
|
||||||
|
| Bit düzeyi kapsayan OR
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Arttırma
|
||||||
|
int i = 0;
|
||||||
|
Console.WriteLine("\n->Inc/Dec-rementation");
|
||||||
|
Console.WriteLine(i++); //i = 1. Post-Incrementation
|
||||||
|
Console.WriteLine(++i); //i = 2. Pre-Incrementation
|
||||||
|
Console.WriteLine(i--); //i = 1. Post-Decrementation
|
||||||
|
Console.WriteLine(--i); //i = 0. Pre-Decrementation
|
||||||
|
|
||||||
|
///////////////////////////////////////
|
||||||
|
// Kontrol Yapıları
|
||||||
|
///////////////////////////////////////
|
||||||
|
Console.WriteLine("\n->Control Structures");
|
||||||
|
|
||||||
|
// If ifadesi c benzeridir
|
||||||
|
int j = 10;
|
||||||
|
if (j == 10)
|
||||||
|
{
|
||||||
|
Console.WriteLine("I get printed");
|
||||||
|
}
|
||||||
|
else if (j > 10)
|
||||||
|
{
|
||||||
|
Console.WriteLine("I don't");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Console.WriteLine("I also don't");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Üçlü operatörler
|
||||||
|
// Basit bir if/else ifadesi şöyle yazılabilir
|
||||||
|
// <koşul> ? <true> : <false>
|
||||||
|
string isTrue = (true) ? "True" : "False";
|
||||||
|
|
||||||
|
// While döngüsü
|
||||||
|
int fooWhile = 0;
|
||||||
|
while (fooWhile < 100)
|
||||||
|
{
|
||||||
|
//100 kere tekrarlanır, fooWhile 0->99
|
||||||
|
fooWhile++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do While Döngüsü
|
||||||
|
int fooDoWhile = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
//100 kere tekrarlanır, fooDoWhile 0->99
|
||||||
|
fooDoWhile++;
|
||||||
|
} while (fooDoWhile < 100);
|
||||||
|
|
||||||
|
//for döngüsü yapısı => for(<başlangıç ifadesi>; <koşul>; <adım>)
|
||||||
|
for (int fooFor = 0; fooFor < 10; fooFor++)
|
||||||
|
{
|
||||||
|
//10 kere tekrarlanır, fooFor 0->9
|
||||||
|
}
|
||||||
|
|
||||||
|
// For Each Döngüsü
|
||||||
|
// foreach döngüsü yapısı => foreach(<yineleyici tipi> <yineleyici ismi> in <enumerable>)
|
||||||
|
// foreach döngüsü, IEnumerable ya da IEnumerable<T> e dönüştürülmüş herhangi bir obje üzerinde döngü yapabilir
|
||||||
|
// .Net framework üzerindeki bütün koleksiyon tiplerinden (Dizi, Liste, Sözlük...)
|
||||||
|
// biri ya da hepsi uygulanarak gerçekleştirilebilir.
|
||||||
|
// (ToCharArray() silindi, çünkü string'ler aynı zamanda IEnumerable'dır.)
|
||||||
|
foreach (char character in "Hello World".ToCharArray())
|
||||||
|
{
|
||||||
|
//String içindeki bütün karakterler üzerinde döner
|
||||||
|
}
|
||||||
|
|
||||||
|
// Switch Case
|
||||||
|
// Bir switch byte, short, char ve int veri tipleri ile çalışır.
|
||||||
|
// Aynı zamanda sıralı tipler ile de çalışabilir.(Enum Tipleri bölümünde tartışıldı),
|
||||||
|
// String sınıfı, ve bir kaç özel sınıf kaydırılır
|
||||||
|
// basit tipler: Character, Byte, Short, and Integer.
|
||||||
|
int month = 3;
|
||||||
|
string monthString;
|
||||||
|
switch (month)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
monthString = "January";
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
monthString = "February";
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
monthString = "March";
|
||||||
|
break;
|
||||||
|
// Bir aksiyon için birden fazla durum atayabilirsiniz
|
||||||
|
// Ancak, break olmadan yeni bir durum ekleyemezsiniz
|
||||||
|
// (Eğer bunu yapmak istiyorsanız, goto komutu eklemek zorundasınız)
|
||||||
|
case 6:
|
||||||
|
case 7:
|
||||||
|
case 8:
|
||||||
|
monthString = "Summer time!!";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
monthString = "Some other month";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////
|
||||||
|
// Veri Tipleri Dönüştürme ve Typecasting
|
||||||
|
///////////////////////////////////////
|
||||||
|
|
||||||
|
// Veri Dönüştürme
|
||||||
|
|
||||||
|
// String'i Integer'a Dönüştürme
|
||||||
|
// bu başarısız olursa hata fırlatacaktır
|
||||||
|
int.Parse("123");// "123" 'in Integer değerini döndürür
|
||||||
|
|
||||||
|
// try parse hata durumunda değişkene varsayılan bir değer atamak için kullanılır
|
||||||
|
// bu durumda: 0
|
||||||
|
int tryInt;
|
||||||
|
if (int.TryParse("123", out tryInt)) // Fonksiyon boolean'dır
|
||||||
|
Console.WriteLine(tryInt); // 123
|
||||||
|
|
||||||
|
// Integer'ı String'e Dönüştürme
|
||||||
|
// Convert sınıfı dönüştürme işlemini kolaylaştırmak için bir dizi metoda sahiptir
|
||||||
|
Convert.ToString(123);
|
||||||
|
// veya
|
||||||
|
tryInt.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////
|
||||||
|
// SINIFLAR - dosyanın sonunda tanımları görebilirsiniz
|
||||||
|
///////////////////////////////////////
|
||||||
|
public static void Classes()
|
||||||
|
{
|
||||||
|
// Obje tanımlamalarını dosyanın sonunda görebilirsiniz
|
||||||
|
|
||||||
|
// Bir sınıfı türetmek için new kullanın
|
||||||
|
Bicycle trek = new Bicycle();
|
||||||
|
|
||||||
|
// Obje metodlarını çağırma
|
||||||
|
trek.SpeedUp(3); // Her zaman setter ve getter metodları kullanmalısınız
|
||||||
|
trek.Cadence = 100;
|
||||||
|
|
||||||
|
// ToString objenin değerini göstermek için kullanılır.
|
||||||
|
Console.WriteLine("trek info: " + trek.Info());
|
||||||
|
|
||||||
|
// Yeni bir Penny Farthing sınıfı türetmek
|
||||||
|
PennyFarthing funbike = new PennyFarthing(1, 10);
|
||||||
|
Console.WriteLine("funbike info: " + funbike.Info());
|
||||||
|
|
||||||
|
Console.Read();
|
||||||
|
} // Ana metodun sonu
|
||||||
|
|
||||||
|
// KONSOLE BAŞLANGICI Bir konsol uygulaması başlangıç olarak mutlaka ana metod'a sahip olmalı
|
||||||
|
public static void Main(string[] args)
|
||||||
|
{
|
||||||
|
OtherInterestingFeatures();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// İLGİNÇ ÖZELLİKLER
|
||||||
|
//
|
||||||
|
|
||||||
|
// VARSAYILAN METOD TANIMLAMALARI
|
||||||
|
|
||||||
|
public // Görünebilir
|
||||||
|
static // Sınıf üzerinden obje türetmeden çağırılabilir
|
||||||
|
int // Dönüş Tipi,
|
||||||
|
MethodSignatures(
|
||||||
|
int maxCount, // İlk değişken, int değer bekler
|
||||||
|
int count = 0, // Eğer değer gönderilmezse varsayılan olarak 0 değerini alır
|
||||||
|
int another = 3,
|
||||||
|
params string[] otherParams // Metoda gönderilen diğer bütün parametreleri alır
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Metodlar tanımlamalar benzersiz ise aynı isimleri alabilirler
|
||||||
|
public static void MethodSignatures(string maxCount)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// GENERIC'LER
|
||||||
|
// TKey ve TValue değerleri kullanıcı tarafından bu fonksiyon çağırılırken belirtilir.
|
||||||
|
// Bu metod Python'daki SetDefault'a benzer
|
||||||
|
public static TValue SetDefault<TKey, TValue>(
|
||||||
|
IDictionary<TKey, TValue> dictionary,
|
||||||
|
TKey key,
|
||||||
|
TValue defaultItem)
|
||||||
|
{
|
||||||
|
TValue result;
|
||||||
|
if (!dictionary.TryGetValue(key, out result))
|
||||||
|
return dictionary[key] = defaultItem;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gönderilen objeleri daraltabilirsiniz
|
||||||
|
public static void IterateAndPrint<T>(T toPrint) where T: IEnumerable<int>
|
||||||
|
{
|
||||||
|
// Eğer T IEnumerable ise tekrarlayabiliriz
|
||||||
|
foreach (var item in toPrint)
|
||||||
|
// Item bir int
|
||||||
|
Console.WriteLine(item.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void OtherInterestingFeatures()
|
||||||
|
{
|
||||||
|
// İSTEĞE BAĞLI PARAMETRELER
|
||||||
|
MethodSignatures(3, 1, 3, "Some", "Extra", "Strings");
|
||||||
|
MethodSignatures(3, another: 3); // isteğe bağlı olanlar gönderilmedi
|
||||||
|
|
||||||
|
// UZANTI METODLARI
|
||||||
|
int i = 3;
|
||||||
|
i.Print(); // Aşağıda tanımlandı
|
||||||
|
|
||||||
|
// NULLABLE TYPES - veri tabanı işlemleri için uygun / return values
|
||||||
|
// Herhangi bir değer tipi sonuna ? eklenerek nullable yapılabilir (sınıflar hariç)
|
||||||
|
// <tip>? <değiken ismi> = <değer>
|
||||||
|
int? nullable = null; // Nullable<int> için kısa yol
|
||||||
|
Console.WriteLine("Nullable variable: " + nullable);
|
||||||
|
bool hasValue = nullable.HasValue; // eğer null değilse true döner
|
||||||
|
|
||||||
|
// ?? varsayılan değer belirlemek için söz dizimsel güzel bir özellik
|
||||||
|
// bu durumda değişken null'dır
|
||||||
|
int notNullable = nullable ?? 0; // 0
|
||||||
|
|
||||||
|
// TİPİ BELİRTİLMEMİŞ DEĞİŞKENLER - compiler değişkenin tipini bilmeden çalışabilir:
|
||||||
|
var magic = "magic is a string, at compile time, so you still get type safety";
|
||||||
|
// magic = 9; string gibi çalışmayacaktır, bu bir int değil
|
||||||
|
|
||||||
|
// GENERIC'LER
|
||||||
|
//
|
||||||
|
var phonebook = new Dictionary<string, string>() {
|
||||||
|
{"Sarah", "212 555 5555"} // Telefon rehberine bir kaç numara ekleyelim.
|
||||||
|
};
|
||||||
|
|
||||||
|
// Yukarıda generic olarak tanımlanan SETDEFAULT'u çağırma
|
||||||
|
Console.WriteLine(SetDefault<string,string>(phonebook, "Shaun", "No Phone")); // Telefonu yok
|
||||||
|
// TKey ve TValue tipini belirtmek zorunda değilsiniz
|
||||||
|
Console.WriteLine(SetDefault(phonebook, "Sarah", "No Phone")); // 212 555 5555
|
||||||
|
|
||||||
|
// LAMBDA IFADELERİ - satır içinde kod yazmanıza olanak sağlar
|
||||||
|
Func<int, int> square = (x) => x * x; // Son T nesnesi dönüş değeridir
|
||||||
|
Console.WriteLine(square(3)); // 9
|
||||||
|
|
||||||
|
// TEK KULLANIMLIK KAYNAK YÖNETİMİ - Yönetilemeyen kaynakların üstesinden kolayca gelebilirsiniz.
|
||||||
|
// Bir çok obje yönetilemeyen kaynaklara (dosya yakalama, cihaz içeriği, vb.)
|
||||||
|
// IDisposable arabirimi ile erişebilir. Using ifadesi sizin için IDisposable objeleri temizler.
|
||||||
|
using (StreamWriter writer = new StreamWriter("log.txt"))
|
||||||
|
{
|
||||||
|
writer.WriteLine("Nothing suspicious here");
|
||||||
|
// Bu bölümün sonunda kaynaklar temilenir.
|
||||||
|
// Hata fırlatılmış olsa bile.
|
||||||
|
}
|
||||||
|
|
||||||
|
// PARALEL FRAMEWORK
|
||||||
|
// http://blogs.msdn.com/b/csharpfaq/archive/2010/06/01/parallel-programming-in-net-framework-4-getting-started.aspx
|
||||||
|
var websites = new string[] {
|
||||||
|
"http://www.google.com", "http://www.reddit.com",
|
||||||
|
"http://www.shaunmccarthy.com"
|
||||||
|
};
|
||||||
|
var responses = new Dictionary<string, string>();
|
||||||
|
|
||||||
|
// Her istek farklı bir thread de işlem görecek
|
||||||
|
// bir sonraki işleme geçmeden birleştirilecek.
|
||||||
|
Parallel.ForEach(websites,
|
||||||
|
new ParallelOptions() {MaxDegreeOfParallelism = 3}, // en fazla 3 thread kullanmak için
|
||||||
|
website =>
|
||||||
|
{
|
||||||
|
// Uzun sürecek bir işlem yapın
|
||||||
|
using (var r = WebRequest.Create(new Uri(website)).GetResponse())
|
||||||
|
{
|
||||||
|
responses[website] = r.ContentType;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Bütün istekler tamamlanmadan bu döndü çalışmayacaktır.
|
||||||
|
foreach (var key in responses.Keys)
|
||||||
|
Console.WriteLine("{0}:{1}", key, responses[key]);
|
||||||
|
|
||||||
|
// DİNAMİK OBJELER (diğer dillerle çalışırken kullanmak için uygun)
|
||||||
|
dynamic student = new ExpandoObject();
|
||||||
|
student.FirstName = "First Name"; // Önce yeni bir sınıf tanımlamanız gerekmez!
|
||||||
|
|
||||||
|
// Hatta metod bile ekleyebilirsiniz (bir string döner, ve bir string alır)
|
||||||
|
student.Introduce = new Func<string, string>(
|
||||||
|
(introduceTo) => string.Format("Hey {0}, this is {1}", student.FirstName, introduceTo));
|
||||||
|
Console.WriteLine(student.Introduce("Beth"));
|
||||||
|
|
||||||
|
// IQUERYABLE<T> - neredeyse bütün koleksiyonlar bundan türer, bu size bir çok
|
||||||
|
// kullanışlı Map / Filter / Reduce stili metod sağlar.
|
||||||
|
var bikes = new List<Bicycle>();
|
||||||
|
bikes.Sort(); // Dizi sıralama
|
||||||
|
bikes.Sort((b1, b2) => b1.Wheels.CompareTo(b2.Wheels)); // Wheels baz alınarak sıralama
|
||||||
|
var result = bikes
|
||||||
|
.Where(b => b.Wheels > 3) // Filters- chainable (bir önceki tipin IQueryable'ını döner)
|
||||||
|
.Where(b => b.IsBroken && b.HasTassles)
|
||||||
|
.Select(b => b.ToString()); // Map - sadece bunu seçiyoruz, yani sonuç bir IQueryable<string> olacak
|
||||||
|
|
||||||
|
var sum = bikes.Sum(b => b.Wheels); // Reduce - koleksiyonda bulunan bütün wheel değerlerinin toplamı
|
||||||
|
|
||||||
|
// Bike içindeki bazı parametreleri baz alarak bir liste oluşturmak
|
||||||
|
var bikeSummaries = bikes.Select(b=>new { Name = b.Name, IsAwesome = !b.IsBroken && b.HasTassles });
|
||||||
|
// Burada göstermek zor ama, compiler yukaridaki tipleri çözümleyebilirse derlenmeden önce tipi verebilir.
|
||||||
|
foreach (var bikeSummary in bikeSummaries.Where(b => b.IsAwesome))
|
||||||
|
Console.WriteLine(bikeSummary.Name);
|
||||||
|
|
||||||
|
// ASPARALLEL
|
||||||
|
// Linq ve paralel işlemlerini birleştirme
|
||||||
|
var threeWheelers = bikes.AsParallel().Where(b => b.Wheels == 3).Select(b => b.Name);
|
||||||
|
// bu paralel bir şekilde gerçekleşecek! Threadler otomatik ve sihirli bir şekilde işleri paylaşacak!
|
||||||
|
// Birden fazla çekirdeğiniz varsa büyük veri setleri ile kullanmak için oldukça uygun bir yapı.
|
||||||
|
|
||||||
|
// LINQ - IQueryable<T> objelerini mapler ve saklar, gecikmeli bir işlemdir
|
||||||
|
// e.g. LinqToSql - veri tabanını mapler, LinqToXml xml dökümanlarını mapler.
|
||||||
|
var db = new BikeRepository();
|
||||||
|
|
||||||
|
// işlem gecikmelidir, bir veri tabanı üzerinde sorgulama yaparken harikadır.
|
||||||
|
var filter = db.Bikes.Where(b => b.HasTassles); // sorgu henüz çalışmadı
|
||||||
|
if (42 > 6) // Filtreler eklemeye devam edebilirsiniz - ileri düzey arama fonksiyonları için harikadır
|
||||||
|
filter = filter.Where(b => b.IsBroken); // sorgu henüz çalışmadı
|
||||||
|
|
||||||
|
var query = filter
|
||||||
|
.OrderBy(b => b.Wheels)
|
||||||
|
.ThenBy(b => b.Name)
|
||||||
|
.Select(b => b.Name); // hala sorgu çalışmadı
|
||||||
|
|
||||||
|
// Şimdi sorgu çalışıyor, reader'ı açar ama sadece sizin sorgunuza uyanlar foreach döngüsüne girer.
|
||||||
|
foreach (string bike in query)
|
||||||
|
Console.WriteLine(result);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} // LearnCSharp sınıfının sonu
|
||||||
|
|
||||||
|
// Bir .cs dosyasına diğer sınıflarıda dahil edebilirsiniz
|
||||||
|
|
||||||
|
public static class Extensions
|
||||||
|
{
|
||||||
|
// UZANTI FONKSİYONLARI
|
||||||
|
public static void Print(this object obj)
|
||||||
|
{
|
||||||
|
Console.WriteLine(obj.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sınıf Tanımlama Sözdizimi:
|
||||||
|
// <public/private/protected/internal> class <sınıf ismi>{
|
||||||
|
// //veri alanları, kurucular , fonksiyonlar hepsi içindedir.
|
||||||
|
// //Fonksiyonlar Java'daki gibi metod olarak çağırılır.
|
||||||
|
// }
|
||||||
|
|
||||||
|
public class Bicycle
|
||||||
|
{
|
||||||
|
// Bicycle'ın Alanları/Değişkenleri
|
||||||
|
public int Cadence // Public: herhangi bir yerden erişilebilir
|
||||||
|
{
|
||||||
|
get // get - değeri almak için tanımlanan metod
|
||||||
|
{
|
||||||
|
return _cadence;
|
||||||
|
}
|
||||||
|
set // set - değer atamak için tanımlanan metod
|
||||||
|
{
|
||||||
|
_cadence = value; // Değer setter'a gönderilen value değeridir
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private int _cadence;
|
||||||
|
|
||||||
|
protected virtual int Gear // Protected: Sınıf ve alt sınıflar tarafından erişilebilir
|
||||||
|
{
|
||||||
|
get; // bir üye alanına ihtiyacınız yok, bu otomatik olarak bir değer oluşturacaktır
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal int Wheels // Internal: Assembly tarafından erişilebilir
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
private set; // Nitelik belirleyicileri get/set metodlarında atayabilirsiniz
|
||||||
|
}
|
||||||
|
|
||||||
|
int _speed; // Her şey varsayılan olarak private'dır : Sadece sınıf içinden erişilebilir.
|
||||||
|
// İsterseniz yinede private kelimesini kullanabilirsiniz.
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
// Enum sabitler kümesinden oluşan bir değer tipidir.
|
||||||
|
// Gerçekten sadece bir isim ile bir değeri tutmak için kullanılır. (aksi belirtilmedikçe bir int'dir).
|
||||||
|
// İzin verilen enum tipleri şunlardır byte, sbyte, short, ushort, int, uint, long, veya ulong.
|
||||||
|
// Bir enum aynı değeri birden fazla sayıda barındıramaz.
|
||||||
|
public enum BikeBrand
|
||||||
|
{
|
||||||
|
AIST,
|
||||||
|
BMC,
|
||||||
|
Electra = 42, // bir isme tam bir değer verebilirsiniz
|
||||||
|
Gitane // 43
|
||||||
|
}
|
||||||
|
// Bu tipi Bicycle sınıfı içinde tanımladığımız için bu bir bağımlı tipdir.
|
||||||
|
// Bu sınıf dışında kullanmak için tipi Bicycle.Brand olarak kullanmamız gerekir
|
||||||
|
|
||||||
|
public BikeBrand Brand; // Enum tipini tanımladıktan sonra alan tipini tanımlayabiliriz
|
||||||
|
|
||||||
|
// Static üyeler belirli bir obje yerine kendi tipine aittir
|
||||||
|
// Onlara bir obje referans göstermeden erişebilirsiniz:
|
||||||
|
// Console.WriteLine("Bicycles created: " + Bicycle.bicyclesCreated);
|
||||||
|
static public int BicyclesCreated = 0;
|
||||||
|
|
||||||
|
// readonly değerleri çalışma zamanında atanır
|
||||||
|
// onlara sadece tanımlama yapılarak ya da kurucular içinden atama yapılabilir
|
||||||
|
readonly bool _hasCardsInSpokes = false; // read-only private
|
||||||
|
|
||||||
|
// Kurucular sınıf oluşturmanın bir yoludur
|
||||||
|
// Bu bir varsayılan kurucudur.
|
||||||
|
public Bicycle()
|
||||||
|
{
|
||||||
|
this.Gear = 1; // bu objenin üyelerine this anahtar kelimesi ile ulaşılır
|
||||||
|
Cadence = 50; // ama her zaman buna ihtiyaç duyulmaz
|
||||||
|
_speed = 5;
|
||||||
|
Name = "Bontrager";
|
||||||
|
Brand = BikeBrand.AIST;
|
||||||
|
BicyclesCreated++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bu belirlenmiş bir kurucudur. (argümanlar içerir)
|
||||||
|
public Bicycle(int startCadence, int startSpeed, int startGear,
|
||||||
|
string name, bool hasCardsInSpokes, BikeBrand brand)
|
||||||
|
: base() // önce base'i çağırın
|
||||||
|
{
|
||||||
|
Gear = startGear;
|
||||||
|
Cadence = startCadence;
|
||||||
|
_speed = startSpeed;
|
||||||
|
Name = name;
|
||||||
|
_hasCardsInSpokes = hasCardsInSpokes;
|
||||||
|
Brand = brand;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Kurucular zincirleme olabilir
|
||||||
|
public Bicycle(int startCadence, int startSpeed, BikeBrand brand) :
|
||||||
|
this(startCadence, startSpeed, 0, "big wheels", true, brand)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fonksiyon Sözdizimi:
|
||||||
|
// <public/private/protected> <dönüş tipi> <fonksiyon ismi>(<argümanlar>)
|
||||||
|
|
||||||
|
// sınıflar getter ve setter'ları alanları için kendisi uygular
|
||||||
|
// veya property'ler eklenebilir (C# da tercih edilen yol budur)
|
||||||
|
|
||||||
|
// Metod parametreleri varsayılan değerlere sahip olabilir.
|
||||||
|
// Bu durumda, metodlar bu parametreler olmadan çağırılabilir.
|
||||||
|
public void SpeedUp(int increment = 1)
|
||||||
|
{
|
||||||
|
_speed += increment;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SlowDown(int decrement = 1)
|
||||||
|
{
|
||||||
|
_speed -= decrement;
|
||||||
|
}
|
||||||
|
|
||||||
|
// property'lerin get/set değerleri
|
||||||
|
// sadece veri gerektiği zaman erişilebilir, kullanmak için bunu göz önünde bulundurun.
|
||||||
|
// property'ler sadece get ya da set'e sahip olabilir veya ikisine birden
|
||||||
|
private bool _hasTassles; // private değişken
|
||||||
|
public bool HasTassles // public accessor
|
||||||
|
{
|
||||||
|
get { return _hasTassles; }
|
||||||
|
set { _hasTassles = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ayrıca tek bir satırda otomatik property tanımlayabilirsiniz.
|
||||||
|
// bu söz dizimi otomatik olarak alan oluşturacaktır.
|
||||||
|
// Erişimi kısıtlamak için nitelik belirleyiciler getter veya setter'a ya da ikisine birden atanabilir:
|
||||||
|
public bool IsBroken { get; private set; }
|
||||||
|
|
||||||
|
// Property'ler otomatik eklenmiş olabilir
|
||||||
|
public int FrameSize
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
// nitelik beliryecileri get veya set için tanımlayabilirsiniz
|
||||||
|
// bu sadece Bicycle sınıfı Framesize değerine atama yapabilir demektir
|
||||||
|
private set;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ayrıca obje üzerinde özel indeksleyici belirlemek mümkündür.
|
||||||
|
// Tüm bunlar bu örnek için çok kullanışlı değil,
|
||||||
|
// bicycle[0] ile ilk yolcu olan "chris" i almak mümkün veya
|
||||||
|
// bicycle[1] = "lisa" ile yolcuyu atayabilirsiniz. (bariz quattrocycle)
|
||||||
|
private string[] passengers = { "chris", "phil", "darren", "regina" }
|
||||||
|
|
||||||
|
public string this[int i]
|
||||||
|
{
|
||||||
|
get {
|
||||||
|
return passengers[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
set {
|
||||||
|
return passengers[i] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Bu objenin nitelik değerlerini göstermek için bir metod.
|
||||||
|
public virtual string Info()
|
||||||
|
{
|
||||||
|
return "Gear: " + Gear +
|
||||||
|
" Cadence: " + Cadence +
|
||||||
|
" Speed: " + _speed +
|
||||||
|
" Name: " + Name +
|
||||||
|
" Cards in Spokes: " + (_hasCardsInSpokes ? "yes" : "no") +
|
||||||
|
"\n------------------------------\n"
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Metodlar static olabilir. Yardımcı metodlar için kullanışlı olabilir.
|
||||||
|
public static bool DidWeCreateEnoughBycles()
|
||||||
|
{
|
||||||
|
// Bir static metod içinde sadece static sınıf üyeleri referans gösterilebilir
|
||||||
|
return BicyclesCreated > 9000;
|
||||||
|
} // Eğer sınıfınızın sadece static üyelere ihtiyacı varsa, sınıfın kendisini static yapmayı düşünebilirsiniz.
|
||||||
|
|
||||||
|
|
||||||
|
} // Bicycle sınıfı sonu
|
||||||
|
|
||||||
|
// PennyFarthing , Bicycle sınıfının alt sınıfıdır.
|
||||||
|
class PennyFarthing : Bicycle
|
||||||
|
{
|
||||||
|
// (Penny Farthing'ler ön jantı büyük bisikletlerdir.
|
||||||
|
// Vitesleri yoktur.)
|
||||||
|
|
||||||
|
// Ana kurucuyu çağırmak
|
||||||
|
public PennyFarthing(int startCadence, int startSpeed) :
|
||||||
|
base(startCadence, startSpeed, 0, "PennyFarthing", true, BikeBrand.Electra)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override int Gear
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
throw new ArgumentException("You can't change gears on a PennyFarthing");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string Info()
|
||||||
|
{
|
||||||
|
string result = "PennyFarthing bicycle ";
|
||||||
|
result += base.ToString(); // Metodun temel versiyonunu çağırmak
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Arabirimler sadece üyelerin izlerini içerir, değerlerini değil.
|
||||||
|
interface IJumpable
|
||||||
|
{
|
||||||
|
void Jump(int meters); // bütün arbirim üyeleri public'tir
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IBreakable
|
||||||
|
{
|
||||||
|
bool Broken { get; } // arabirimler property'leri, metodları ve olayları içerebilir
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sınıflar sadece tek bir sınıftan miras alabilir ama sınırsız sayıda arabirime sahip olabilir
|
||||||
|
class MountainBike : Bicycle, IJumpable, IBreakable
|
||||||
|
{
|
||||||
|
int damage = 0;
|
||||||
|
|
||||||
|
public void Jump(int meters)
|
||||||
|
{
|
||||||
|
damage += meters;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Broken
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return damage > 100;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// LinqToSql örneği veri tabanına bağlanmak için kullanılır.
|
||||||
|
/// EntityFramework Code First harika! (Ruby'deki ActiveRecord'a benzer, ama iki yönlü)
|
||||||
|
/// http://msdn.microsoft.com/en-us/data/jj193542.aspx
|
||||||
|
/// </summary>
|
||||||
|
public class BikeRepository : DbSet
|
||||||
|
{
|
||||||
|
public BikeRepository()
|
||||||
|
: base()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public DbSet<Bicycle> Bikes { get; set; }
|
||||||
|
}
|
||||||
|
} // namespace sonu
|
||||||
|
```
|
||||||
|
|
||||||
|
## İşlenmeyen Konular
|
||||||
|
|
||||||
|
* Flags
|
||||||
|
* Attributes
|
||||||
|
* Static properties
|
||||||
|
* Exceptions, Abstraction
|
||||||
|
* ASP.NET (Web Forms/MVC/WebMatrix)
|
||||||
|
* Winforms
|
||||||
|
* Windows Presentation Foundation (WPF)
|
||||||
|
|
||||||
|
## Daha Fazlasını Okuyun
|
||||||
|
|
||||||
|
* [DotNetPerls](http://www.dotnetperls.com)
|
||||||
|
* [C# in Depth](http://manning.com/skeet2)
|
||||||
|
* [Programming C#](http://shop.oreilly.com/product/0636920024064.do)
|
||||||
|
* [LINQ](http://shop.oreilly.com/product/9780596519254.do)
|
||||||
|
* [MSDN Library](http://msdn.microsoft.com/en-us/library/618ayhy6.aspx)
|
||||||
|
* [ASP.NET MVC Tutorials](http://www.asp.net/mvc/tutorials)
|
||||||
|
* [ASP.NET Web Matrix Tutorials](http://www.asp.net/web-pages/tutorials)
|
||||||
|
* [ASP.NET Web Forms Tutorials](http://www.asp.net/web-forms/tutorials)
|
||||||
|
* [Windows Forms Programming in C#](http://www.amazon.com/Windows-Forms-Programming-Chris-Sells/dp/0321116208)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[C# Kodlama Adetleri](http://msdn.microsoft.com/en-us/library/vstudio/ff926074.aspx)
|
491
zh-cn/matlab-cn.html.markdown
Normal file
491
zh-cn/matlab-cn.html.markdown
Normal file
@ -0,0 +1,491 @@
|
|||||||
|
---
|
||||||
|
language: Matlab
|
||||||
|
contributors:
|
||||||
|
- ["mendozao", "http://github.com/mendozao"]
|
||||||
|
- ["jamesscottbrown", "http://jamesscottbrown.com"]
|
||||||
|
translators:
|
||||||
|
- ["sunxb10", "https://github.com/sunxb10"]
|
||||||
|
lang: zh-cn
|
||||||
|
---
|
||||||
|
|
||||||
|
MATLAB 是 MATrix LABoratory (矩阵实验室)的缩写,它是一种功能强大的数值计算语言,在工程和数学领域中应用广泛。
|
||||||
|
|
||||||
|
如果您有任何需要反馈或交流的内容,请联系本教程作者[@the_ozzinator](https://twitter.com/the_ozzinator)、[osvaldo.t.mendoza@gmail.com](mailto:osvaldo.t.mendoza@gmail.com)。
|
||||||
|
|
||||||
|
```matlab
|
||||||
|
% 以百分号作为注释符
|
||||||
|
|
||||||
|
%{
|
||||||
|
多行注释
|
||||||
|
可以
|
||||||
|
这样
|
||||||
|
表示
|
||||||
|
%}
|
||||||
|
|
||||||
|
% 指令可以随意跨行,但需要在跨行处用 '...' 标明:
|
||||||
|
a = 1 + 2 + ...
|
||||||
|
+ 4
|
||||||
|
|
||||||
|
% 可以在MATLAB中直接向操作系统发出指令
|
||||||
|
!ping google.com
|
||||||
|
|
||||||
|
who % 显示内存中的所有变量
|
||||||
|
whos % 显示内存中的所有变量以及它们的类型
|
||||||
|
clear % 清除内存中的所有变量
|
||||||
|
clear('A') % 清除指定的变量
|
||||||
|
openvar('A') % 在变量编辑器中编辑指定变量
|
||||||
|
|
||||||
|
clc % 清除命令窗口中显示的所有指令
|
||||||
|
diary % 将命令窗口中的内容写入本地文件
|
||||||
|
ctrl-c % 终止当前计算
|
||||||
|
|
||||||
|
edit('myfunction.m') % 在编辑器中打开指定函数或脚本
|
||||||
|
type('myfunction.m') % 在命令窗口中打印指定函数或脚本的源码
|
||||||
|
|
||||||
|
profile on % 打开 profile 代码分析工具
|
||||||
|
profile of % 关闭 profile 代码分析工具
|
||||||
|
profile viewer % 查看 profile 代码分析工具的分析结果
|
||||||
|
|
||||||
|
help command % 在命令窗口中显示指定命令的帮助文档
|
||||||
|
doc command % 在帮助窗口中显示指定命令的帮助文档
|
||||||
|
lookfor command % 在所有 MATLAB 内置函数的头部注释块的第一行中搜索指定命令
|
||||||
|
lookfor command -all % 在所有 MATLAB 内置函数的整个头部注释块中搜索指定命令
|
||||||
|
|
||||||
|
|
||||||
|
% 输出格式
|
||||||
|
format short % 浮点数保留 4 位小数
|
||||||
|
format long % 浮点数保留 15 位小数
|
||||||
|
format bank % 金融格式,浮点数只保留 2 位小数
|
||||||
|
fprintf('text') % 在命令窗口中显示 "text"
|
||||||
|
disp('text') % 在命令窗口中显示 "text"
|
||||||
|
|
||||||
|
|
||||||
|
% 变量与表达式
|
||||||
|
myVariable = 4 % 命令窗口中将新创建的变量
|
||||||
|
myVariable = 4; % 加上分号可使命令窗口中不显示当前语句执行结果
|
||||||
|
4 + 6 % ans = 10
|
||||||
|
8 * myVariable % ans = 32
|
||||||
|
2 ^ 3 % ans = 8
|
||||||
|
a = 2; b = 3;
|
||||||
|
c = exp(a)*sin(pi/2) % c = 7.3891
|
||||||
|
|
||||||
|
|
||||||
|
% 调用函数有两种方式:
|
||||||
|
% 标准函数语法:
|
||||||
|
load('myFile.mat', 'y') % 参数放在括号内,以英文逗号分隔
|
||||||
|
% 指令语法:
|
||||||
|
load myFile.mat y % 不加括号,以空格分隔参数
|
||||||
|
% 注意在指令语法中参数不需要加引号:在这种语法下,所有输入参数都只能是文本文字,
|
||||||
|
% 不能是变量的具体值,同样也不能是输出变量
|
||||||
|
[V,D] = eig(A); % 这条函数调用无法转换成等价的指令语法
|
||||||
|
[~,D] = eig(A); % 如果结果中只需要 D 而不需要 V 则可以这样写
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
% 逻辑运算
|
||||||
|
1 > 5 % 假,ans = 0
|
||||||
|
10 >= 10 % 真,ans = 1
|
||||||
|
3 ~= 4 % 不等于 -> ans = 1
|
||||||
|
3 == 3 % 等于 -> ans = 1
|
||||||
|
3 > 1 && 4 > 1 % 与 -> ans = 1
|
||||||
|
3 > 1 || 4 > 1 % 或 -> ans = 1
|
||||||
|
~1 % 非 -> ans = 0
|
||||||
|
|
||||||
|
% 逻辑运算可直接应用于矩阵,运算结果也是矩阵
|
||||||
|
A > 5
|
||||||
|
% 对矩阵中每个元素做逻辑运算,若为真,则在运算结果的矩阵中对应位置的元素就是 1
|
||||||
|
A( A > 5 )
|
||||||
|
% 如此返回的向量,其元素就是 A 矩阵中所有逻辑运算为真的元素
|
||||||
|
|
||||||
|
% 字符串
|
||||||
|
a = 'MyString'
|
||||||
|
length(a) % ans = 8
|
||||||
|
a(2) % ans = y
|
||||||
|
[a,a] % ans = MyStringMyString
|
||||||
|
b = '字符串' % MATLAB目前已经可以支持包括中文在内的多种文字
|
||||||
|
length(b) % ans = 3
|
||||||
|
b(2) % ans = 符
|
||||||
|
[b,b] % ans = 字符串字符串
|
||||||
|
|
||||||
|
|
||||||
|
% 元组(cell 数组)
|
||||||
|
a = {'one', 'two', 'three'}
|
||||||
|
a(1) % ans = 'one' - 返回一个元组
|
||||||
|
char(a(1)) % ans = one - 返回一个字符串
|
||||||
|
|
||||||
|
|
||||||
|
% 结构体
|
||||||
|
A.b = {'one','two'};
|
||||||
|
A.c = [1 2];
|
||||||
|
A.d.e = false;
|
||||||
|
|
||||||
|
|
||||||
|
% 向量
|
||||||
|
x = [4 32 53 7 1]
|
||||||
|
x(2) % ans = 32,MATLAB中向量的下标索引从1开始,不是0
|
||||||
|
x(2:3) % ans = 32 53
|
||||||
|
x(2:end) % ans = 32 53 7 1
|
||||||
|
|
||||||
|
x = [4; 32; 53; 7; 1] % 列向量
|
||||||
|
|
||||||
|
x = [1:10] % x = 1 2 3 4 5 6 7 8 9 10
|
||||||
|
|
||||||
|
|
||||||
|
% 矩阵
|
||||||
|
A = [1 2 3; 4 5 6; 7 8 9]
|
||||||
|
% 以分号分隔不同的行,以空格或逗号分隔同一行中的不同元素
|
||||||
|
% A =
|
||||||
|
|
||||||
|
% 1 2 3
|
||||||
|
% 4 5 6
|
||||||
|
% 7 8 9
|
||||||
|
|
||||||
|
A(2,3) % ans = 6,A(row, column)
|
||||||
|
A(6) % ans = 8
|
||||||
|
% (隐式地将 A 的三列首尾相接组成一个列向量,然后取其下标为 6 的元素)
|
||||||
|
|
||||||
|
|
||||||
|
A(2,3) = 42 % 将第 2 行第 3 列的元素设为 42
|
||||||
|
% A =
|
||||||
|
|
||||||
|
% 1 2 3
|
||||||
|
% 4 5 42
|
||||||
|
% 7 8 9
|
||||||
|
|
||||||
|
A(2:3,2:3) % 取原矩阵中的一块作为新矩阵
|
||||||
|
%ans =
|
||||||
|
|
||||||
|
% 5 42
|
||||||
|
% 8 9
|
||||||
|
|
||||||
|
A(:,1) % 第 1 列的所有元素
|
||||||
|
%ans =
|
||||||
|
|
||||||
|
% 1
|
||||||
|
% 4
|
||||||
|
% 7
|
||||||
|
|
||||||
|
A(1,:) % 第 1 行的所有元素
|
||||||
|
%ans =
|
||||||
|
|
||||||
|
% 1 2 3
|
||||||
|
|
||||||
|
[A ; A] % 将两个矩阵上下相接构成新矩阵
|
||||||
|
%ans =
|
||||||
|
|
||||||
|
% 1 2 3
|
||||||
|
% 4 5 42
|
||||||
|
% 7 8 9
|
||||||
|
% 1 2 3
|
||||||
|
% 4 5 42
|
||||||
|
% 7 8 9
|
||||||
|
|
||||||
|
% 等价于
|
||||||
|
vertcat(A, A);
|
||||||
|
|
||||||
|
|
||||||
|
[A , A] % 将两个矩阵左右相接构成新矩阵
|
||||||
|
|
||||||
|
%ans =
|
||||||
|
|
||||||
|
% 1 2 3 1 2 3
|
||||||
|
% 4 5 42 4 5 42
|
||||||
|
% 7 8 9 7 8 9
|
||||||
|
|
||||||
|
% 等价于
|
||||||
|
horzcat(A, A);
|
||||||
|
|
||||||
|
|
||||||
|
A(:, [3 1 2]) % 重新排布原矩阵的各列
|
||||||
|
%ans =
|
||||||
|
|
||||||
|
% 3 1 2
|
||||||
|
% 42 4 5
|
||||||
|
% 9 7 8
|
||||||
|
|
||||||
|
size(A) % 返回矩阵的行数和列数,ans = 3 3
|
||||||
|
|
||||||
|
A(1, :) =[] % 删除矩阵的第 1 行
|
||||||
|
A(:, 1) =[] % 删除矩阵的第 1 列
|
||||||
|
|
||||||
|
transpose(A) % 矩阵转置,等价于 A'
|
||||||
|
ctranspose(A) % 矩阵的共轭转置(对矩阵中的每个元素取共轭复数)
|
||||||
|
|
||||||
|
|
||||||
|
% 元素运算 vs. 矩阵运算
|
||||||
|
% 单独运算符就是对矩阵整体进行矩阵运算
|
||||||
|
% 在运算符加上英文句点就是对矩阵中的元素进行元素计算
|
||||||
|
% 示例如下:
|
||||||
|
A * B % 矩阵乘法,要求 A 的列数等于 B 的行数
|
||||||
|
A .* B % 元素乘法,要求 A 和 B 形状一致(A 的行数等于 B 的行数, A 的列数等于 B 的列数)
|
||||||
|
% 元素乘法的结果是与 A 和 B 形状一致的矩阵,其每个元素等于 A 对应位置的元素乘 B 对应位置的元素
|
||||||
|
|
||||||
|
% 以下函数中,函数名以 m 结尾的执行矩阵运算,其余执行元素运算:
|
||||||
|
exp(A) % 对矩阵中每个元素做指数运算
|
||||||
|
expm(A) % 对矩阵整体做指数运算
|
||||||
|
sqrt(A) % 对矩阵中每个元素做开方运算
|
||||||
|
sqrtm(A) % 对矩阵整体做开放运算(即试图求出一个矩阵,该矩阵与自身的乘积等于 A 矩阵)
|
||||||
|
|
||||||
|
|
||||||
|
% 绘图
|
||||||
|
x = 0:.10:2*pi; % 生成一向量,其元素从 0 开始,以 0.1 的间隔一直递增到 2*pi(pi 就是圆周率)
|
||||||
|
y = sin(x);
|
||||||
|
plot(x,y)
|
||||||
|
xlabel('x axis')
|
||||||
|
ylabel('y axis')
|
||||||
|
title('Plot of y = sin(x)')
|
||||||
|
axis([0 2*pi -1 1]) % x 轴范围是从 0 到 2*pi,y 轴范围是从 -1 到 1
|
||||||
|
|
||||||
|
plot(x,y1,'-',x,y2,'--',x,y3,':') % 在同一张图中绘制多条曲线
|
||||||
|
legend('Line 1 label', 'Line 2 label') % 为图片加注图例
|
||||||
|
% 图例数量应当小于或等于实际绘制的曲线数目,从 plot 绘制的第一条曲线开始对应
|
||||||
|
|
||||||
|
% 在同一张图上绘制多条曲线的另一种方法:
|
||||||
|
% 使用 hold on,令系统保留前次绘图结果并在其上直接叠加新的曲线,
|
||||||
|
% 如果没有 hold on,则每个 plot 都会首先清除之前的绘图结果再进行绘制。
|
||||||
|
% 在 hold on 和 hold off 中可以放置任意多的 plot 指令,
|
||||||
|
% 它们和 hold on 前最后一个 plot 指令的结果都将显示在同一张图中。
|
||||||
|
plot(x, y1)
|
||||||
|
hold on
|
||||||
|
plot(x, y2)
|
||||||
|
plot(x, y3)
|
||||||
|
plot(x, y4)
|
||||||
|
hold off
|
||||||
|
|
||||||
|
loglog(x, y) % 对数—对数绘图
|
||||||
|
semilogx(x, y) % 半对数(x 轴对数)绘图
|
||||||
|
semilogy(x, y) % 半对数(y 轴对数)绘图
|
||||||
|
|
||||||
|
fplot (@(x) x^2, [2,5]) % 绘制函数 x^2 在 [2, 5] 区间的曲线
|
||||||
|
|
||||||
|
grid on % 在绘制的图中显示网格,使用 grid off 可取消网格显示
|
||||||
|
axis square % 将当前坐标系设定为正方形(保证在图形显示上各轴等长)
|
||||||
|
axis equal % 将当前坐标系设定为相等(保证在实际数值上各轴等长)
|
||||||
|
|
||||||
|
scatter(x, y); % 散点图
|
||||||
|
hist(x); % 直方图
|
||||||
|
|
||||||
|
z = sin(x);
|
||||||
|
plot3(x,y,z); % 绘制三维曲线
|
||||||
|
|
||||||
|
pcolor(A) % 伪彩色图(热图)
|
||||||
|
contour(A) % 等高线图
|
||||||
|
mesh(A) % 网格曲面图
|
||||||
|
|
||||||
|
h = figure % 创建新的图片对象并返回其句柄 h
|
||||||
|
figure(h) % 将句柄 h 对应的图片作为当前图片
|
||||||
|
close(h) % 关闭句柄 h 对应的图片
|
||||||
|
close all % 关闭 MATLAB 中所用打开的图片
|
||||||
|
close % 关闭当前图片
|
||||||
|
|
||||||
|
shg % 显示图形窗口
|
||||||
|
clf clear % 清除图形窗口中的图像,并重置图像属性
|
||||||
|
|
||||||
|
% 图像属性可以通过图像句柄进行设定
|
||||||
|
% 在创建图像时可以保存图像句柄以便于设置
|
||||||
|
% 也可以用 gcf 函数返回当前图像的句柄
|
||||||
|
h = plot(x, y); % 在创建图像时显式地保存图像句柄
|
||||||
|
set(h, 'Color', 'r')
|
||||||
|
% 颜色代码:'y' 黄色,'m' 洋红色,'c' 青色,'r' 红色,'g' 绿色,'b' 蓝色,'w' 白色,'k' 黑色
|
||||||
|
set(h, 'Color', [0.5, 0.5, 0.4])
|
||||||
|
% 也可以使用 RGB 值指定颜色
|
||||||
|
set(h, 'LineStyle', '--')
|
||||||
|
% 线型代码:'--' 实线,'---' 虚线,':' 点线,'-.' 点划线,'none' 不划线
|
||||||
|
get(h, 'LineStyle')
|
||||||
|
% 获取当前句柄的线型
|
||||||
|
|
||||||
|
|
||||||
|
% 用 gca 函数返回当前图像的坐标轴句柄
|
||||||
|
set(gca, 'XDir', 'reverse'); % 令 x 轴反向
|
||||||
|
|
||||||
|
% 用 subplot 指令创建平铺排列的多张子图
|
||||||
|
subplot(2,3,1); % 选择 2 x 3 排列的子图中的第 1 张图
|
||||||
|
plot(x1); title('First Plot') % 在选中的图中绘图
|
||||||
|
subplot(2,3,2); % 选择 2 x 3 排列的子图中的第 2 张图
|
||||||
|
plot(x2); title('Second Plot') % 在选中的图中绘图
|
||||||
|
|
||||||
|
|
||||||
|
% 要调用函数或脚本,必须保证它们在你的当前工作目录中
|
||||||
|
path % 显示当前工作目录
|
||||||
|
addpath /path/to/dir % 将指定路径加入到当前工作目录中
|
||||||
|
rmpath /path/to/dir % 将指定路径从当前工作目录中删除
|
||||||
|
cd /path/to/move/into % 以制定路径作为当前工作目录
|
||||||
|
|
||||||
|
|
||||||
|
% 变量可保存到 .mat 格式的本地文件
|
||||||
|
save('myFileName.mat') % 保存当前工作空间中的所有变量
|
||||||
|
load('myFileName.mat') % 将指定文件中的变量载入到当前工作空间
|
||||||
|
|
||||||
|
|
||||||
|
% .m 脚本文件
|
||||||
|
% 脚本文件是一个包含多条 MATLAB 指令的外部文件,以 .m 为后缀名
|
||||||
|
% 使用脚本文件可以避免在命令窗口中重复输入冗长的指令
|
||||||
|
|
||||||
|
|
||||||
|
% .m 函数文件
|
||||||
|
% 与脚本文件类似,同样以 .m 作为后缀名
|
||||||
|
% 但函数文件可以接受用户输入的参数并返回运算结果
|
||||||
|
% 并且函数拥有自己的工作空间(变量域),不必担心变量名称冲突
|
||||||
|
% 函数文件的名称应当与其所定义的函数的名称一致(比如下面例子中函数文件就应命名为 double_input.m)
|
||||||
|
% 使用 'help double_input.m' 可返回函数定义中第一行注释信息
|
||||||
|
function output = double_input(x)
|
||||||
|
% double_input(x) 返回 x 的 2 倍
|
||||||
|
output = 2*x;
|
||||||
|
end
|
||||||
|
double_input(6) % ans = 12
|
||||||
|
|
||||||
|
|
||||||
|
% 同样还可以定义子函数和内嵌函数
|
||||||
|
% 子函数与主函数放在同一个函数文件中,且只能被这个主函数调用
|
||||||
|
% 内嵌函数放在另一个函数体内,可以直接访问被嵌套函数的各个变量
|
||||||
|
|
||||||
|
|
||||||
|
% 使用匿名函数可以不必创建 .m 函数文件
|
||||||
|
% 匿名函数适用于快速定义某函数以便传递给另一指令或函数(如绘图、积分、求根、求极值等)
|
||||||
|
% 下面示例的匿名函数返回输入参数的平方根,可以使用句柄 sqr 进行调用:
|
||||||
|
sqr = @(x) x.^2;
|
||||||
|
sqr(10) % ans = 100
|
||||||
|
doc function_handle % find out more
|
||||||
|
|
||||||
|
|
||||||
|
% 接受用户输入
|
||||||
|
a = input('Enter the value: ')
|
||||||
|
|
||||||
|
|
||||||
|
% 从文件中读取数据
|
||||||
|
fopen(filename)
|
||||||
|
% 类似函数还有 xlsread(excel 文件)、importdata(CSV 文件)、imread(图像文件)
|
||||||
|
|
||||||
|
|
||||||
|
% 输出
|
||||||
|
disp(a) % 在命令窗口中打印变量 a 的值
|
||||||
|
disp('Hello World') % 在命令窗口中打印字符串
|
||||||
|
fprintf % 按照指定格式在命令窗口中打印内容
|
||||||
|
|
||||||
|
% 条件语句(if 和 elseif 语句中的括号并非必需,但推荐加括号避免混淆)
|
||||||
|
if (a > 15)
|
||||||
|
disp('Greater than 15')
|
||||||
|
elseif (a == 23)
|
||||||
|
disp('a is 23')
|
||||||
|
else
|
||||||
|
disp('neither condition met')
|
||||||
|
end
|
||||||
|
|
||||||
|
% 循环语句
|
||||||
|
% 注意:对向量或矩阵使用循环语句进行元素遍历的效率很低!!
|
||||||
|
% 注意:只要有可能,就尽量使用向量或矩阵的整体运算取代逐元素循环遍历!!
|
||||||
|
% MATLAB 在开发时对向量和矩阵运算做了专门优化,做向量和矩阵整体运算的效率高于循环语句
|
||||||
|
for k = 1:5
|
||||||
|
disp(k)
|
||||||
|
end
|
||||||
|
|
||||||
|
k = 0;
|
||||||
|
while (k < 5)
|
||||||
|
k = k + 1;
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
% 程序运行计时:'tic' 是计时开始,'toc' 是计时结束并打印结果
|
||||||
|
tic
|
||||||
|
A = rand(1000);
|
||||||
|
A*A*A*A*A*A*A;
|
||||||
|
toc
|
||||||
|
|
||||||
|
|
||||||
|
% 链接 MySQL 数据库
|
||||||
|
dbname = 'database_name';
|
||||||
|
username = 'root';
|
||||||
|
password = 'root';
|
||||||
|
driver = 'com.mysql.jdbc.Driver';
|
||||||
|
dburl = ['jdbc:mysql://localhost:8889/' dbname];
|
||||||
|
javaclasspath('mysql-connector-java-5.1.xx-bin.jar'); % 此处 xx 代表具体版本号
|
||||||
|
% 这里的 mysql-connector-java-5.1.xx-bin.jar 可从 http://dev.mysql.com/downloads/connector/j/ 下载
|
||||||
|
conn = database(dbname, username, password, driver, dburl);
|
||||||
|
sql = ['SELECT * from table_name where id = 22'] % SQL 语句
|
||||||
|
a = fetch(conn, sql) % a 即包含所需数据
|
||||||
|
|
||||||
|
|
||||||
|
% 常用数学函数
|
||||||
|
sin(x)
|
||||||
|
cos(x)
|
||||||
|
tan(x)
|
||||||
|
asin(x)
|
||||||
|
acos(x)
|
||||||
|
atan(x)
|
||||||
|
exp(x)
|
||||||
|
sqrt(x)
|
||||||
|
log(x)
|
||||||
|
log10(x)
|
||||||
|
abs(x)
|
||||||
|
min(x)
|
||||||
|
max(x)
|
||||||
|
ceil(x)
|
||||||
|
floor(x)
|
||||||
|
round(x)
|
||||||
|
rem(x)
|
||||||
|
rand % 均匀分布的伪随机浮点数
|
||||||
|
randi % 均匀分布的伪随机整数
|
||||||
|
randn % 正态分布的伪随机浮点数
|
||||||
|
|
||||||
|
% 常用常数
|
||||||
|
pi
|
||||||
|
NaN
|
||||||
|
inf
|
||||||
|
|
||||||
|
% 求解矩阵方程(如果方程无解,则返回最小二乘近似解)
|
||||||
|
% \ 操作符等价于 mldivide 函数,/ 操作符等价于 mrdivide 函数
|
||||||
|
x=A\b % 求解 Ax=b,比先求逆再左乘 inv(A)*b 更加高效、准确
|
||||||
|
x=b/A % 求解 xA=b
|
||||||
|
|
||||||
|
inv(A) % 逆矩阵
|
||||||
|
pinv(A) % 伪逆矩阵
|
||||||
|
|
||||||
|
|
||||||
|
% 常用矩阵函数
|
||||||
|
zeros(m, n) % m x n 阶矩阵,元素全为 0
|
||||||
|
ones(m, n) % m x n 阶矩阵,元素全为 1
|
||||||
|
diag(A) % 返回矩阵 A 的对角线元素
|
||||||
|
diag(x) % 构造一个对角阵,对角线元素就是向量 x 的各元素
|
||||||
|
eye(m, n) % m x n 阶单位矩阵
|
||||||
|
linspace(x1, x2, n) % 返回介于 x1 和 x2 之间的 n 个等距节点
|
||||||
|
inv(A) % 矩阵 A 的逆矩阵
|
||||||
|
det(A) % 矩阵 A 的行列式
|
||||||
|
eig(A) % 矩阵 A 的特征值和特征向量
|
||||||
|
trace(A) % 矩阵 A 的迹(即对角线元素之和),等价于 sum(diag(A))
|
||||||
|
isempty(A) % 测试 A 是否为空
|
||||||
|
all(A) % 测试 A 中所有元素是否都非 0 或都为真(逻辑值)
|
||||||
|
any(A) % 测试 A 中是否有元素非 0 或为真(逻辑值)
|
||||||
|
isequal(A, B) % 测试 A 和 B是否相等
|
||||||
|
numel(A) % 矩阵 A 的元素个数
|
||||||
|
triu(x) % 返回 x 的上三角这部分
|
||||||
|
tril(x) % 返回 x 的下三角这部分
|
||||||
|
cross(A, B) % 返回 A 和 B 的叉积(矢量积、外积)
|
||||||
|
dot(A, B) % 返回 A 和 B 的点积(数量积、内积),要求 A 和 B 必须等长
|
||||||
|
transpose(A) % A 的转置,等价于 A'
|
||||||
|
fliplr(A) % 将一个矩阵左右翻转
|
||||||
|
flipud(A) % 将一个矩阵上下翻转
|
||||||
|
|
||||||
|
% 矩阵分解
|
||||||
|
[L, U, P] = lu(A) % LU 分解:PA = LU,L 是下三角阵,U 是上三角阵,P 是置换阵
|
||||||
|
[P, D] = eig(A) % 特征值分解:AP = PD,D 是由特征值构成的对角阵,P 的各列就是对应的特征向量
|
||||||
|
[U, S, V] = svd(X) % 奇异值分解:XV = US,U 和 V 是酉矩阵,S 是由奇异值构成的半正定实数对角阵
|
||||||
|
|
||||||
|
% 常用向量函数
|
||||||
|
max % 最大值
|
||||||
|
min % 最小值
|
||||||
|
length % 元素个数
|
||||||
|
sort % 按升序排列
|
||||||
|
sum % 各元素之和
|
||||||
|
prod % 各元素之积
|
||||||
|
mode % 众数
|
||||||
|
median % 中位数
|
||||||
|
mean % 平均值
|
||||||
|
std % 标准差
|
||||||
|
perms(x) % x 元素的全排列
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 相关资料
|
||||||
|
|
||||||
|
* 官方网页:[http://http://www.mathworks.com/products/matlab/](http://www.mathworks.com/products/matlab/)
|
||||||
|
* 官方论坛:[http://www.mathworks.com/matlabcentral/answers/](http://www.mathworks.com/matlabcentral/answers/)
|
Loading…
Reference in New Issue
Block a user