summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--asymptotic-notation.html.markdown12
-rw-r--r--c++.html.markdown12
-rw-r--r--css.html.markdown19
-rw-r--r--fr-fr/go-fr.html.markdown438
-rw-r--r--git.html.markdown3
-rw-r--r--hack.html.markdown307
-rw-r--r--haskell.html.markdown42
-rw-r--r--haxe.html.markdown33
-rw-r--r--java.html.markdown14
-rw-r--r--javascript.html.markdown6
-rw-r--r--nim.html.markdown14
-rw-r--r--perl6.html.markdown6
-rw-r--r--pt-br/brainfuck-pt.html.markdown84
-rw-r--r--pt-br/git-pt.html.markdown312
-rw-r--r--pt-pt/git-pt.html.markdown13
-rw-r--r--python.html.markdown2
-rw-r--r--python3.html.markdown12
-rw-r--r--racket.html.markdown48
-rw-r--r--ru-ru/lua-ru.html.markdown2
-rw-r--r--ru-ru/swift-ru.html.markdown52
-rw-r--r--ruby.html.markdown25
-rw-r--r--swift.html.markdown52
-rwxr-xr-xtcl.html.markdown4
-rw-r--r--typescript.html.markdown133
-rw-r--r--xml.html.markdown4
-rw-r--r--zh-cn/javascript-cn.html.markdown516
-rw-r--r--zh-cn/swift-cn.html.markdown590
27 files changed, 2116 insertions, 639 deletions
diff --git a/asymptotic-notation.html.markdown b/asymptotic-notation.html.markdown
index deb3e37d..e1f961f8 100644
--- a/asymptotic-notation.html.markdown
+++ b/asymptotic-notation.html.markdown
@@ -66,8 +66,8 @@ Polynomial - n^z, where z is some constant
Exponential - a^n, where a is some constant
```
-### Big-Oh
-Big-Oh, commonly written as O, is an Asymptotic Notation for the worst case, or ceiling of growth
+### Big-O
+Big-O, commonly written as O, is an Asymptotic Notation for the worst case, or ceiling of growth
for a given function. Say `f(n)` is your algorithm runtime, and `g(n)` is an arbitrary time complexity
you are trying to relate to your algorithm. `f(n)` is O(g(n)), if for any real constant c (c > 0),
`f(n)` <= `c g(n)` for every input size n (n > 0).
@@ -81,7 +81,7 @@ g(n) = log n
Is `f(n)` O(g(n))?
Is `3 log n + 100` O(log n)?
-Let's look to the definition of Big-Oh.
+Let's look to the definition of Big-O.
```
3log n + 100 <= c * log n
@@ -93,7 +93,7 @@ Is there some constant c that satisfies this for all n?
3log n + 100 <= 150 * log n, n > 2 (undefined at n = 1)
```
-Yes! The definition of Big-Oh has been met therefore `f(n)` is O(g(n)).
+Yes! The definition of Big-O has been met therefore `f(n)` is O(g(n)).
*Example 2*
@@ -104,7 +104,7 @@ g(n) = n
Is `f(n)` O(g(n))?
Is `3 * n^2` O(n)?
-Let's look at the definition of Big-Oh.
+Let's look at the definition of Big-O.
```
3 * n^2 <= c * n
@@ -119,7 +119,7 @@ for a given function.
`f(n)` is Ω(g(n)), if for any real constant c (c > 0), `f(n)` is >= `c g(n)` for every input size n (n > 0).
-Feel free to head over to additional resources for examples on this. Big-Oh is the primary notation used
+Feel free to head over to additional resources for examples on this. Big-O is the primary notation used
for general algorithm time complexity.
### Ending Notes
diff --git a/c++.html.markdown b/c++.html.markdown
index 5f80f26f..1978d183 100644
--- a/c++.html.markdown
+++ b/c++.html.markdown
@@ -30,10 +30,10 @@ one of the most widely-used programming languages.
// C++ is _almost_ a superset of C and shares its basic syntax for
// variable declarations, primitive types, and functions.
-// However, C++ varies in some of the following ways:
-// A main() function in C++ should return an int,
-// though void main() is accepted by most compilers (gcc, clang, etc.)
+// Just like in C, your program's entry point is a function called
+// main with an integer return type,
+// though void main() is also accepted by most compilers (gcc, clang, etc.)
// This value serves as the program's exit status.
// See http://en.wikipedia.org/wiki/Exit_status for more information.
int main(int argc, char** argv)
@@ -51,6 +51,8 @@ int main(int argc, char** argv)
return 0;
}
+// However, C++ varies in some of the following ways:
+
// In C++, character literals are one byte.
sizeof('c') == 1
@@ -492,7 +494,7 @@ bool doSomethingWithAFile(const char* filename)
{
FILE* fh = fopen(filename, "r"); // Open the file in read mode
if (fh == nullptr) // The returned pointer is null on failure.
- reuturn false; // Report that failure to the caller.
+ return false; // Report that failure to the caller.
// Assume each function returns false if it failed
if (!doSomethingWithTheFile(fh)) {
@@ -513,7 +515,7 @@ bool doSomethingWithAFile(const char* filename)
{
FILE* fh = fopen(filename, "r");
if (fh == nullptr)
- reuturn false;
+ return false;
if (!doSomethingWithTheFile(fh))
goto failure;
diff --git a/css.html.markdown b/css.html.markdown
index e058d691..9e8664b3 100644
--- a/css.html.markdown
+++ b/css.html.markdown
@@ -37,19 +37,19 @@ selector { property: value; /* more properties...*/ }
/* the selector is used to target an element on page.
-You can target all elments on the page using asterisk! */
+You can target all elements on the page using asterisk! */
* { color:red; }
/*
Given an element like this on the page:
-<div class='some-class class2' id='someId' attr='value' />
+<div class='some-class class2' id='someId' attr='value' otherAttr='en-us foo bar' />
*/
/* you can target it by its name */
.some-class { }
-/*or by both classes! */
+/* or by both classes! */
.some-class.class2 { }
/* or by its element name */
@@ -70,8 +70,11 @@ div { }
/* or ends with (CSS3) */
[attr$='ue'] { font-size:smaller; }
-/* or even contains a value (CSS3) */
-[attr~='lu'] { font-size:smaller; }
+/* or select by one of the values from the whitespace separated list (CSS3) */
+[otherAttr~='foo'] { font-size:smaller; }
+
+/* or value can be exactly “value” or can begin with “value” immediately followed by “-” (U+002D) */
+[otherAttr|='en'] { font-size:smaller; }
/* and more importantly you can combine these together -- there shouldn't be
@@ -89,7 +92,7 @@ div.some-parent > .class-name {}
and is child of a div with class name "some-parent" IN ANY DEPTH */
div.some-parent .class-name {}
-/* warning: the same selector wihout spaaace has another meaning.
+/* warning: the same selector without space has another meaning.
can you say what? */
div.some-parent.class-name {}
@@ -152,7 +155,7 @@ selector {
/* Fonts */
font-family: Arial;
- font-family: "Courier New"; /* if name has spaaace it appears in single or double quotes */
+ font-family: "Courier New"; /* if name has space it appears in single or double quotes */
font-family: "Courier New", Trebuchet, Arial, sans-serif; /* if first one was not found
browser uses the second font, and so forth */
}
@@ -230,7 +233,7 @@ Remember, the precedence is for each **property**, not for the entire block.
## Compatibility
Most of the features in CSS2 (and gradually in CSS3) are compatible across
-all browsers and devices. But it's always vital to have in mind the compatiblity
+all browsers and devices. But it's always vital to have in mind the compatibility
of what you use in CSS with your target browsers.
[QuirksMode CSS](http://www.quirksmode.org/css/) is one of the best sources for this.
diff --git a/fr-fr/go-fr.html.markdown b/fr-fr/go-fr.html.markdown
new file mode 100644
index 00000000..2ff5902f
--- /dev/null
+++ b/fr-fr/go-fr.html.markdown
@@ -0,0 +1,438 @@
+---
+name: Go
+category: language
+language: Go
+filename: learngo.go
+contributors:
+ - ["Sonia Keys", "https://github.com/soniakeys"]
+ - ["Christopher Bess", "https://github.com/cbess"]
+ - ["Jesse Johnson", "https://github.com/holocronweaver"]
+ - ["Quint Guvernator", "https://github.com/qguv"]
+ - ["Jose Donizetti", "https://github.com/josedonizetti"]
+ - ["Alexej Friesen", "https://github.com/heyalexej"]
+ - ["Jean-Philippe Monette", "http://blogue.jpmonette.net/"]
+---
+
+Go a été créé dans l'optique de développer de façon efficace. Ce n'est pas la
+dernière tendance en ce qui est au développement, mais c'est la nouvelle façon
+de régler des défis réels de façon rapide.
+
+Le langage possède des concepts familiers à la programmation impérative avec
+typage. Il est rapide à compiler et exécuter, ajoute une concurrence facile à
+comprendre, pour les processeurs multi coeurs d'aujourd'hui et apporte des
+fonctionnalités facilitant le développement à grande échelle.
+
+Développer avec Go, c'est bénéficier d'une riche bibliothèque standard et d'une
+communauté active.
+
+```go
+// Commentaire ligne simple
+/* Commentaire
+ multiligne */
+
+// Un paquet débute avec une clause "package"
+// "Main" est un nom spécial déclarant un paquet de type exécutable plutôt
+// qu'une bibliothèque
+package main
+
+// "Import" déclare les paquets référencés dans ce fichier.
+import (
+ "fmt" // Un paquet dans la bibliothèque standard.
+ "io/ioutil" // Implémente des fonctions utilitaires I/O.
+ m "math" // Bibliothèque mathématique utilisant un alias local "m".
+ "net/http" // Un serveur Web!
+ "strconv" // Bibliothèque pour convertir les chaînes de caractères.
+)
+
+// Une définition de fonction. La fonction "main" est spéciale - c'est le point
+// d'entrée du binaire.
+func main() {
+ // Println retournera la valeur à la console.
+ // Associez la fonction avec son paquet respectif, fmt.
+ fmt.Println("Hello world!")
+
+ // Appelez une fonction différente à partir de ce paquet.
+ beyondHello()
+}
+
+// Les fonctions ont des paramètres entre parenthèses.
+// Les parenthèses sont nécessaires avec ou sans paramètre.
+func beyondHello() {
+ var x int // Déclaration de variable. Les variables doivent être déclarées
+ // avant leur utilisation.
+ x = 3 // Assignation de valeur.
+ // Les déclarations courtes utilisent := pour inférer le type, déclarer et
+ // assigner.
+ y := 4
+ sum, prod := learnMultiple(x, y) // La fonction retourne deux valeurs.
+ fmt.Println("sum:", sum, "prod:", prod) // Affichage simple.
+ learnTypes() // < y minutes, en savoir plus!
+}
+
+// Les fonctions peuvent avoir des paramètres et plusieurs valeurs retournées.
+func learnMultiple(x, y int) (sum, prod int) {
+ return x + y, x * y // Deux valeurs retournées.
+}
+
+// Quelques types inclus et littéraux.
+func learnTypes() {
+ // Une déclaration courte infère généralement le type désiré.
+ str := "Learn Go!" // Type string.
+
+ s2 := `Une chaîne de caractères peut contenir des
+sauts de ligne.` // Chaîne de caractère.
+
+ // Littéral non-ASCII. Les sources Go utilisent le charset UTF-8.
+ g := 'Σ' // type rune, un alias pour le type int32, contenant un caractère
+ // unicode.
+
+ f := 3.14195 // float64, un nombre flottant IEEE-754 de 64-bit.
+ c := 3 + 4i // complex128, considéré comme deux float64 par le compilateur.
+
+ // Syntaxe "var" avec une valeur d'initialisation.
+ var u uint = 7 // Non signé, mais la taille dépend selon l'entier.
+ var pi float32 = 22. / 7
+
+ // Conversion avec syntaxe courte.
+ n := byte('\n') // byte est un alias du type uint8.
+
+ // Les tableaux ont une taille fixe déclarée à la compilation.
+ var a4 [4]int // Un tableau de 4 ints, tous initialisés à 0.
+ a3 := [...]int{3, 1, 5} // Un tableau initialisé avec une taille fixe de 3
+ // éléments, contenant les valeurs 3, 1 et 5.
+
+ // Les slices ont des tailles dynamiques. Les tableaux et slices ont chacun
+ // des avantages, mais les cas d'utilisation des slices sont plus fréquents.
+ s3 := []int{4, 5, 9} // Comparable à a3.
+ s4 := make([]int, 4) // Alloue un slice de 4 ints, initialisés à 0.
+ var d2 [][]float64 // Déclaration seulement, sans allocation de mémoire.
+ bs := []byte("a slice") // Conversion d'une chaîne en slice de bytes.
+
+ // Parce qu'elles sont dynamiques, les slices peuvent être jointes sur
+ // demande. Pour joindre un élément à une slice, la fonction standard append()
+ // est utilisée. Le premier argument est la slice à utiliser. Habituellement,
+ // la variable tableau est mise à jour sur place, voir ci-bas.
+ s := []int{1, 2, 3} // Le résultat est une slice de taille 3.
+ s = append(s, 4, 5, 6) // Ajout de 3 valeurs. La taille est de 6.
+ fmt.Println(s) // La valeur est de [1 2 3 4 5 6]
+
+ // Pour ajouter une slice à une autre, au lieu d'utiliser une liste de valeurs
+ // atomiques, il est possible de mettre en argument une référence de
+ // slice littérale grâce aux points de suspension.
+ s = append(s, []int{7, 8, 9}...) // Le deuxième argument est une slice
+ // littérale.
+ fmt.Println(s) // La slice contient [1 2 3 4 5 6 7 8 9]
+
+ p, q := learnMemory() // Déclare p, q comme étant des pointeurs de type int.
+ fmt.Println(*p, *q) // * suit un pointeur. Ceci retourne deux ints.
+
+ // Les maps sont des tableaux associatifs de taille dynamique, comme les
+ // hash ou les types dictionnaires de certains langages.
+ m := map[string]int{"trois": 3, "quatre": 4}
+ m["un"] = 1
+
+ // Les valeurs inutilisées sont considérées comme des erreurs en Go.
+ // Un tiret bas permet d'ignorer une valeur inutilisée, évitant une erreur.
+ _, _, _, _, _, _, _, _, _, _ = str, s2, g, f, u, pi, n, a3, s4, bs
+
+ // Cependant, son affichage en console est considéré comme une utilisation,
+ // ce qui ne sera pas considéré comme une erreur à la compilation.
+ fmt.Println(s, c, a4, s3, d2, m)
+
+ learnFlowControl() // De retour dans le flux.
+}
+
+// Il est possible, à l'opposé de plusieurs autres langages, de retourner des
+// variables par leur nom à partir de fonctions.
+// Assigner un nom à un type retourné par une fonction permet de retrouver sa
+// valeur ainsi que d'utiliser le mot-clé "return" uniquement, sans plus.
+func learnNamedReturns(x, y int) (z int) {
+ z = x * y
+ return // z est implicite, car la variable a été définie précédemment.
+}
+
+// La récupération de la mémoire est automatique en Go. Le langage possède des
+// pointeurs, mais aucune arithmétique des pointeurs (*(a + b) en C). Vous
+// pouvez produire une erreur avec un pointeur nil, mais pas en incrémentant un
+// pointeur.
+func learnMemory() (p, q *int) {
+ // Les valeurs retournées p et q auront le type pointeur int.
+ p = new(int) // Fonction standard "new" alloue la mémoire.
+ // Le int alloué est initialisé à 0, p n'est plus nil.
+ s := make([]int, 20) // Alloue 20 ints en un seul bloc de mémoire.
+ s[3] = 7 // Assigne l'un des entiers.
+ r := -2 // Déclare une autre variable locale.
+ return &s[3], &r // & retourne l'adresse d'un objet.
+}
+
+func expensiveComputation() float64 {
+ return m.Exp(10)
+}
+
+func learnFlowControl() {
+ // Bien que les "if" requièrent des accolades, les parenthèses ne sont pas
+ // nécessaires pour contenir le test booléen.
+ if true {
+ fmt.Println("voilà!")
+ }
+ // Le formatage du code est standardisé par la commande shell "go fmt."
+ if false {
+ // bing.
+ } else {
+ // bang.
+ }
+ // Utilisez "switch" au lieu des "if" en chaîne
+ x := 42.0
+ switch x {
+ case 0:
+ case 1:
+ case 42:
+ // Les "case" n'ont pas besoin de "break;".
+ case 43:
+ // Non-exécuté.
+ }
+ // Comme les "if", les "for" n'utilisent pas de parenthèses.
+ // Les variables déclarées dans les "for" et les "if" sont locales à leur
+ // portée.
+ for x := 0; x < 3; x++ { // ++ est une incrémentation.
+ fmt.Println("itération ", x)
+ }
+ // x == 42 ici.
+
+ // "For" est le seul type de boucle en Go, mais possède différentes formes.
+ for { // Boucle infinie
+ break // C'est une farce
+ continue // Non atteint.
+ }
+
+ // Vous pouvez utiliser une "range" pour itérer dans un tableau, une slice, une
+ // chaîne, une map ou un canal. Les "range" retournent un canal ou deux
+ // valeurs (tableau, slice, chaîne et map).
+ for key, value := range map[string]int{"une": 1, "deux": 2, "trois": 3} {
+ // pour chaque pair dans une map, affichage de la valeur et clé
+ fmt.Printf("clé=%s, valeur=%d\n", key, value)
+ }
+
+ // À l'opposé du "for", := dans un "if" signifie la déclaration et
+ // l'assignation y en premier, et ensuite y > x
+ if y := expensiveComputation(); y > x {
+ x = y
+ }
+ // Les fonctions littérales sont des fermetures.
+ xBig := func() bool {
+ return x > 10000
+ }
+ fmt.Println("xBig:", xBig()) // true (la valeur e^10 a été assignée à x).
+ x = 1.3e3 // Ceci fait x == 1300
+ fmt.Println("xBig:", xBig()) // Maintenant false.
+
+ // De plus, les fonctions littérales peuvent être définies et appelées
+ // sur la même ligne, agissant comme argument à cette fonction, tant que:
+ // a) la fonction littérale est appelée suite à (),
+ // b) le résultat correspond au type de l'argument.
+ fmt.Println("Ajoute + multiplie deux nombres : ",
+ func(a, b int) int {
+ return (a + b) * 2
+ }(10, 2)) // Appelle la fonction avec les arguments 10 et 2
+ // => Ajoute + double deux nombres : 24
+
+ // Quand vous en aurez besoin, vous allez l'adorer.
+ goto love
+love:
+
+ learnFunctionFactory() // func retournant func correspondant à fun(3)(3).
+ learnDefer() // Un survol de cette instruction importante.
+ learnInterfaces() // Incontournable !
+}
+
+func learnFunctionFactory() {
+ // Les deux syntaxes sont identiques, bien que la seconde soit plus pratique.
+ fmt.Println(sentenceFactory("été")("Une matinée d'", "agréable!"))
+
+ d := sentenceFactory("été")
+ fmt.Println(d("Une matinée d'", "agréable!"))
+ fmt.Println(d("Une soirée d'", "relaxante!"))
+}
+
+// Le décorateur est un patron de conception commun dans d'autres langages.
+// Il est possible de faire de même en Go avec des fonctions littérales
+// acceptant des arguments.
+func sentenceFactory(mystring string) func(before, after string) string {
+ return func(before, after string) string {
+ return fmt.Sprintf("%s %s %s", before, mystring, after) // nouvelle chaîne
+ }
+}
+
+func learnDefer() (ok bool) {
+ // Les déclarations différées sont exécutées avant la sortie d'une fonction.
+ defer fmt.Println("les déclarations différées s'exécutent en ordre LIFO.")
+ defer fmt.Println("\nCette ligne est affichée en premier parce que")
+ // Les déclarations différées sont utilisées fréquemment pour fermer un
+ // fichier, afin que la fonction ferme le fichier en fin d'exécution.
+ return true
+}
+
+// Défini Stringer comme étant une interface avec une méthode, String.
+type Stringer interface {
+ String() string
+}
+
+// Défini pair comme étant une structure contenant deux entiers, x et y.
+type pair struct {
+ x, y int
+}
+
+// Défini une méthode associée au type pair. Pair implémente maintenant Stringer
+func (p pair) String() string { // p s'appelle le "destinataire"
+ // Sprintf est une autre fonction publique dans le paquet fmt.
+ // La syntaxe avec point permet de faire référence aux valeurs de p.
+ return fmt.Sprintf("(%d, %d)", p.x, p.y)
+}
+
+func learnInterfaces() {
+ // La syntaxe avec accolade défini une "structure littérale". Celle-ci
+ // s'évalue comme étant une structure. La syntaxe := déclare et initialise p
+ // comme étant une instance.
+ p := pair{3, 4}
+ fmt.Println(p.String()) // Appelle la méthode String de p, de type pair.
+ var i Stringer // Déclare i instance de l'interface Stringer.
+ i = p // Valide, car pair implémente Stringer.
+ // Appelle la méthode String de i, de type Stringer. Retourne la même valeur
+ // que ci-haut.
+ fmt.Println(i.String())
+
+ // Les fonctions dans le paquet fmt appellent la méthode String, demandant
+ // aux objets d'afficher une représentation de leur structure.
+ fmt.Println(p) // Affiche la même chose que ci-haut. Println appelle la
+ // méthode String.
+ fmt.Println(i) // Affiche la même chose que ci-haut.
+
+ learnVariadicParams("apprentissage", "génial", "ici!")
+}
+
+// Les fonctions peuvent être définie de façon à accepter un ou plusieurs
+// paramètres grâce aux points de suspension, offrant une flexibilité lors de
+// son appel.
+func learnVariadicParams(myStrings ...interface{}) {
+ // Itère chaque paramètre dans la range.
+ // Le tiret bas sert à ignorer l'index retourné du tableau.
+ for _, param := range myStrings {
+ fmt.Println("paramètre:", param)
+ }
+
+ // Passe une valeur variadique comme paramètre variadique.
+ fmt.Println("paramètres:", fmt.Sprintln(myStrings...))
+
+ learnErrorHandling()
+}
+
+func learnErrorHandling() {
+ // ", ok" idiome utilisée pour définir si l'opération s'est déroulée avec
+ // succès ou non
+ m := map[int]string{3: "trois", 4: "quatre"}
+ if x, ok := m[1]; !ok { // ok sera faux, car 1 n'est pas dans la map.
+ fmt.Println("inexistant")
+ } else {
+ fmt.Print(x) // x serait la valeur, si elle se trouvait dans la map.
+ }
+ // Une erreur ne retourne qu'un "ok", mais également plus d'information
+ // par rapport à un problème survenu.
+ if _, err := strconv.Atoi("non-int"); err != nil { // _ discarte la valeur
+ // retourne: 'strconv.ParseInt: parsing "non-int": invalid syntax'
+ fmt.Println(err)
+ }
+ // Nous réviserons les interfaces un peu plus tard. Pour l'instant,
+ learnConcurrency()
+}
+
+// c est un canal, un objet permettant de communiquer en simultané de façon
+// sécurisée.
+func inc(i int, c chan int) {
+ c <- i + 1 // <- est l'opérateur "envoi" quand un canal apparaît à
+ // gauche.
+}
+
+// Nous utiliserons inc pour incrémenter des nombres en même temps.
+func learnConcurrency() {
+ // La fonction "make" utilisée précédemment pour générer un slice. Elle
+ // alloue et initialise les slices, maps et les canaux.
+ c := make(chan int)
+ // Démarrage de trois goroutines simultanées. Les nombres seront incrémentés
+ // simultanément, peut-être en paralèle si la machine le permet et configurée
+ // correctement. Les trois utilisent le même canal.
+ go inc(0, c) // go est une instruction démarrant une nouvelle goroutine.
+ go inc(10, c)
+ go inc(-805, c)
+ // Lis et affiche trois résultats du canal - impossible de savoir dans quel
+ // ordre !
+ fmt.Println(<-c, <-c, <-c) // Canal à droite, <- est l'opérateur de
+ // "réception".
+
+ cs := make(chan string) // Un autre canal, celui-ci gère des chaînes.
+ ccs := make(chan chan string) // Un canal de canaux de chaînes.
+ go func() { c <- 84 }() // Démarre une nouvelle goroutine, pour
+ // envoyer une valeur.
+ go func() { cs <- "wordy" }() // De nouveau, pour cs cette fois-ci.
+ // Select possède une syntaxe similaire au switch, mais chaque cas requiert
+ // une opération impliquant un canal. Il sélectionne un cas aléatoirement
+ // prêt à communiquer.
+ select {
+ case i := <-c: // La valeur reçue peut être assignée à une variable,
+ fmt.Printf("c'est un %T", i)
+ case <-cs: // ou la valeur reçue peut être ignorée.
+ fmt.Println("c'est une chaîne")
+ case <-ccs: // Un canal vide, indisponible à la communication.
+ fmt.Println("ne surviendra pas.")
+ }
+ // À ce point, une valeur a été prise de c ou cs. L'une des deux goroutines
+ // démarrée plus haut a complétée, la seconde restera bloquée.
+
+ learnWebProgramming() // Go permet la programmation Web.
+}
+
+// Une seule fonction du paquet http démarre un serveur Web.
+func learnWebProgramming() {
+
+ // Le premier paramètre de ListenAndServe est une adresse TCP à écouter.
+ // Le second est une interface, de type http.Handler.
+ go func() {
+ err := http.ListenAndServe(":8080", pair{})
+ fmt.Println(err) // n'ignorez pas les erreurs !
+ }()
+
+ requestServer()
+}
+
+// Implémente la méthode ServeHTTP de http.Handler à pair, la rendant compatible
+// avec les opérations utilisant l'interface http.Handler.
+func (p pair) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+ // Répondez à une requête à l'aide de la méthode http.ResponseWriter.
+ w.Write([]byte("Vous avez appris Go en Y minutes!"))
+}
+
+func requestServer() {
+ resp, err := http.Get("http://localhost:8080")
+ fmt.Println(err)
+ defer resp.Body.Close()
+ body, err := ioutil.ReadAll(resp.Body)
+ fmt.Printf("\nLe serveur Web a dit: `%s`", string(body))
+}
+```
+
+## En savoir plus
+
+La référence Go se trouve sur [le site officiel de Go](http://golang.org/).
+Vous pourrez y suivre le tutoriel interactif et en apprendre beaucoup plus.
+
+Une lecture de la documentation du langage est grandement conseillée. C'est
+facile à lire et très court (comparé aux autres langages).
+
+Vous pouvez exécuter et modifier le code sur [Go playground](https://play.golang.org/p/tnWMjr16Mm). Essayez de le modifier et de l'exécuter à partir de votre navigateur! Prennez en note que vous pouvez utiliser [https://play.golang.org](https://play.golang.org) comme un [REPL](https://en.wikipedia.org/wiki/Read-eval-print_loop) pour tester et coder dans votre navigateur, sans même avoir à installer Go.
+
+Sur la liste de lecteur des étudiants de Go se trouve le [code source de la
+librairie standard](http://golang.org/src/pkg/). Bien documentée, elle démontre
+le meilleur de la clarté de Go, le style ainsi que ses expressions. Sinon, vous
+pouvez cliquer sur le nom d'une fonction dans [la
+documentation](http://golang.org/pkg/) et le code source apparaît!
+
+Une autre excellente ressource pour apprendre est [Go par l'exemple](https://gobyexample.com/).
diff --git a/git.html.markdown b/git.html.markdown
index 04350dd5..af65afb0 100644
--- a/git.html.markdown
+++ b/git.html.markdown
@@ -217,6 +217,9 @@ the changes made and a message created by the user.
```bash
# commit with a message
$ git commit -m "Added multiplyNumbers() function to HelloWorld.c"
+
+# automatically stage modified or deleted files, except new files, and then commit
+$ git commit -a -m "Modified foo.php and removed bar.php"
```
### diff
diff --git a/hack.html.markdown b/hack.html.markdown
new file mode 100644
index 00000000..632fc705
--- /dev/null
+++ b/hack.html.markdown
@@ -0,0 +1,307 @@
+---
+language: Hack
+contributors:
+ - ["Stephen Holdaway", "https://github.com/stecman"]
+filename: learnhack.hh
+---
+
+Hack is a superset of PHP that runs under a virtual machine called HHVM. Hack
+is almost completely interoperable with existing PHP code and adds a bunch of
+useful features from statically typed languages.
+
+
+Only Hack-specific features are covered here. Details about PHP's syntax are
+available in the [PHP article](http://learnxinyminutes.com/docs/php/) on this site.
+
+```php
+<?hh
+
+// Hack syntax is only enabled for files starting with an <?hh marker
+// <?hh markers cannot be interspersed with HTML the way <?php can be.
+// Using the marker "<?hh //strict" puts the type checker in strict mode.
+
+
+// Scalar parameter type hints
+function repeat(string $word, int $count)
+{
+ $word = trim($word);
+ return str_repeat($word . ' ', $count);
+}
+
+// Type hints for return values
+function add(...$numbers) : int
+{
+ return array_sum($numbers);
+}
+
+// Functions that return nothing are hinted as "void"
+function truncate(resource $handle) : void
+{
+ // ...
+}
+
+// Type hints must explicitly allow being nullable
+function identity(?string $stringOrNull) : ?string
+{
+ return $stringOrNull;
+}
+
+// Type hints can be specified on class properties
+class TypeHintedProperties
+{
+ public ?string $name;
+
+ protected int $id;
+
+ private float $score = 100.0;
+
+ // Hack's type checker enforces that typed properties either have a
+ // default value or are set in the constructor.
+ public function __construct(int $id)
+ {
+ $this->id = $id;
+ }
+}
+
+
+// Concise anonymous functions (lambdas)
+$multiplier = 5;
+array_map($y ==> $y * $multiplier, [1, 2, 3]);
+
+
+// Generics
+class Box<T>
+{
+ protected T $data;
+
+ public function __construct(T $data) {
+ $this->data = $data;
+ }
+
+ public function getData(): T {
+ return $this->data;
+ }
+}
+
+function openBox(Box<int> $box) : int
+{
+ return $box->getData();
+}
+
+
+// Shapes
+//
+// Hack adds the concept of shapes for defining struct-like arrays with a
+// guaranteed, type-checked set of keys
+type Point2D = shape('x' => int, 'y' => int);
+
+function distance(Point2D $a, Point2D $b) : float
+{
+ return sqrt(pow($b['x'] - $a['x'], 2) + pow($b['y'] - $a['y'], 2));
+}
+
+distance(
+ shape('x' => -1, 'y' => 5),
+ shape('x' => 2, 'y' => 50)
+);
+
+
+// Type aliasing
+//
+// Hack adds a bunch of type aliasing features for making complex types readable
+newtype VectorArray = array<int, Vector<int>>;
+
+// A tuple containing two integers
+newtype Point = (int, int);
+
+function addPoints(Point $p1, Point $p2) : Point
+{
+ return tuple($p1[0] + $p2[0], $p1[1] + $p2[1]);
+}
+
+addPoints(
+ tuple(1, 2),
+ tuple(5, 6)
+);
+
+
+// First-class enums
+enum RoadType : int
+{
+ Road = 0;
+ Street = 1;
+ Avenue = 2;
+ Boulevard = 3;
+}
+
+function getRoadType() : RoadType
+{
+ return RoadType::Avenue;
+}
+
+
+// Constructor argument promotion
+//
+// To avoid boilerplate property and constructor definitions that only set
+// properties, Hack adds a concise syntax for defining properties and a
+// constructor at the same time.
+class ArgumentPromotion
+{
+ public function __construct(public string $name,
+ protected int $age,
+ private bool $isAwesome) {}
+}
+
+class WithoutArugmentPromotion
+{
+ public string $name;
+
+ protected int $age;
+
+ private bool $isAwesome;
+
+ public function __construct(string $name, int $age, bool $isAwesome)
+ {
+ $this->name = $name;
+ $this->age = $age;
+ $this->isAwesome = $isAwesome;
+ }
+}
+
+
+// Co-oprerative multi-tasking
+//
+// Two new keywords "async" and "await" can be used to perform mutli-tasking
+// Note that this does not involve threads - it just allows transfer of control
+async function cooperativePrint(int $start, int $end) : Awaitable<void>
+{
+ for ($i = $start; $i <= $end; $i++) {
+ echo "$i ";
+
+ // Give other tasks a chance to do something
+ await RescheduleWaitHandle::create(RescheduleWaitHandle::QUEUE_DEFAULT, 0);
+ }
+}
+
+// This prints "1 4 7 2 5 8 3 6 9"
+AwaitAllWaitHandle::fromArray([
+ cooperativePrint(1, 3),
+ cooperativePrint(4, 6),
+ cooperativePrint(7, 9)
+])->getWaitHandle()->join();
+
+
+// Attributes
+//
+// Attributes are a form of metadata for functions. Hack provides some
+// special built-in attributes that introduce useful behaviour.
+
+// The __Memoize special attribute causes the result of a function to be cached
+<<__Memoize>>
+function doExpensiveTask() : ?string
+{
+ return file_get_contents('http://example.com');
+}
+
+// The function's body is only executed once here:
+doExpensiveTask();
+doExpensiveTask();
+
+
+// The __ConsistentConstruct special attribute signals the Hack type checker to
+// ensure that the signature of __construct is the same for all subclasses.
+<<__ConsistentConstruct>>
+class ConsistentFoo
+{
+ public function __construct(int $x, float $y)
+ {
+ // ...
+ }
+
+ public function someMethod()
+ {
+ // ...
+ }
+}
+
+class ConsistentBar extends ConsistentFoo
+{
+ public function __construct(int $x, float $y)
+ {
+ // Hack's type checker enforces that parent constructors are called
+ parent::__construct($x, $y);
+
+ // ...
+ }
+
+ // The __Override annotation is an optional signal for the Hack type
+ // checker to enforce that this method is overriding a method in a parent
+ // or trait. If not, this will error.
+ <<__Override>>
+ public function someMethod()
+ {
+ // ...
+ }
+}
+
+class InvalidFooSubclass extends ConsistentFoo
+{
+ // Not matching the parent constructor will cause a type checker error:
+ //
+ // "This object is of type ConsistentBaz. It is incompatible with this object
+ // of type ConsistentFoo because some of their methods are incompatible"
+ //
+ public function __construct(float $x)
+ {
+ // ...
+ }
+
+ // Using the __Override annotation on a non-overriden method will cause a
+ // type checker error:
+ //
+ // "InvalidFooSubclass::otherMethod() is marked as override; no non-private
+ // parent definition found or overridden parent is defined in non-<?hh code"
+ //
+ <<__Override>>
+ public function otherMethod()
+ {
+ // ...
+ }
+}
+
+
+// Traits can implement interfaces (standard PHP does not support this)
+interface KittenInterface
+{
+ public function play() : void;
+}
+
+trait CatTrait implements KittenInterface
+{
+ public function play() : void
+ {
+ // ...
+ }
+}
+
+class Samuel
+{
+ use CatTrait;
+}
+
+
+$cat = new Samuel();
+$cat instanceof KittenInterface === true; // True
+
+```
+
+## More Information
+
+Visit the [Hack language reference](http://docs.hhvm.com/manual/en/hacklangref.php)
+for detailed explainations of the features Hack adds to PHP, or the [official Hack website](http://hacklang.org/)
+for more general information.
+
+Visit the [official HHVM website](http://hhvm.com/) for HHVM installation instructions.
+
+Visit [Hack's unsupported PHP features article](http://docs.hhvm.com/manual/en/hack.unsupported.php)
+for details on the backwards incompatibility between Hack and PHP.
diff --git a/haskell.html.markdown b/haskell.html.markdown
index 52433aaa..2f807c5f 100644
--- a/haskell.html.markdown
+++ b/haskell.html.markdown
@@ -80,6 +80,9 @@ not False -- True
[5..1] -- This doesn't work because Haskell defaults to incrementing.
[5,4..1] -- [5, 4, 3, 2, 1]
+-- indexing into a list
+[0..] !! 5 -- 5
+
-- You can also have infinite lists in Haskell!
[1..] -- a list of all the natural numbers
@@ -99,9 +102,6 @@ not False -- True
-- adding to the head of a list
0:[1..5] -- [0, 1, 2, 3, 4, 5]
--- indexing into a list
-[0..] !! 5 -- 5
-
-- more list operations
head [1..5] -- 1
tail [1..5] -- [2, 3, 4, 5]
@@ -148,12 +148,12 @@ add 1 2 -- 3
-- Guards: an easy way to do branching in functions
fib x
- | x < 2 = x
+ | x < 2 = 1
| otherwise = fib (x - 1) + fib (x - 2)
-- Pattern matching is similar. Here we have given three different
-- definitions for fib. Haskell will automatically call the first
--- function that matches the pattern of the value.
+-- function that matches the pattern of the value.
fib 1 = 1
fib 2 = 2
fib x = fib (x - 1) + fib (x - 2)
@@ -181,7 +181,7 @@ foldl1 (\acc x -> acc + x) [1..5] -- 15
----------------------------------------------------
-- partial application: if you don't pass in all the arguments to a function,
--- it gets "partially applied". That means it returns a function that takes the
+-- it gets "partially applied". That means it returns a function that takes the
-- rest of the arguments.
add a b = a + b
@@ -319,13 +319,13 @@ Nothing -- of type `Maybe a` for any `a`
-- called. It must return a value of type `IO ()`. For example:
main :: IO ()
-main = putStrLn $ "Hello, sky! " ++ (say Blue)
+main = putStrLn $ "Hello, sky! " ++ (say Blue)
-- putStrLn has type String -> IO ()
--- It is easiest to do IO if you can implement your program as
--- a function from String to String. The function
+-- It is easiest to do IO if you can implement your program as
+-- a function from String to String. The function
-- interact :: (String -> String) -> IO ()
--- inputs some text, runs a function on it, and prints out the
+-- inputs some text, runs a function on it, and prints out the
-- output.
countLines :: String -> String
@@ -339,43 +339,43 @@ main' = interact countLines
-- the `do` notation to chain actions together. For example:
sayHello :: IO ()
-sayHello = do
+sayHello = do
putStrLn "What is your name?"
name <- getLine -- this gets a line and gives it the name "name"
putStrLn $ "Hello, " ++ name
-
+
-- Exercise: write your own version of `interact` that only reads
-- one line of input.
-
+
-- The code in `sayHello` will never be executed, however. The only
--- action that ever gets executed is the value of `main`.
--- To run `sayHello` comment out the above definition of `main`
+-- action that ever gets executed is the value of `main`.
+-- To run `sayHello` comment out the above definition of `main`
-- and replace it with:
-- main = sayHello
--- Let's understand better how the function `getLine` we just
+-- Let's understand better how the function `getLine` we just
-- used works. Its type is:
-- getLine :: IO String
-- You can think of a value of type `IO a` as representing a
--- computer program that will generate a value of type `a`
+-- computer program that will generate a value of type `a`
-- when executed (in addition to anything else it does). We can
--- store and reuse this value using `<-`. We can also
+-- store and reuse this value using `<-`. We can also
-- make our own action of type `IO String`:
action :: IO String
action = do
putStrLn "This is a line. Duh"
- input1 <- getLine
+ input1 <- getLine
input2 <- getLine
-- The type of the `do` statement is that of its last line.
- -- `return` is not a keyword, but merely a function
+ -- `return` is not a keyword, but merely a function
return (input1 ++ "\n" ++ input2) -- return :: String -> IO String
-- We can use this just like we used `getLine`:
main'' = do
putStrLn "I will echo two lines!"
- result <- action
+ result <- action
putStrLn result
putStrLn "This was all, folks!"
diff --git a/haxe.html.markdown b/haxe.html.markdown
index 8599de8d..c807d2d7 100644
--- a/haxe.html.markdown
+++ b/haxe.html.markdown
@@ -3,6 +3,7 @@ language: haxe
filename: LearnHaxe3.hx
contributors:
- ["Justin Donaldson", "https://github.com/jdonaldson/"]
+ - ["Dan Korostelev", "https://github.com/nadako/"]
---
Haxe is a web-oriented language that provides platform support for C++, C#,
@@ -34,16 +35,20 @@ references.
/*
This is your first actual haxe code coming up, it's declaring an empty
package. A package isn't necessary, but it's useful if you want to create a
- namespace for your code (e.g. org.module.ClassName).
+ namespace for your code (e.g. org.yourapp.ClassName).
+
+ Omitting package declaration is the same as declaring an empty package.
*/
package; // empty package, no namespace.
/*
- Packages define modules for your code. Each module (e.g. org.module) must
- be lower case, and should exist as a folder structure containing the class.
- Class (and type) names must be capitalized. E.g, the class "org.module.Foo"
- should have the folder structure org/module/Foo.hx, as accessible from the
- compiler's working directory or class path.
+ Packages are directories that contain modules. Each module is a .hx file
+ that contains types defined in a package. Package names (e.g. org.yourapp)
+ must be lower case while module names are capitalized. A module contain one
+ or more types whose names are also capitalized.
+
+ E.g, the class "org.yourapp.Foo" should have the folder structure org/module/Foo.hx,
+ as accessible from the compiler's working directory or class path.
If you import code from other files, it must be declared before the rest of
the code. Haxe provides a lot of common default classes to get you started:
@@ -53,6 +58,12 @@ import haxe.ds.ArraySort;
// you can import many classes/modules at once with "*"
import haxe.ds.*;
+// you can import static fields
+import Lambda.array;
+
+// you can also use "*" to import all static fields
+import Math.*;
+
/*
You can also import classes in a special way, enabling them to extend the
functionality of other classes like a "mixin". More on 'using' later.
@@ -172,7 +183,8 @@ class LearnHaxe3{
Regexes are also supported, but there's not enough space to go into
much detail.
*/
- trace((~/foobar/.match('foo')) + " is the value for (~/foobar/.match('foo')))");
+ var re = ~/foobar/;
+ trace(re.match('foo') + " is the value for (~/foobar/.match('foo')))");
/*
Arrays are zero-indexed, dynamic, and mutable. Missing values are
@@ -383,11 +395,7 @@ class LearnHaxe3{
*/
// if statements
- var k = if (true){
- 10;
- } else {
- 20;
- }
+ var k = if (true) 10 else 20;
trace("K equals ", k); // outputs 10
@@ -628,6 +636,7 @@ enum ComplexEnum{
ComplexEnumEnum(c:ComplexEnum);
}
// Note: The enum above can include *other* enums as well, including itself!
+// Note: This is what's called *Algebraic data type* in some other languages.
class ComplexEnumTest{
public static function example(){
diff --git a/java.html.markdown b/java.html.markdown
index 3dd65679..10dd498c 100644
--- a/java.html.markdown
+++ b/java.html.markdown
@@ -103,15 +103,15 @@ public class LearnJava {
// Arrays
//The array size must be decided upon instantiation
//The following formats work for declaring an array
- //<datatype> [] <var name> = new <datatype>[<array size>];
+ //<datatype>[] <var name> = new <datatype>[<array size>];
//<datatype> <var name>[] = new <datatype>[<array size>];
- int [] intArray = new int[10];
- String [] stringArray = new String[1];
- boolean boolArray [] = new boolean[100];
+ int[] intArray = new int[10];
+ String[] stringArray = new String[1];
+ boolean boolArray[] = new boolean[100];
// Another way to declare & initialize an array
- int [] y = {9000, 1000, 1337};
- String names [] = {"Bob", "John", "Fred", "Juan Pedro"};
+ int[] y = {9000, 1000, 1337};
+ String names[] = {"Bob", "John", "Fred", "Juan Pedro"};
boolean bools[] = new boolean[] {true, false, false};
// Indexing an array - Accessing an element
@@ -495,6 +495,8 @@ The links provided here below are just to get an understanding of the topic, fee
* [Head First Java](http://www.headfirstlabs.com/books/hfjava/)
+* [Thinking in Java](http://www.mindview.net/Books/TIJ/)
+
* [Objects First with Java](http://www.amazon.com/Objects-First-Java-Practical-Introduction/dp/0132492660)
* [Java The Complete Reference](http://www.amazon.com/gp/product/0071606300)
diff --git a/javascript.html.markdown b/javascript.html.markdown
index f61e6c74..588ea86d 100644
--- a/javascript.html.markdown
+++ b/javascript.html.markdown
@@ -207,7 +207,7 @@ while (true){
}
// Do-while loops are like while loops, except they always run at least once.
-var input
+var input;
do {
input = getInput();
} while (!isValid(input))
@@ -407,7 +407,7 @@ myNewObj.myNumber; // = 5
// look at its prototype.
// Some JS implementations let you access an object's prototype on the magic
-// property __proto__. While this is useful for explaining prototypes it's not
+// property `__proto__`. While this is useful for explaining prototypes it's not
// part of the standard; we'll get to standard ways of using prototypes later.
var myObj = {
myString: "Hello world!"
@@ -438,7 +438,7 @@ myObj.myBoolean; // = true
myPrototype.meaningOfLife = 43;
myObj.meaningOfLife; // = 43
-// We mentioned that __proto__ was non-standard, and there's no standard way to
+// We mentioned that `__proto__` was non-standard, and there's no standard way to
// change the prototype of an existing object. However, there are two ways to
// create a new object with a given prototype.
diff --git a/nim.html.markdown b/nim.html.markdown
index c74fece7..aa15e591 100644
--- a/nim.html.markdown
+++ b/nim.html.markdown
@@ -3,14 +3,15 @@ language: Nim
filename: learnNim.nim
contributors:
- ["Jason J. Ayala P.", "http://JasonAyala.com"]
+ - ["Dennis Felsing", "http://felsin9.de/nnis/"]
---
-Nim (formally Nimrod) is a statically typed, imperative programming language
+Nim (formerly Nimrod) is a statically typed, imperative programming language
that gives the programmer power without compromises on runtime efficiency.
Nim is efficient, expressive, and elegant.
-```ruby
+```nimrod
var # Declare (and assign) variables,
letter: char = 'n' # with or without type annotations
lang = "N" & "im"
@@ -60,6 +61,13 @@ var
drinks = @["Water", "Juice", "Chocolate"] # @[V1,..,Vn] is the sequence literal
+drinks.add("Milk")
+
+if "Milk" in drinks:
+ echo "We have Milk and ", drinks.len - 1, " other drinks"
+
+let myDrink = drinks[2]
+
#
# Defining Types
#
@@ -261,5 +269,5 @@ performance, and compile-time features.
* [FAQ](http://nimrod-lang.org/question.html)
* [Documentation](http://nimrod-lang.org/documentation.html)
* [Manual](http://nimrod-lang.org/manual.html)
-* [Standard Libray](http://nimrod-lang.org/lib.html)
+* [Standard Library](http://nimrod-lang.org/lib.html)
* [Rosetta Code](http://rosettacode.org/wiki/Category:Nimrod)
diff --git a/perl6.html.markdown b/perl6.html.markdown
index 72faecb6..1b320028 100644
--- a/perl6.html.markdown
+++ b/perl6.html.markdown
@@ -201,7 +201,7 @@ sub mutate($n is rw) {
my $x = 42;
sub x-store() is rw { $x }
x-store() = 52; # in this case, the parentheses are mandatory
- # (else Perl 6 thinks `mod` is an identifier)
+ # (else Perl 6 thinks `x-store` is an identifier)
say $x; #=> 52
@@ -283,7 +283,7 @@ for @array -> $variable {
}
# As we saw with given, for's default "current iteration" variable is `$_`.
-# That means you can use `when` in a `for` just like you were in a when.
+# That means you can use `when` in a `for` just like you were in a `given`.
for @array {
say "I've got $_";
@@ -963,7 +963,7 @@ say join ',', gather if False {
# But consider:
constant thrice = gather for ^3 { say take $_ }; # Doesn't print anything
# versus:
-constant thrice = eager gather for ^3 { say take $_ }; #=> 0 1 2 3 4
+constant thrice = eager gather for ^3 { say take $_ }; #=> 0 1 2
# - `lazy` - Defer actual evaluation until value is fetched (forces lazy context)
# Not yet implemented !!
diff --git a/pt-br/brainfuck-pt.html.markdown b/pt-br/brainfuck-pt.html.markdown
new file mode 100644
index 00000000..72c2cf6e
--- /dev/null
+++ b/pt-br/brainfuck-pt.html.markdown
@@ -0,0 +1,84 @@
+---
+language: brainfuck
+contributors:
+ - ["Prajit Ramachandran", "http://prajitr.github.io/"]
+ - ["Mathias Bynens", "http://mathiasbynens.be/"]
+translators:
+ - ["Suzane Sant Ana", "http://github.com/suuuzi"]
+lang: pt-pt
+---
+
+Brainfuck (em letras minúsculas, eceto no início de frases) é uma linguagem de
+programação Turing-completa extremamente simples com apenas 8 comandos.
+
+```
+Qualquer caractere exceto "><+-.,[]" (sem contar as aspas) é ignorado.
+
+Brainfuck é representado por um vetor com 30 000 células inicializadas em zero
+e um ponteiro de dados que aponta para a célula atual.
+
+Existem 8 comandos:
++ : Incrementa o vaor da célula atual em 1.
+- : Decrementa o valor da célula atual em 1.
+> : Move o ponteiro de dados para a célula seguinte (célula à direita).
+< : Move o ponteiro de dados para a célula anterior (célula à esquerda).
+. : Imprime o valor ASCII da célula atual. (ex. 65 = 'A').
+, : Lê um único caractere para a célula atual.
+[ : Se o valor da célula atual for zero, salta para o ] correspondente.
+ Caso contrário, passa para a instrução seguinte.
+] : Se o valor da célula atual for zero, passa para a instrução seguinte.
+ Caso contrário, volta para a instrução relativa ao [ correspondente.
+
+[ e ] formam um ciclo while. Obviamente, devem ser equilibrados.
+
+Vamos ver alguns exemplos básicos em brainfuck:
+
+++++++ [ > ++++++++++ < - ] > +++++ .
+
+Este programa imprime a letra 'A'. Primeiro incrementa a célula #1 para 6.
+A célula #1 será usada num ciclo. Depois é iniciado o ciclo ([) e move-se
+o ponteiro de dados para a célula #2. O valor da célula #2 é incrementado 10
+vezes, move-se o ponteiro de dados de volta para a célula #1, e decrementa-se
+a célula #1. Este ciclo acontece 6 vezes (são necessários 6 decrementos para
+a célula #1 chegar a 0, momento em que se salta para o ] correspondente,
+continuando com a instrução seguinte).
+
+Nesta altura estamos na célula #1, cujo valor é 0, enquanto a célula #2
+tem o valor 60. Movemos o ponteiro de dados para a célula #2, incrementa-se 5
+vezes para um valor final de 65, e então é impresso o valor da célula #2. O valor
+65 corresponde ao caractere 'A' em ASCII, então 'A' é impresso no terminal.
+
+, [ > + < - ] > .
+
+Este programa lê um caractere e copia o seu valor para a célula #1. Um ciclo é
+iniciado. Movemos o ponteiro de dados para a célula #2, incrementamos o valor na
+célula #2, movemos o ponteiro de dados de volta para a célula #1 e finalmente
+decrementamos o valor na célula #1. Isto continua até o valor na célula #1 ser
+igual a 0 e a célula #2 ter o antigo valor da célula #1. Como o ponteiro de
+dados está apontando para a célula #1 no fim do ciclo, movemos o ponteiro para a
+célula #2 e imprimimos o valor em ASCII.
+
+Os espaços servem apenas para tornar o programa mais legível. Podemos escrever
+o mesmo programa da seguinte maneira:
+
+,[>+<-]>.
+
+Tente descobrir o que este programa faz:
+
+,>,< [ > [ >+ >+ << -] >> [- << + >>] <<< -] >>
+
+Este programa lê dois números e os multiplica.
+
+Basicamente o programa pede dois caracteres ao usuário. Depois é iniciado um
+ciclo exterior controlado pelo valor da célula #1. Movemos o ponteiro de dados
+para a célula #2 e inicia-se o ciclo interior controlado pelo valor da célula
+#2, incrementando o valor da célula #3. Porém existe um problema, no final do
+ciclo interior: a célula #2 tem o valor 0. Para resolver este problema o valor da
+célula #4 é também incrementado e copiado para a célula #2.
+```
+
+E isto é brainfuck. Simples, não? Por divertimento você pode escrever os
+seus próprios programas em brainfuck, ou então escrever um interpretador de
+brainfuck em outra linguagem. O interpretador é relativamente fácil de se
+implementar, mas caso você seja masoquista, tente escrever um interpretador de
+brainfuck… em brainfuck.
diff --git a/pt-br/git-pt.html.markdown b/pt-br/git-pt.html.markdown
index 6d2a55cd..b8cbd0a9 100644
--- a/pt-br/git-pt.html.markdown
+++ b/pt-br/git-pt.html.markdown
@@ -1,110 +1,119 @@
---
category: tool
tool: git
+lang: pt-pt
+filename: LearnGit.txt
contributors:
- ["Jake Prather", "http://github.com/JakeHP"]
translators:
- - ["Miguel Araújo", "https://github.com/miguelarauj1o"]
-lang: pt-br
-filename: learngit-pt.txt
+ - ["Suzane Sant Ana", "http://github.com/suuuzi"]
---
-Git é um sistema de controle de versão distribuído e de gerenciamento de código-fonte.
+Git é um sistema distribuido de gestão para código fonte e controle de versões.
-Ele faz isso através de uma série de momentos instantâneos de seu projeto, e ele funciona
-com esses momentos para lhe fornecer a funcionalidade para a versão e
-gerenciar o seu código-fonte.
+Funciona através de uma série de registos de estado do projeto e usa esse
+registo para permitir funcionalidades de versionamento e gestão de código
+fonte.
-## Versionando Conceitos
+## Conceitos de versionamento
-### O que é controle de versão?
+### O que é controle de versão
-O controle de versão é um sistema que registra alterações em um arquivo ou conjunto
-de arquivos, ao longo do tempo.
+Controle de versão (*source control*) é um processo de registo de alterações
+a um arquivo ou conjunto de arquivos ao longo do tempo.
-### Versionamento Centralizado VS Versionamento Distribuído
+### Controle de versão: Centralizado VS Distribuído
-* Controle de versão centralizado concentra-se na sincronização, controle e backup de arquivos.
-* Controle de versão distribuído concentra-se na partilha de mudanças. Toda mudança tem um ID único.
-* Sistemas Distribuídos não têm estrutura definida. Você poderia facilmente ter um estilo SVN,
-sistema centralizado, com git.
+* Controle de versão centralizado foca na sincronização, registo e *backup*
+de arquivos.
+* Controle de versão distribuído foca em compartilhar alterações. Cada
+alteração é associada a um *id* único.
+* Sistemas distribuídos não tem estrutura definida. É possivel ter um sistema
+centralizado ao estilo SVN usando git.
-[Informação Adicional](http://git-scm.com/book/en/Getting-Started-About-Version-Control)
+[Informação adicional (EN)](http://git-scm.com/book/en/Getting-Started-About-Version-Control)
-### Porque usar o Git?
+### Por que usar git?
-* Possibilidade de trabalhar offline
-* Colaborar com os outros é fácil!
-* Ramificação é fácil
-* Mesclagem é fácil
-* Git é rápido
-* Git é flexível.
+* Permite trabalhar offline.
+* Colaborar com outros é fácil!
+* Criar *branches* é fácil!
+* Fazer *merge* é fácil!
+* Git é rápido.
+* Git é flexivel.
+
+## Git - Arquitetura
-## Arquitetura Git
### Repositório
-Um conjunto de arquivos, diretórios, registros históricos, cometes, e cabeças. Imagine-o
-como uma estrutura de dados de código-fonte, com o atributo que cada "elemento" do
-código-fonte dá-lhe acesso ao seu histórico de revisão, entre outras coisas.
+Um conjunto de arquivos, diretórios, registos históricos, *commits* e
+referências. Pode ser descrito como uma estrutura de dados de código fonte
+com a particularidade de cada elemento do código fonte permitir acesso ao
+histórico das suas alterações, entre outras coisas.
-Um repositório git é composto do diretório git. e árvore de trabalho.
+Um repositório git é constituido pelo diretório .git e a *working tree*
### Diretório .git (componente do repositório)
-O diretório git. contém todas as configurações, registros, galhos, cabeça(HEAD) e muito mais.
-[Lista Detalhada](http://gitready.com/advanced/2009/03/23/whats-inside-your-git-directory.html)
+O repositório .git contém todas as configurações, *logs*, *branches*,
+referências e outros.
+
+[Lista detalhada (EN)](http://gitready.com/advanced/2009/03/23/whats-inside-your-git-directory.html)
-### Árvore de trabalho (componente do repositório)
+### *Working Tree* (componente do repositório)
-Esta é, basicamente, os diretórios e arquivos no seu repositório. Ele é muitas vezes referida
-como seu diretório de trabalho.
+A *Working Tree* é basicamente a listagem dos diretórios e arquivos do repositório. É chamada também de diretório do projeto.
-### Índice (componente do diretório .git)
+### *Index* (componente do diretório .git)
-O Índice é a área de teste no git. É basicamente uma camada que separa a sua árvore de trabalho
-a partir do repositório Git. Isso dá aos desenvolvedores mais poder sobre o que é enviado para o
-repositório Git.
+O *Index* é a camada da interface no git. É o elemento que separa
+o diretório do projeto do repositório git. Isto permite aos programadores um
+maior controle sobre o que é registado no repositório git.
-### Comete (commit)
+### *Commit*
-A commit git é um instantâneo de um conjunto de alterações ou manipulações a sua árvore de trabalho.
-Por exemplo, se você adicionou 5 imagens, e removeu outros dois, estas mudanças serão contidas
-em um commit (ou instantâneo). Esta confirmação pode ser empurrado para outros repositórios, ou não!
+Um *commit** de git é um registo de um cojunto de alterações ou manipulações nos arquivos do projeto.
+Por exemplo, ao adicionar cinco arquivos e remover outros 2, estas alterações
+serão gravadas num *commit* (ou registo). Este *commit* pode então ser enviado
+para outros repositórios ou não!
-### Ramo (branch)
+### *Branch*
-Um ramo é, essencialmente, um ponteiro que aponta para o último commit que você fez. Como
-você se comprometer, este ponteiro irá atualizar automaticamente e apontar para o último commit.
+Um *branch* é essencialmente uma referência que aponta para o último *commit*
+efetuado. Na medida que são feitos novos commits, esta referência é atualizada
+automaticamente e passa a apontar para o commit mais recente.
-### Cabeça (HEAD) e cabeça (head) (componente do diretório .git)
+### *HEAD* e *head* (componentes do diretório .git)
-HEAD é um ponteiro que aponta para o ramo atual. Um repositório tem apenas 1 * ativo * HEAD.
-head é um ponteiro que aponta para qualquer commit. Um repositório pode ter qualquer número de commits.
+*HEAD* é a referência que aponta para o *branch* em uso. Um repositório só tem
+uma *HEAD* activa.
+*head* é uma referência que aponta para qualquer *commit*. Um repositório pode
+ter um número indefinido de *heads*
-### Recursos Conceituais
+### Recursos conceituais (EN)
-* [Git para Cientistas da Computação](http://eagain.net/articles/git-for-computer-scientists/)
+* [Git para Cientistas de Computação](http://eagain.net/articles/git-for-computer-scientists/)
* [Git para Designers](http://hoth.entp.com/output/git_for_designers.html)
## Comandos
-### init
+### *init*
-Criar um repositório Git vazio. As configurações do repositório Git, informações armazenadas,
-e mais são armazenados em um diretório (pasta) com o nome ". git".
+Cria um repositório Git vazio. As definições, informação guardada e outros do
+repositório git são guardados em uma pasta chamada ".git".
```bash
$ git init
```
-### config
+### *config*
-Para configurar as definições. Quer seja para o repositório, o próprio sistema, ou
-configurações globais.
+Permite configurar as definições, sejam as definições do repositório, sistema
+ou configurações globais.
```bash
-# Impressão e definir algumas variáveis ​​de configuração básica (global)
+# Imprime e define algumas variáveis de configuração básicas (global)
$ git config --global user.email
$ git config --global user.name
@@ -112,22 +121,21 @@ $ git config --global user.email "MyEmail@Zoho.com"
$ git config --global user.name "My Name"
```
-[Saiba mais sobre o git config.](http://git-scm.com/docs/git-config)
+[Aprenda mais sobre git config. (EN)](http://git-scm.com/docs/git-config)
### help
-Para lhe dar um acesso rápido a um guia extremamente detalhada de cada comando. ou
-apenas dar-lhe um rápido lembrete de algumas semânticas.
+Para visualizar rapidamente o detalhamento de cada comando ou apenas lembrar da semântica.
```bash
-# Rapidamente verificar os comandos disponíveis
+# Ver rapidamente os comandos disponiveis
$ git help
-# Confira todos os comandos disponíveis
+# Ver todos os comandos disponiveis
$ git help -a
-# Ajuda específica de comando - manual do usuário
-# git help <command_here>
+# Usar o *help* para um comando especifico
+# git help <comando_aqui>
$ git help add
$ git help commit
$ git help init
@@ -135,85 +143,89 @@ $ git help init
### status
-Para mostrar as diferenças entre o arquivo de índice (basicamente o trabalho de
-copiar/repo) e a HEAD commit corrente.
+Apresenta as diferenças entre o arquivo *index* (a versão corrente
+do repositório) e o *commit* da *HEAD* atual.
+
```bash
-# Irá exibir o ramo, os arquivos não monitorados, as alterações e outras diferenças
+# Apresenta o *branch*, arquivos não monitorados, alterações e outras
+# difereças
$ git status
-# Para saber outras "tid bits" sobre git status
+# Para aprender mais detalhes sobre git *status*
$ git help status
```
### add
-Para adicionar arquivos para a atual árvore/directory/repo trabalho. Se você não
-der `git add` nos novos arquivos para o trabalhando árvore/diretório, eles não serão
-incluídos em commits!
+Adiciona arquivos ao repositório corrente. Se os arquivos novos não forem
+adicionados através de `git add` ao repositório, então eles não serão
+incluidos nos commits!
```bash
-# Adicionar um arquivo no seu diretório de trabalho atual
+# adiciona um arquivo no diretório do projeto atual
$ git add HelloWorld.java
-# Adicionar um arquivo em um diretório aninhado
+# adiciona um arquivo num sub-diretório
$ git add /path/to/file/HelloWorld.c
-# Suporte a expressões regulares!
+# permite usar expressões regulares!
$ git add ./*.java
```
### branch
-Gerenciar seus ramos. Você pode visualizar, editar, criar, apagar ramos usando este comando.
+Gerencia os *branches*. É possível ver, editar, criar e apagar branches com este
+comando.
```bash
-# Lista ramos e controles remotos existentes
+# listar *branches* existentes e remotos
$ git branch -a
-# Criar um novo ramo
+# criar um novo *branch*
$ git branch myNewBranch
-# Apagar um ramo
+# apagar um *branch*
$ git branch -d myBranch
-# Renomear um ramo
+# alterar o nome de um *branch*
# git branch -m <oldname> <newname>
$ git branch -m myBranchName myNewBranchName
-# Editar a descrição de um ramo
+# editar a descrição de um *branch*
$ git branch myBranchName --edit-description
```
### checkout
-Atualiza todos os arquivos na árvore de trabalho para corresponder à versão no
-índice, ou árvore especificada.
+Atualiza todos os arquivos no diretório do projeto para que fiquem iguais
+à versão do index ou do *branch* especificado.
```bash
-# Finalizar um repo - padrão de ramo mestre
+# Checkout de um repositório - por padrão para o branch master
$ git checkout
-# Checa um ramo especificado
+# Checkout de um branch especifico
$ git checkout branchName
-# Criar um novo ramo e mudar para ela, como: "<nome> git branch; git checkout <nome>"
+# Cria um novo branch e faz checkout para ele.
+# Equivalente a: "git branch <name>; git checkout <name>"
$ git checkout -b newBranch
```
### clone
-Clones, ou cópias, de um repositório existente para um novo diretório. Ele também adiciona
-filiais remotas de rastreamento para cada ramo no repo clonado, que permite que você empurre
-a um ramo remoto.
+Clona ou copia um repositório existente para um novo diretório. Também
+adiciona *branches* de monitoramento remoto para cada *branch* no repositório
+clonado o que permite enviar alterações para um *branch* remoto.
```bash
-# Clone learnxinyminutes-docs
+# Clona learnxinyminutes-docs
$ git clone https://github.com/adambard/learnxinyminutes-docs.git
```
### commit
-Armazena o conteúdo atual do índice em um novo "commit". Este commit contém
-as alterações feitas e uma mensagem criada pelo utilizador.
+Guarda o conteudo atual do index num novo *commit*. Este *commit* contém
+as alterações feitas e a mensagem criada pelo usuário.
```bash
# commit com uma mensagem
@@ -222,170 +234,170 @@ $ git commit -m "Added multiplyNumbers() function to HelloWorld.c"
### diff
-Mostra as diferenças entre um arquivo no diretório, o índice de trabalho e commits.
+Apresenta as diferenças entre um arquivo no repositório do projeto, *index*
+e *commits*
```bash
-# Mostrar diferença entre o seu diretório de trabalho e o índice.
+# Apresenta a diferença entre o diretório atual e o index
$ git diff
-# Mostrar diferenças entre o índice e o commit mais recente.
+# Apresenta a diferença entre o index e os commits mais recentes
$ git diff --cached
-# Mostrar diferenças entre o seu diretório de trabalho e o commit mais recente.
+# Apresenta a diferença entre o diretório atual e o commit mais recente
$ git diff HEAD
```
### grep
-Permite procurar rapidamente um repositório.
+Permite procurar facilmente num repositório
Configurações opcionais:
```bash
-# Obrigado ao Travis Jeffery por isto
-# Configure os números de linha a serem mostrados nos resultados de busca grep
+# Define a apresentação de números de linha nos resultados do grep
$ git config --global grep.lineNumber true
-# Fazer resultados de pesquisa mais legível, incluindo agrupamento
+# Agrupa os resultados da pesquisa para facilitar a leitura
$ git config --global alias.g "grep --break --heading --line-number"
```
```bash
-# Procure por "variableName" em todos os arquivos java
+# Pesquisa por "variableName" em todos os arquivos java
$ git grep 'variableName' -- '*.java'
-# Procure por uma linha que contém "arrayListName" e "adicionar" ou "remover"
-$ git grep -e 'arrayListName' --and \( -e add -e remove \)
+# Pesquisa por uma linha que contém "arrayListName" e "add" ou "remove"
+$ git grep -e 'arrayListName' --and \( -e add -e remove \)
```
-Google é seu amigo; para mais exemplos
-[Git Grep Ninja](http://travisjeffery.com/b/2012/02/search-a-git-repo-like-a-ninja)
+O Google é seu amigo; para mais exemplos:
+[Git Grep Ninja (EN)](http://travisjeffery.com/b/2012/02/search-a-git-repo-like-a-ninja)
### log
-Mostrar commits para o repositório.
+Apresenta commits do repositório.
```bash
-# Mostrar todos os commits
+# Apresenta todos os commits
$ git log
-# Mostrar um número X de commits
+# Apresenta X commits
$ git log -n 10
-# Mostrar somente commits mesclados
+# Apresenta apenas commits de merge
$ git log --merges
```
### merge
-"Merge" em mudanças de commits externos no branch atual.
+"Merge" junta as alterações de commits externos com o *branch* atual.
```bash
-# Mesclar o ramo especificado para o atual.
+# Junta o branch especificado com o atual
$ git merge branchName
-# Gera sempre uma mesclagem commit ao mesclar
+# Para gerar sempre um commit ao juntar os branches
$ git merge --no-ff branchName
```
### mv
-Renomear ou mover um arquivo
+Alterar o nome ou mover um arquivo.
```bash
-# Renomear um arquivo
+# Alterar o nome de um arquivo
$ git mv HelloWorld.c HelloNewWorld.c
# Mover um arquivo
$ git mv HelloWorld.c ./new/path/HelloWorld.c
-# Força renomear ou mover
-# "ExistingFile" já existe no diretório, será substituído
+# Forçar a alteração de nome ou mudança local
+# "existingFile" já existe no directório, será sobrescrito.
$ git mv -f myFile existingFile
```
### pull
-Puxa de um repositório e se funde com outro ramo.
+Puxa alterações de um repositório e as junta com outro branch
```bash
-# Atualize seu repo local, através da fusão de novas mudanças
-# A partir da "origem" remoto e ramo "master (mestre)".
+# Atualiza o repositório local, juntando as novas alterações
+# do repositório remoto 'origin' e branch 'master'
# git pull <remote> <branch>
-# git pull => implícito por padrão => git pull origin master
+# git pull => aplica a predefinição => git pull origin master
$ git pull origin master
-# Mesclar em mudanças de ramo remoto e rebase
-# Ramo commita em seu repo local, como: "git pull <remote> <branch>, git rebase <branch>"
+# Juntar alterações do branch remote e fazer rebase commits do branch
+# no repositório local, como: "git pull <remote> <branch>, git rebase <branch>"
$ git pull origin master --rebase
```
### push
-Empurre e mesclar as alterações de uma ramificação para uma remota e ramo.
+Enviar e juntar alterações de um branch para o seu branch correspondente
+num repositório remoto.
```bash
-# Pressione e mesclar as alterações de um repo local para um
-# Chamado remoto "origem" e ramo de "mestre".
+# Envia e junta as alterações de um repositório local
+# para um remoto denominado "origin" no branch "master".
# git push <remote> <branch>
-# git push => implícito por padrão => git push origin master
+# git push => aplica a predefinição => git push origin master
$ git push origin master
-
-# Para ligar atual filial local com uma filial remota, bandeira add-u:
-$ git push -u origin master
-# Agora, a qualquer hora que você quer empurrar a partir desse mesmo ramo local, uso de atalho:
-$ git push
```
-### rebase (CAUTELA)
+### rebase (cautela!)
-Tire todas as alterações que foram commitadas em um ramo, e reproduzi-las em outro ramo.
-* Não rebase commits que você tenha empurrado a um repo público *.
+Pega em todas as alterações que foram registadas num branch e volta a
+aplicá-las em outro branch.
+*Não deve ser feito rebase de commits que foram enviados para um repositório
+público*
```bash
-# Rebase experimentBranch para mestre
+# Faz Rebase de experimentBranch para master
# git rebase <basebranch> <topicbranch>
$ git rebase master experimentBranch
```
-[Leitura Adicional.](http://git-scm.com/book/en/Git-Branching-Rebasing)
+[Leitura adicional (EN).](http://git-scm.com/book/en/Git-Branching-Rebasing)
-### reset (CAUTELA)
+### reset (cuidado!)
-Repor o atual HEAD de estado especificado. Isto permite-lhe desfazer fusões (merge),
-puxa (push), commits, acrescenta (add), e muito mais. É um grande comando, mas também
-perigoso se não saber o que se está fazendo.
+Restabelece a HEAD atual ao estado definido. Isto permite reverter *merges*,
+*pulls*, *commits*, *adds* e outros. É um comando muito poderoso mas também
+perigoso quando não há certeza do que se está fazendo.
```bash
-# Repor a área de teste, para coincidir com o último commit (deixa diretório inalterado)
+# Restabelece a camada intermediária de registo para o último
+# commit (o directório fica sem alterações)
$ git reset
-# Repor a área de teste, para coincidir com o último commit, e substituir diretório trabalhado
+# Restabelece a camada intermediária de registo para o último commit, e
+# sobrescreve o projeto atual
$ git reset --hard
-# Move a ponta ramo atual para o especificado commit (deixa diretório inalterado)
-# Todas as alterações ainda existem no diretório.
+# Move a head do branch atual para o commit especificado, sem alterar o projeto.
+# todas as alterações ainda existem no projeto
$ git reset 31f2bb1
-# Move a ponta ramo atual para trás, para o commit especificado
-# E faz o jogo dir trabalho (exclui mudanças não commitadas e todos os commits
-# Após o commit especificado).
+# Inverte a head do branch atual para o commit especificado
+# fazendo com que este esteja em sintonia com o diretório do projeto
+# Remove alterações não registadas e todos os commits após o commit especificado
$ git reset --hard 31f2bb1
```
### rm
-O oposto do git add, git rm remove arquivos da atual árvore de trabalho.
+O oposto de git add, git rm remove arquivos do branch atual.
```bash
# remove HelloWorld.c
$ git rm HelloWorld.c
-# Remove um arquivo de um diretório aninhado
+# Remove um arquivo de um sub-directório
$ git rm /pather/to/the/file/HelloWorld.c
```
-# # Mais informações
+## Informação complementar (EN)
* [tryGit - A fun interactive way to learn Git.](http://try.github.io/levels/1/challenges/1)
@@ -398,5 +410,3 @@ $ git rm /pather/to/the/file/HelloWorld.c
* [SalesForce Cheat Sheet](https://na1.salesforce.com/help/doc/en/salesforce_git_developer_cheatsheet.pdf)
* [GitGuys](http://www.gitguys.com/)
-
-* [Git - guia prático](http://rogerdudler.github.io/git-guide/index.pt_BR.html) \ No newline at end of file
diff --git a/pt-pt/git-pt.html.markdown b/pt-pt/git-pt.html.markdown
index 66cda07f..a85c9704 100644
--- a/pt-pt/git-pt.html.markdown
+++ b/pt-pt/git-pt.html.markdown
@@ -74,8 +74,7 @@ maior controlo sobre o que é registado no repositório git.
### *Commit*
-Um *commit** de git é um registo de um cojunto de alterações ou manipulações
-no nos ficheiros do projecto.
+Um *commit** de git é um registo de um cojunto de alterações ou manipulações nos ficheiros do projecto.
Por exemplo, ao adicionar cinco ficheiros e remover outros 2, estas alterações
serão gravadas num *commit* (ou registo). Este *commit* pode então ser enviado
para outros repositórios ou não!
@@ -83,7 +82,7 @@ para outros repositórios ou não!
### *Branch*
Um *branch* é essencialmente uma referência que aponta para o último *commit*
-efetuado. à medida que são feitos novos commits, esta referência é atualizada
+efetuado. À medida que são feitos novos commits, esta referência é atualizada
automaticamente e passa a apontar para o commit mais recente.
### *HEAD* e *head* (componentes do directório .git)
@@ -115,7 +114,7 @@ Permite configurar as definições, sejam as definições do repositório, siste
ou configurações globais.
```bash
-# Imprime & Define Algumas Variáveis de Configuração Básicas (Global)
+# Imprime e define algumas variáveis de configuração básicas (global)
$ git config --global user.email
$ git config --global user.name
@@ -123,7 +122,7 @@ $ git config --global user.email "MyEmail@Zoho.com"
$ git config --global user.name "My Name"
```
-[Aprenda Mais Sobre git config. (EN)](http://git-scm.com/docs/git-config)
+[Aprenda mais sobre git config. (EN)](http://git-scm.com/docs/git-config)
### help
@@ -166,7 +165,7 @@ adicionados através de `git add` ao repositório, então eles não serão
incluidos nos commits!
```bash
-# adiciona um ficheiro no directório do project atual
+# adiciona um ficheiro no directório do projecto atual
$ git add HelloWorld.java
# adiciona um ficheiro num sub-directório
@@ -371,7 +370,7 @@ Restabelece a HEAD atual ao estado definido. Isto permite reverter *merges*,
perigoso se não há certeza quanto ao que se está a fazer.
```bash
-# Restabelece a camada intermediária dr registo para o último
+# Restabelece a camada intermediária de registo para o último
# commit (o directório fica sem alterações)
$ git reset
diff --git a/python.html.markdown b/python.html.markdown
index da04d381..478804cd 100644
--- a/python.html.markdown
+++ b/python.html.markdown
@@ -14,7 +14,7 @@ executable pseudocode.
Feedback would be highly appreciated! You can reach me at [@louiedinh](http://twitter.com/louiedinh) or louiedinh [at] [google's email service]
Note: This article applies to Python 2.7 specifically, but should be applicable
-to Python 2.x. For Python 3.x, take a look at the Python 3 tutorial.
+to Python 2.x. For Python 3.x, take a look at the [Python 3 tutorial](http://learnxinyminutes.com/docs/python3/).
```python
diff --git a/python3.html.markdown b/python3.html.markdown
index 6b1d3156..56126ad3 100644
--- a/python3.html.markdown
+++ b/python3.html.markdown
@@ -13,7 +13,7 @@ executable pseudocode.
Feedback would be highly appreciated! You can reach me at [@louiedinh](http://twitter.com/louiedinh) or louiedinh [at] [google's email service]
-Note: This article applies to Python 3 specifically. Check out the other tutorial if you want to learn the old Python 2.7
+Note: This article applies to Python 3 specifically. Check out [here](http://learnxinyminutes.com/docs/python/) if you want to learn the old Python 2.7
```python
@@ -276,7 +276,7 @@ empty_set = set()
# Initialize a set with a bunch of values. Yeah, it looks a bit like a dict. Sorry.
some_set = {1, 1, 2, 2, 3, 4} # some_set is now {1, 2, 3, 4}
-#Can set new variables to a set
+# Can set new variables to a set
filled_set = some_set
# Add one more item to the set
@@ -394,7 +394,6 @@ our_iterator.__next__() # Raises StopIteration
list(filled_dict.keys()) #=> Returns ["one", "two", "three"]
-
####################################################
## 4. Functions
####################################################
@@ -410,7 +409,6 @@ add(5, 6) # => prints out "x is 5 and y is 6" and returns 11
# Another way to call functions is with keyword arguments
add(y=6, x=5) # Keyword arguments can arrive in any order.
-
# You can define functions that take a variable number of
# positional arguments
def varargs(*args):
@@ -418,7 +416,6 @@ def varargs(*args):
varargs(1, 2, 3) # => (1, 2, 3)
-
# You can define functions that take a variable number of
# keyword arguments, as well
def keyword_args(**kwargs):
@@ -501,7 +498,9 @@ class Human(object):
# Basic initializer, this is called when this class is instantiated.
# Note that the double leading and trailing underscores denote objects
# or attributes that are used by python but that live in user-controlled
- # namespaces. You should not invent such names on your own.
+ # namespaces. Methods(or objects or attributes) like: __init__, __str__,
+ # __repr__ etc. are called magic methods (or sometimes called dunder methods)
+ # You should not invent such names on your own.
def __init__(self, name):
# Assign the argument to the instance's name attribute
self.name = name
@@ -636,6 +635,7 @@ print(say(say_please=True)) # Can you buy me a beer? Please! I am poor :(
* [The Official Docs](http://docs.python.org/3/)
* [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/)
* [A Crash Course in Python for Scientists](http://nbviewer.ipython.org/5920182)
+* [Python Course](http://www.python-course.eu/index.php)
### Dead Tree
diff --git a/racket.html.markdown b/racket.html.markdown
index 6abc8759..e345db8b 100644
--- a/racket.html.markdown
+++ b/racket.html.markdown
@@ -7,6 +7,7 @@ contributors:
- ["Eli Barzilay", "https://github.com/elibarzilay"]
- ["Gustavo Schmidt", "https://github.com/gustavoschmidt"]
- ["Duong H. Nguyen", "https://github.com/cmpitg"]
+ - ["Keyan Zhang", "https://github.com/keyanzhang"]
---
Racket is a general purpose, multi-paradigm programming language in the Lisp/Scheme family.
@@ -282,16 +283,49 @@ m ; => '#hash((b . 2) (a . 1) (c . 3)) <-- no `d'
;; for numbers use `='
(= 3 3.0) ; => #t
-(= 2 1) ; => #f
+(= 2 1) ; => #f
+
+;; `eq?' returns #t if 2 arguments refer to the same object (in memory),
+;; #f otherwise.
+;; In other words, it's a simple pointer comparison.
+(eq? '() '()) ; => #t, since there exists only one empty list in memory
+(let ([x '()] [y '()])
+ (eq? x y)) ; => #t, same as above
-;; for object identity use `eq?'
-(eq? 3 3) ; => #t
-(eq? 3 3.0) ; => #f
(eq? (list 3) (list 3)) ; => #f
+(let ([x (list 3)] [y (list 3)])
+ (eq? x y)) ; => #f — not the same list in memory!
+
+(let* ([x (list 3)] [y x])
+ (eq? x y)) ; => #t, since x and y now point to the same stuff
+
+(eq? 'yes 'yes) ; => #t
+(eq? 'yes 'no) ; => #f
+
+(eq? 3 3) ; => #t — be careful here
+ ; It’s better to use `=' for number comparisons.
+(eq? 3 3.0) ; => #f
+
+(eq? (expt 2 100) (expt 2 100)) ; => #f
+(eq? (integer->char 955) (integer->char 955)) ; => #f
+
+(eq? (string-append "foo" "bar") (string-append "foo" "bar")) ; => #f
+
+;; `eqv?' supports the comparison of number and character datatypes.
+;; for other datatypes, `eqv?' and `eq?' return the same result.
+(eqv? 3 3.0) ; => #f
+(eqv? (expt 2 100) (expt 2 100)) ; => #t
+(eqv? (integer->char 955) (integer->char 955)) ; => #t
+
+(eqv? (string-append "foo" "bar") (string-append "foo" "bar")) ; => #f
-;; for collections use `equal?'
-(equal? (list 'a 'b) (list 'a 'b)) ; => #t
-(equal? (list 'a 'b) (list 'b 'a)) ; => #f
+;; `equal?' supports the comparison of the following datatypes:
+;; strings, byte strings, pairs, mutable pairs, vectors, boxes,
+;; hash tables, and inspectable structures.
+;; for other datatypes, `equal?' and `eqv?' return the same result.
+(equal? 3 3.0) ; => #f
+(equal? (string-append "foo" "bar") (string-append "foo" "bar")) ; => #t
+(equal? (list 3) (list 3)) ; => #t
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 5. Control Flow
diff --git a/ru-ru/lua-ru.html.markdown b/ru-ru/lua-ru.html.markdown
index 6f515975..da9ced6a 100644
--- a/ru-ru/lua-ru.html.markdown
+++ b/ru-ru/lua-ru.html.markdown
@@ -1,5 +1,5 @@
---
-language: lua
+language: Lua
filename: learnlua-ru.lua
contributors:
- ["Tyler Neylon", "http://tylerneylon.com/"]
diff --git a/ru-ru/swift-ru.html.markdown b/ru-ru/swift-ru.html.markdown
index ab1b3434..77987bb3 100644
--- a/ru-ru/swift-ru.html.markdown
+++ b/ru-ru/swift-ru.html.markdown
@@ -3,6 +3,7 @@ language: swift
contributors:
- ["Grant Timmerman", "http://github.com/grant"]
- ["Christopher Bess", "http://github.com/cbess"]
+ - ["Joey Huang", "http://github.com/kamidox"]
filename: learnswift-ru.swift
translators:
- ["Dmitry Bessonov", "https://github.com/TheDmitry"]
@@ -402,6 +403,35 @@ if mySquare === mySquare {
println("Ага, это mySquare")
}
+// Опциональная инициализация (init)
+class Circle: Shape {
+ var radius: Int
+ override func getArea() -> Int {
+ return 3 * radius * radius
+ }
+
+ // Поместите постфиксный знак вопроса после `init` - это и будет опциональная инициализация,
+ // которая может вернуть nil
+ init?(radius: Int) {
+ self.radius = radius
+ super.init()
+
+ if radius <= 0 {
+ return nil
+ }
+ }
+}
+
+var myCircle = Circle(radius: 1)
+println(myCircle?.getArea()) // Optional(3)
+println(myCircle!.getArea()) // 3
+var myEmptyCircle = Circle(radius: -1)
+println(myEmptyCircle?.getArea()) // "nil"
+if let circle = myEmptyCircle {
+ // не будет выполняться, поскольку myEmptyCircle равен nil
+ println("circle не nil")
+}
+
//
// MARK: Перечисления
@@ -433,6 +463,28 @@ enum BookName: String {
}
println("Имя: \(BookName.John.rawValue)")
+// Перечисление (enum) со связанными значениями
+enum Furniture {
+ // Связать с типом Int
+ case Desk(height: Int)
+ // Связать с типами String и Int
+ case Chair(String, Int)
+
+ func description() -> String {
+ switch self {
+ case .Desk(let height):
+ return "Письменный стол высотой \(height) см."
+ case .Chair(let brand, let height):
+ return "Стул марки \(brand) высотой \(height) см."
+ }
+ }
+}
+
+var desk: Furniture = .Desk(height: 80)
+println(desk.description()) // "Письменный стол высотой 80 см."
+var chair = Furniture.Chair("Foo", 40)
+println(chair.description()) // "Стул марки Foo высотой 40 см."
+
//
// MARK: Протоколы
diff --git a/ruby.html.markdown b/ruby.html.markdown
index 7cf5bdc7..792c9c95 100644
--- a/ruby.html.markdown
+++ b/ruby.html.markdown
@@ -11,6 +11,7 @@ contributors:
- ["Ariel Krakowski", "http://www.learneroo.com"]
- ["Dzianis Dashkevich", "https://github.com/dskecse"]
- ["Levi Bostian", "https://github.com/levibostian"]
+ - ["Rahil Momin", "https://github.com/iamrahil"]
---
@@ -60,8 +61,6 @@ false.class #=> FalseClass
# Inequality
1 != 1 #=> false
2 != 1 #=> true
-!true #=> false
-!false #=> true
# apart from false itself, nil is the only other 'falsey' value
@@ -75,6 +74,17 @@ false.class #=> FalseClass
2 <= 2 #=> true
2 >= 2 #=> true
+# Logical operators
+true && false #=> false
+true || false #=> true
+!true #=> false
+
+# Alternate spellings of logical operators
+true and false #=> false
+true or false #=> true
+not true #=> false
+
+
# Strings are objects
'I am a string'.class #=> String
@@ -160,6 +170,9 @@ array[1..3] #=> [2, 3, 4]
# Add to an array like this
array << 6 #=> [1, 2, 3, 4, 5, 6]
+# Check if an item exists in an array
+array.include?(1) #=> true
+
# Hashes are Ruby's primary dictionary with keys/value pairs.
# Hashes are denoted with curly braces:
hash = { 'color' => 'green', 'number' => 5 }
@@ -179,6 +192,10 @@ new_hash = { defcon: 3, action: true }
new_hash.keys #=> [:defcon, :action]
+# Check existence of keys and values in hash
+new_hash.has_key?(:defcon) #=> true
+new_hash.has_value?(3) #=> true
+
# Tip: Both Arrays and Hashes are Enumerable
# They share a lot of useful methods such as each, map, count, and more
@@ -280,9 +297,9 @@ rescue NoMemoryError => exception_variable
puts 'NoMemoryError was raised', exception_variable
rescue RuntimeError => other_exception_variable
puts 'RuntimeError was raised now'
-else
+else
puts 'This runs if no exceptions were thrown at all'
-ensure
+ensure
puts 'This code always runs no matter what'
end
diff --git a/swift.html.markdown b/swift.html.markdown
index 0977efc4..ffc57e69 100644
--- a/swift.html.markdown
+++ b/swift.html.markdown
@@ -3,6 +3,7 @@ language: swift
contributors:
- ["Grant Timmerman", "http://github.com/grant"]
- ["Christopher Bess", "http://github.com/cbess"]
+ - ["Joey Huang", "http://github.com/kamidox"]
filename: learnswift.swift
---
@@ -388,6 +389,35 @@ if mySquare === mySquare {
println("Yep, it's mySquare")
}
+// Optional init
+class Circle: Shape {
+ var radius: Int
+ override func getArea() -> Int {
+ return 3 * radius * radius
+ }
+
+ // Place a question mark postfix after `init` is an optional init
+ // which can return nil
+ init?(radius: Int) {
+ self.radius = radius
+ super.init()
+
+ if radius <= 0 {
+ return nil
+ }
+ }
+}
+
+var myCircle = Circle(radius: 1)
+println(myCircle?.getArea()) // Optional(3)
+println(myCircle!.getArea()) // 3
+var myEmptyCircle = Circle(radius: -1)
+println(myEmptyCircle?.getArea()) // "nil"
+if let circle = myEmptyCircle {
+ // will not execute since myEmptyCircle is nil
+ println("circle is not nil")
+}
+
//
// MARK: Enums
@@ -419,6 +449,28 @@ enum BookName: String {
}
println("Name: \(BookName.John.rawValue)")
+// Enum with associated Values
+enum Furniture {
+ // Associate with Int
+ case Desk(height: Int)
+ // Associate with String and Int
+ case Chair(String, Int)
+
+ func description() -> String {
+ switch self {
+ case .Desk(let height):
+ return "Desk with \(height) cm"
+ case .Chair(let brand, let height):
+ return "Chair of \(brand) with \(height) cm"
+ }
+ }
+}
+
+var desk: Furniture = .Desk(height: 80)
+println(desk.description()) // "Desk with 80 cm"
+var chair = Furniture.Chair("Foo", 40)
+println(chair.description()) // "Chair of Foo with 40 cm"
+
//
// MARK: Protocols
diff --git a/tcl.html.markdown b/tcl.html.markdown
index f2d92fcd..198f675e 100755
--- a/tcl.html.markdown
+++ b/tcl.html.markdown
@@ -169,7 +169,7 @@ namespace eval people {
#The full name of a variable includes its enclosing namespace(s), delimited by two colons:
-set greeting "Hello $people::person::name"
+set greeting "Hello $people::person1::name"
@@ -189,7 +189,7 @@ set greeting "Hello $people::person::name"
namespace delete ::
-# Because of name resolution behaviour, its safer to use the "variable" command to declare or to assign a value to a namespace.
+# Because of name resolution behaviour, it's safer to use the "variable" command to declare or to assign a value to a namespace.
namespace eval people {
namespace eval person1 {
variable name Neo
diff --git a/typescript.html.markdown b/typescript.html.markdown
index 9f04169a..27a1f71a 100644
--- a/typescript.html.markdown
+++ b/typescript.html.markdown
@@ -14,100 +14,111 @@ This article will focus only on TypeScript extra syntax, as oposed to [JavaScrip
To test TypeScript's compiler, head to the [Playground] (http://www.typescriptlang.org/Playground) where you will be able to type code, have auto completion and directly see the emitted JavaScript.
```js
-//There are 3 basic types in TypeScript
+// There are 3 basic types in TypeScript
var isDone: boolean = false;
var lines: number = 42;
var name: string = "Anders";
-//..When it's impossible to know, there is the "Any" type
+// When it's impossible to know, there is the "Any" type
var notSure: any = 4;
notSure = "maybe a string instead";
notSure = false; // okay, definitely a boolean
-//For collections, there are typed arrays and generic arrays
+// For collections, there are typed arrays and generic arrays
var list: number[] = [1, 2, 3];
-//Alternatively, using the generic array type
+// Alternatively, using the generic array type
var list: Array<number> = [1, 2, 3];
-//For enumerations:
+// For enumerations:
enum Color {Red, Green, Blue};
var c: Color = Color.Green;
-//Lastly, "void" is used in the special case of a function not returning anything
+// Lastly, "void" is used in the special case of a function returning nothing
function bigHorribleAlert(): void {
alert("I'm a little annoying box!");
}
-//Functions are first class citizens, support the lambda "fat arrow" syntax and use type inference
-//All examples are equivalent, the same signature will be infered by the compiler, and same JavaScript will be emitted
-var f1 = function(i: number) : number { return i * i; }
-var f2 = function(i: number) { return i * i; } //Return type infered
-var f3 = (i : number) : number => { return i * i; }
-var f4 = (i: number) => { return i * i; } //Return type infered
-var f5 = (i: number) => i * i; //Return type infered, one-liner means no return keyword needed
-
-//Interfaces are structural, anything that has the properties is compliant with the interface
+// Functions are first class citizens, support the lambda "fat arrow" syntax and
+// use type inference
+
+// The following are equivalent, the same signature will be infered by the
+// compiler, and same JavaScript will be emitted
+var f1 = function(i: number): number { return i * i; }
+// Return type inferred
+var f2 = function(i: number) { return i * i; }
+var f3 = (i: number): number => { return i * i; }
+// Return type inferred
+var f4 = (i: number) => { return i * i; }
+// Return type inferred, one-liner means no return keyword needed
+var f5 = (i: number) => i * i;
+
+// Interfaces are structural, anything that has the properties is compliant with
+// the interface
interface Person {
name: string;
- //Optional properties, marked with a "?"
+ // Optional properties, marked with a "?"
age?: number;
- //And of course functions
+ // And of course functions
move(): void;
}
-//..Object that implements the "Person" interface
-var p : Person = { name: "Bobby", move : () => {} }; //Can be treated as a Person since it has the name and age properties
-//..Objects that have the optional property:
-var validPerson : Person = { name: "Bobby", age: 42, move: () => {} };
-var invalidPerson : Person = { name: "Bobby", age: true }; //Is not a person because age is not a number
+// Object that implements the "Person" interface
+// Can be treated as a Person since it has the name and move properties
+var p: Person = { name: "Bobby", move: () => {} };
+// Objects that have the optional property:
+var validPerson: Person = { name: "Bobby", age: 42, move: () => {} };
+// Is not a person because age is not a number
+var invalidPerson: Person = { name: "Bobby", age: true };
-//..Interfaces can also describe a function type
+// Interfaces can also describe a function type
interface SearchFunc {
(source: string, subString: string): boolean;
}
-//..Only the parameters' types are important, names are not important.
+// Only the parameters' types are important, names are not important.
var mySearch: SearchFunc;
mySearch = function(src: string, sub: string) {
return src.search(sub) != -1;
}
-//Classes - members are public by default
+// Classes - members are public by default
class Point {
- //Properties
- x: number;
-
- //Constructor - the public/private keywords in this context will generate the boiler plate code
- // for the property and the initialization in the constructor.
- // In this example, "y" will be defined just like "x" is, but with less code
- //Default values are also supported
- constructor(x: number, public y: number = 0) {
- this.x = x;
- }
-
- //Functions
- dist() { return Math.sqrt(this.x * this.x + this.y * this.y); }
-
- //Static members
- static origin = new Point(0, 0);
+ // Properties
+ x: number;
+
+ // Constructor - the public/private keywords in this context will generate
+ // the boiler plate code for the property and the initialization in the
+ // constructor.
+ // In this example, "y" will be defined just like "x" is, but with less code
+ // Default values are also supported
+
+ constructor(x: number, public y: number = 0) {
+ this.x = x;
+ }
+
+ // Functions
+ dist() { return Math.sqrt(this.x * this.x + this.y * this.y); }
+
+ // Static members
+ static origin = new Point(0, 0);
}
var p1 = new Point(10 ,20);
var p2 = new Point(25); //y will be 0
-//Inheritance
+// Inheritance
class Point3D extends Point {
- constructor(x: number, y: number, public z: number = 0) {
- super(x, y); //Explicit call to the super class constructor is mandatory
- }
-
- //Overwrite
- dist() {
- var d = super.dist();
- return Math.sqrt(d * d + this.z * this.z);
- }
+ constructor(x: number, y: number, public z: number = 0) {
+ super(x, y); // Explicit call to the super class constructor is mandatory
+ }
+
+ // Overwrite
+ dist() {
+ var d = super.dist();
+ return Math.sqrt(d * d + this.z * this.z);
+ }
}
-//Modules, "." can be used as separator for sub modules
+// Modules, "." can be used as separator for sub modules
module Geometry {
export class Square {
constructor(public sideLength: number = 0) {
@@ -120,32 +131,32 @@ module Geometry {
var s1 = new Geometry.Square(5);
-//..Local alias for referencing a module
+// Local alias for referencing a module
import G = Geometry;
var s2 = new G.Square(10);
-//Generics
-//..Classes
+// Generics
+// Classes
class Tuple<T1, T2> {
constructor(public item1: T1, public item2: T2) {
}
}
-//..Interfaces
+// Interfaces
interface Pair<T> {
- item1: T;
- item2: T;
+ item1: T;
+ item2: T;
}
-//..And functions
+// And functions
var pairToTuple = function<T>(p: Pair<T>) {
- return new Tuple(p.item1, p.item2);
+ return new Tuple(p.item1, p.item2);
};
var tuple = pairToTuple({ item1:"hello", item2:"world"});
-//Including references to a definition file:
+// Including references to a definition file:
/// <reference path="jquery.d.ts" />
```
diff --git a/xml.html.markdown b/xml.html.markdown
index 94fc93f4..fce1a3a4 100644
--- a/xml.html.markdown
+++ b/xml.html.markdown
@@ -7,7 +7,7 @@ contributors:
XML is a markup language designed to store and transport data.
-Unlike HTML, XML does not specifies how to display or to format data, just carry it.
+Unlike HTML, XML does not specify how to display or to format data, just carry it.
* XML Syntax
@@ -123,4 +123,4 @@ With this tool, you can check the XML data outside the application logic.
<price>30.00</price>
</book>
</bookstore>
-``` \ No newline at end of file
+```
diff --git a/zh-cn/javascript-cn.html.markdown b/zh-cn/javascript-cn.html.markdown
index 7dee9cc4..64b0aadc 100644
--- a/zh-cn/javascript-cn.html.markdown
+++ b/zh-cn/javascript-cn.html.markdown
@@ -5,17 +5,19 @@ name: javascript
filename: javascript-zh.js
contributors:
- ["Adam Brenecki", "http://adam.brenecki.id.au"]
+ - ["Ariel Krakowski", "http://www.learneroo.com"]
translators:
- ["Chenbo Li", "http://binarythink.net"]
+ - ["Guodong Qu", "https://github.com/jasonqu"]
lang: zh-cn
---
Javascript于1995年由网景公司的Brendan Eich发明。
最初发明的目的是作为一个简单的网站脚本语言,来作为
-复杂网站应用java的补充。但由于javascript和网站结合度很高
-所以javascript逐渐变得比java在前端更为流行了。
+复杂网站应用java的补充。但由于它与网页结合度很高并且由浏览器内置支持,
+所以javascript变得比java在前端更为流行了。
-JavaScript 不仅仅只可以用于浏览器, 也可用于 Node.js 等后台环境。
+不过 JavaScript 可不仅仅只用于浏览器: Node.js,一个基于Google Chrome V8引擎的独立运行时环境,也越来越流行。
很欢迎来自您的反馈,您可以通过下列方式联系到我:
[@adambrenecki](https://twitter.com/adambrenecki), 或者
@@ -29,145 +31,167 @@ JavaScript 不仅仅只可以用于浏览器, 也可用于 Node.js 等后台环
// 语句可以以分号结束
doStuff();
-// ... 但是分号也可以省略,每当遇到一个新行时,分号会自动插入
+// ... 但是分号也可以省略,每当遇到一个新行时,分号会自动插入(除了一些特殊情况)。
doStuff()
-// 我们在这里会去掉分号,但是否添加最后的分号取决于你个人的习惯
-// 及你所在团队的编程风格
+// 因为这些特殊情况会导致意外的结果,所以我们在这里保留分号。
///////////////////////////////////
// 1. 数字、字符串与操作符
-// Javascript 只有一种数字类型 (即 64位 IEEE 754 双精度浮点).
-3 // = 3
-1.5 // = 1.5
+// Javascript 只有一种数字类型(即 64位 IEEE 754 双精度浮点 double)。
+// double 有 52 位表示尾数,足以精确存储大到 9✕10¹⁵ 的整数。
+3; // = 3
+1.5; // = 1.5
-// 所有基本的算数运算
-1 + 1 // = 2
-8 - 1 // = 7
-10 * 2 // = 20
-35 / 5 // = 7
+// 所有基本的算数运算都如你预期。
+1 + 1; // = 2
+0.1 + 0.2; // = 0.30000000000000004
+8 - 1; // = 7
+10 * 2; // = 20
+35 / 5; // = 7
-// 包括无法整除的除法
-5 / 2 // = 2.5
+// 包括无法整除的除法。
+5 / 2; // = 2.5
-// 位运算也和其他语言一样。当你对浮点数进行位运算时,
-// 浮点数会转换为至多 32 位的无符号整数
-1 << 2 // = 4
+// 位运算也和其他语言一样;当你对浮点数进行位运算时,
+// 浮点数会转换为*至多* 32 位的无符号整数。
+1 << 2; // = 4
-// 括号可以决定优先级
-(1 + 3) * 2 // = 8
+// 括号可以决定优先级。
+(1 + 3) * 2; // = 8
// 有三种非数字的数字类型
-Infinity // 1/0 的结果
--Infinity // -1/0 的结果
-NaN // 0/0 的结果
+Infinity; // 1/0 的结果
+-Infinity; // -1/0 的结果
+NaN; // 0/0 的结果
-// 也有布尔值
-true
-false
+// 也有布尔值。
+true;
+false;
-// 可以通过单引号或双引号来构造字符串
-'abc'
-"Hello, world"
+// 可以通过单引号或双引号来构造字符串。
+'abc';
+"Hello, world";
// 用!来取非
-!true // = false
-!false // = true
+!true; // = false
+!false; // = true
-// 相等 ==
-1 == 1 // = true
-2 == 1 // = false
+// 相等 ===
+1 === 1; // = true
+2 === 1; // = false
// 不等 !=
-1 != 1 // = false
-2 != 1 // = true
+1 !== 1; // = false
+2 !== 1; // = true
// 更多的比较操作符
-1 < 10 // = true
-1 > 10 // = false
-2 <= 2 // = true
-2 >= 2 // = true
+1 < 10; // = true
+1 > 10; // = false
+2 <= 2; // = true
+2 >= 2; // = true
// 字符串用+连接
-"Hello " + "world!" // = "Hello world!"
+"Hello " + "world!"; // = "Hello world!"
// 字符串也可以用 < 、> 来比较
-"a" < "b" // = true
+"a" < "b"; // = true
-// 比较时会进行类型转换...
-"5" == 5 // = true
+// 使用“==”比较时会进行类型转换...
+"5" == 5; // = true
+null == undefined; // = true
// ...除非你是用 ===
-"5" === 5 // = false
+"5" === 5; // = false
+null === undefined; // = false
-// 你可以用charAt来得到字符串中的字符
-"This is a string".charAt(0)
+// ...但会导致奇怪的行为
+13 + !0; // 14
+"13" + !0; // '13true'
-// 还有两个特殊的值:null和undefined
-null // 用来表示刻意设置成的空值
-undefined // 用来表示还没有设置的值
+// 你可以用`charAt`来得到字符串中的字符
+"This is a string".charAt(0); // = 'T'
-// null, undefined, NaN, 0 和 "" 都是假的(false),其他的都视作逻辑真
-// 注意 0 是逻辑假而 "0"是逻辑真, 尽管 0 == "0".
+// ...或使用 `substring` 来获取更大的部分。
+"Hello world".substring(0, 5); // = "Hello"
+
+// `length` 是一个属性,所以不要使用 ().
+"Hello".length; // = 5
+
+// 还有两个特殊的值:`null`和`undefined`
+null; // 用来表示刻意设置的空值
+undefined; // 用来表示还没有设置的值(尽管`undefined`自身实际是一个值)
+
+// false, null, undefined, NaN, 0 和 "" 都是假的;其他的都视作逻辑真
+// 注意 0 是逻辑假而 "0"是逻辑真,尽管 0 == "0"。
///////////////////////////////////
// 2. 变量、数组和对象
-// 变量需要用 var 这个关键字声明. Javascript是动态类型语言
-// 所以你在声明时无需指定类型。 赋值需要用 =
-var someVar = 5
+// 变量需要用`var`关键字声明。Javascript是动态类型语言,
+// 所以你无需指定类型。 赋值需要用 `=`
+var someVar = 5;
-// 如果你在声明时没有加var关键字,你也不会得到错误
-someOtherVar = 10
+// 如果你在声明时没有加var关键字,你也不会得到错误...
+someOtherVar = 10;
-// ...但是此时这个变量就会拥有全局的作用域,而非当前作用域
+// ...但是此时这个变量就会在全局作用域被创建,而非你定义的当前作用域
-// 没有被赋值的变量都会返回undefined这个值
-var someThirdVar // = undefined
+// 没有被赋值的变量都会被设置为undefined
+var someThirdVar; // = undefined
-// 对变量进行数学运算有一些简写法
-someVar += 5 // 等价于 someVar = someVar + 5; someVar 现在是 10
-someVar *= 10 // 现在 someVar 是 100
+// 对变量进行数学运算有一些简写法:
+someVar += 5; // 等价于 someVar = someVar + 5; someVar 现在是 10
+someVar *= 10; // 现在 someVar 是 100
// 自增和自减也有简写
-someVar++ // someVar 是 101
-someVar-- // 回到 100
+someVar++; // someVar 是 101
+someVar--; // 回到 100
// 数组是任意类型组成的有序列表
-var myArray = ["Hello", 45, true]
+var myArray = ["Hello", 45, true];
+
+// 数组的元素可以用方括号下标来访问。
+// 数组的索引从0开始。
+myArray[1]; // = 45
-// 数组的元素可以用方括号下标来访问
-// 数组的索引从0开始
-myArray[1] // = 45
+// 数组是可变的,并拥有变量 length。
+myArray.push("World");
+myArray.length; // = 4
-// javascript中的对象相当于其他语言中的字典或映射:是键-值的集合
-{key1: "Hello", key2: "World"}
+// 在指定下标添加/修改
+myArray[3] = "Hello";
-// 键是字符串,但是引号也并非是必须的,如果键本身是合法的js标识符
-// 而值则可以是任意类型的值
-var myObj = {myKey: "myValue", "my other key": 4}
+// javascript中的对象相当于其他语言中的“字典”或“映射”:是键-值对的无序集合。
+var myObj = {key1: "Hello", key2: "World"};
-// 对象的访问可以通过下标
-myObj["my other key"] // = 4
+// 键是字符串,但如果键本身是合法的js标识符,则引号并非是必须的。
+// 值可以是任意类型。
+var myObj = {myKey: "myValue", "my other key": 4};
+
+// 对象属性的访问可以通过下标
+myObj["my other key"]; // = 4
// ... 或者也可以用 . ,如果属性是合法的标识符
-myObj.myKey // = "myValue"
+myObj.myKey; // = "myValue"
-// 对象是可变的,键和值也可以被更改或增加
-myObj.myThirdKey = true
+// 对象是可变的;值也可以被更改或增加新的键
+myObj.myThirdKey = true;
-// 如果你想要访问一个还没有被定义的属性,那么会返回undefined
-myObj.myFourthKey // = undefined
+// 如果你想要获取一个还没有被定义的值,那么会返回undefined
+myObj.myFourthKey; // = undefined
///////////////////////////////////
// 3. 逻辑与控制结构
-// if语句和其他语言中一样
-var count = 1
+// 本节介绍的语法与Java的语法几乎完全相同
+
+// `if`语句和其他语言中一样。
+var count = 1;
if (count == 3){
// count 是 3 时执行
-} else if (count == 4) {
+} else if (count == 4){
// count 是 4 时执行
} else {
// 其他情况下执行
@@ -179,219 +203,273 @@ while (true) {
}
// Do-while 和 While 循环很像 ,但前者会至少执行一次
-var input
+var input;
do {
- input = getInput()
+ input = getInput();
} while (!isValid(input))
-// for循环和C、Java中的一样
-// 初始化; 继续执行的条件; 遍历后执行.
+// `for`循环和C、Java中的一样:
+// 初始化; 继续执行的条件; 迭代。
for (var i = 0; i < 5; i++){
// 遍历5次
}
// && 是逻辑与, || 是逻辑或
if (house.size == "big" && house.colour == "blue"){
- house.contains = "bear"
+ house.contains = "bear";
}
if (colour == "red" || colour == "blue"){
// colour是red或者blue时执行
}
-// && 和 || 是“短路”语句,在初始化值时会变得有用
-var name = otherName || "default"
+// && 和 || 是“短路”语句,它在设定初始化值时特别有用
+var name = otherName || "default";
+
+// `switch`语句使用`===`检查相等性。
+// 在每一个case结束时使用 'break'
+// 否则其后的case语句也将被执行。
+grade = 'B';
+switch (grade) {
+ case 'A':
+ console.log("Great job");
+ break;
+ case 'B':
+ console.log("OK job");
+ break;
+ case 'C':
+ console.log("You can do better");
+ break;
+ default:
+ console.log("Oy vey");
+ break;
+}
///////////////////////////////////
// 4. 函数、作用域、闭包
-// JavaScript 函数由function关键字定义
+// JavaScript 函数由`function`关键字定义
function myFunction(thing){
- return thing.toUpperCase()
+ return thing.toUpperCase();
}
-myFunction("foo") // = "FOO"
-
-// 函数也可以是匿名的:
-function(thing){
- return thing.toLowerCase()
+myFunction("foo"); // = "FOO"
+
+// 注意被返回的值必须开始于`return`关键字的那一行,
+// 否则由于自动的分号补齐,你将返回`undefined`。
+// 在使用Allman风格的时候要注意.
+function myFunction()
+{
+ return // <- 分号自动插在这里
+ {
+ thisIsAn: 'object literal'
+ }
}
-// (我们无法调用此函数,因为我们不知道这个函数的名字)
+myFunction(); // = undefined
-// javascript中的函数也是对象,所以函数也能够赋给一个变量,并且被传递
-// 比如一个事件处理函数:
+// javascript中函数是一等对象,所以函数也能够赋给一个变量,
+// 并且被作为参数传递 —— 比如一个事件处理函数:
function myFunction(){
- // this code will be called in 5 seconds' time
+ // 这段代码将在5秒钟后被调用
}
-setTimeout(myFunction, 5000)
-
-// 你甚至可以直接把一个函数写到另一个函数的参数中
+setTimeout(myFunction, 5000);
+// 注意:setTimeout不是js语言的一部分,而是由浏览器和Node.js提供的。
-setTimeout(function myFunction(){
- // 5秒之后会执行这里的代码
-}, 5000)
+// 函数对象甚至不需要声明名称 —— 你可以直接把一个函数定义写到另一个函数的参数中
+setTimeout(function(){
+ // 这段代码将在5秒钟后被调用
+}, 5000);
-// JavaScript 仅有函数作用于,而其他的语句则没有作用域
+// JavaScript 有函数作用域;函数有其自己的作用域而其他的代码块则没有。
if (true){
- var i = 5
+ var i = 5;
}
-i // = 5 - 并非我们在其他语言中所得到的undefined
-
-// 这就导致了人们经常用一种叫做“即使执行匿名函数”的模式
-// 这样可以避免一些临时变量扩散到外边去
-function(){
- var temporary = 5
- // 我们可以访问一个全局对象来访问全局作用域
- // 在浏览器中是 'window' 这个对象。
- // 在Node.js中这个对象的名字可能会不同。
- window.permanent = 10
- // 或者,我们也可以把var去掉就行了
- permanent2 = 15
-}()
-temporary // 抛出引用异常
-permanent // = 10
-permanent2 // = 15
-
-// javascript最强大的功能之一就是闭包
-// 如果一个函数在另一个函数中定义,那么这个函数就拥有外部函数的所有访问权
+i; // = 5 - 并非我们在其他语言中所期望得到的undefined
+
+// 这就导致了人们经常使用的“立即执行匿名函数”的模式,
+// 这样可以避免一些临时变量扩散到全局作用域去。
+(function(){
+ var temporary = 5;
+ // 我们可以访问修改全局对象("global object")来访问全局作用域,
+ // 在web浏览器中是`window`这个对象。
+ // 在其他环境如Node.js中这个对象的名字可能会不同。
+ window.permanent = 10;
+})();
+temporary; // 抛出引用异常ReferenceError
+permanent; // = 10
+
+// javascript最强大的功能之一就是闭包。
+// 如果一个函数在另一个函数中定义,那么这个内部函数就拥有外部函数的所有变量的访问权,
+// 即使在外部函数结束之后。
function sayHelloInFiveSeconds(name){
- var prompt = "Hello, " + name + "!"
+ var prompt = "Hello, " + name + "!";
+ // 内部函数默认是放在局部作用域的,
+ // 就像是用`var`声明的。
function inner(){
- alert(prompt)
+ alert(prompt);
}
- setTimeout(inner, 5000)
- // setTimeout 是异步的,所以这个函数会马上终止不会等待。
- // 然而,在5秒结束后,inner函数仍然会弹出prompt信息。
+ setTimeout(inner, 5000);
+ // setTimeout是异步的,所以 sayHelloInFiveSeconds 函数会立即退出,
+ // 而 setTimeout 会在后面调用inner
+ // 然而,由于inner是由sayHelloInFiveSeconds“闭合包含”的,
+ // 所以inner在其最终被调用时仍然能够访问`prompt`变量。
}
-sayHelloInFiveSeconds("Adam") // 会在5秒后弹出 "Hello, Adam!"
+sayHelloInFiveSeconds("Adam"); // 会在5秒后弹出 "Hello, Adam!"
+
///////////////////////////////////
// 5. 对象、构造函数与原型
-// 对象包含方法
+// 对象可以包含方法。
var myObj = {
myFunc: function(){
- return "Hello world!"
+ return "Hello world!";
}
-}
-myObj.myFunc() // = "Hello world!"
+};
+myObj.myFunc(); // = "Hello world!"
-// 当对象中的函数被调用时,这个函数就可以通过this关键字访问这个对象
+// 当对象中的函数被调用时,这个函数可以通过`this`关键字访问其依附的这个对象。
myObj = {
myString: "Hello world!",
myFunc: function(){
- return this.myString
+ return this.myString;
}
-}
-myObj.myFunc() // = "Hello world!"
+};
+myObj.myFunc(); // = "Hello world!"
-// 但这个函数访问的其实是其运行时环境,而非定义时环境
-// 所以如果函数所在的环境不在当前对象的环境中运行时,就运行不成功了
-var myFunc = myObj.myFunc
-myFunc() // = undefined
+// 但这个函数访问的其实是其运行时环境,而非定义时环境,即取决于函数是如何调用的。
+// 所以如果函数被调用时不在这个对象的上下文中,就不会运行成功了。
+var myFunc = myObj.myFunc;
+myFunc(); // = undefined
-// 相应的,一个函数也可以被指定为一个对象的方法,并且用过this可以访问
-// 这个对象的成员,即使在定义时并没有绑定任何值
+// 相应的,一个函数也可以被指定为一个对象的方法,并且可以通过`this`访问
+// 这个对象的成员,即使在行数被定义时并没有依附在对象上。
var myOtherFunc = function(){
- return this.myString.toUpperCase()
+ return this.myString.toUpperCase();
+}
+myObj.myOtherFunc = myOtherFunc;
+myObj.myOtherFunc(); // = "HELLO WORLD!"
+
+// 当我们通过`call`或者`apply`调用函数的时候,也可以为其指定一个执行上下文。
+var anotherFunc = function(s){
+ return this.myString + s;
}
-myObj.myOtherFunc = myOtherFunc
-myObj.myOtherFunc() // = "HELLO WORLD!"
+anotherFunc.call(myObj, " And Hello Moon!"); // = "Hello World! And Hello Moon!"
-// 当你通过new关键字调用一个函数时,就会生成一个对象
-// 而对象的成员需要通过this来定义。
-// 这样的函数就叫做构造函数
+// `apply`函数几乎完全一样,只是要求一个array来传递参数列表。
+anotherFunc.apply(myObj, [" And Hello Sun!"]); // = "Hello World! And Hello Sun!"
+// 当一个函数接受一系列参数,而你想传入一个array时特别有用。
+Math.min(42, 6, 27); // = 6
+Math.min([42, 6, 27]); // = NaN (uh-oh!)
+Math.min.apply(Math, [42, 6, 27]); // = 6
+
+// 但是`call`和`apply`只是临时的。如果我们希望函数附着在对象上,可以使用`bind`。
+var boundFunc = anotherFunc.bind(myObj);
+boundFunc(" And Hello Saturn!"); // = "Hello World! And Hello Saturn!"
+
+// `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
+ this.myNumber = 5;
}
-myNewObj = new MyConstructor() // = {myNumber: 5}
-myNewObj.myNumber // = 5
+myNewObj = new MyConstructor(); // = {myNumber: 5}
+myNewObj.myNumber; // = 5
-// 每一个js对象都有一个原型,当你要访问一个没有定义过的成员时,
-// 解释器就回去找这个对象的原型
+// 每一个js对象都有一个‘原型’。当你要访问一个实际对象中没有定义的一个属性时,
+// 解释器就回去找这个对象的原型。
-// 有一些JS实现会让你通过一个对象的__proto__方法访问这个原型。
-// 这虽然对理解这个对象很有用,但是这并不是标准的一部分
-// 我们之后会通过标准方式来访问原型。
+// 一些JS实现会让你通过`__proto__`属性访问一个对象的原型。
+// 这虽然对理解原型很有用,但是它并不是标准的一部分;
+// 我们后面会介绍使用原型的标准方式。
var myObj = {
- myString: "Hello world!",
-}
+ myString: "Hello world!"
+};
var myPrototype = {
meaningOfLife: 42,
myFunc: function(){
return this.myString.toLowerCase()
}
-}
-myObj.__proto__ = myPrototype
-myObj.meaningOfLife // = 42
+};
-// This works for functions, too.
+myObj.__proto__ = myPrototype;
+myObj.meaningOfLife; // = 42
+
+// 函数也可以工作。
myObj.myFunc() // = "hello world!"
-// 当然,如果你要访问的成员在原型当中也没有定义的话,解释器就会去找原型的原型。
+// 当然,如果你要访问的成员在原型当中也没有定义的话,解释器就会去找原型的原型,以此类堆。
myPrototype.__proto__ = {
myBoolean: true
-}
-myObj.myBoolean // = true
-
-// 这其中并没有对象的拷贝。每个对象的原型实际上是持有原型对象的引用
-// 这说明当我们改变对象的原型时,会影响到其他以这个原型为原型的对象
-myPrototype.meaningOfLife = 43
-myObj.meaningOfLife // = 43
-
-// 我们知道 __proto__ 并非标准规定,实际上也没有办法更改已经指定好的原型。
-// 但是,我们有两种方式可以为新的对象指定原型。
-
-// 第一种方式是 Object.create,这个方法是在最近才被添加到Js中的
-// 也因此并不是所有的JS实现都有这个放啊
-var myObj = Object.create(myPrototype)
-myObj.meaningOfLife // = 43
-
-// 第二种方式可以在任意版本中使用,不过需要通过构造函数。
-// 构造函数有一个属性prototype。但是这 *不是* 构造函数本身的函数
-// 而是通过构造函数和new关键字生成新对象时自动生成的。
-myConstructor.prototype = {
+};
+myObj.myBoolean; // = true
+
+// 这其中并没有对象的拷贝;每个对象实际上是持有原型对象的引用。
+// 这意味着当我们改变对象的原型时,会影响到其他以这个原型为原型的对象。
+myPrototype.meaningOfLife = 43;
+myObj.meaningOfLife; // = 43
+
+// 我们知道 `__proto__` 并非标准规定,实际上也没有标准办法来修改一个已存在对象的原型。
+// 然而,我们有两种方式为指定原型创建一个新的对象。
+
+// 第一种方式是 Object.create,这个方法是在最近才被添加到Js中的,
+// 因此并不是所有的JS实现都有这个方法
+var myObj = Object.create(myPrototype);
+myObj.meaningOfLife; // = 43
+
+// 第二种方式可以在任意版本中使用,不过必须通过构造函数。
+// 构造函数有一个属性prototype。但是它 *不是* 构造函数本身的原型;相反,
+// 是通过构造函数和new关键字创建的新对象的原型。
+MyConstructor.prototype = {
+ myNumber: 5,
getMyNumber: function(){
- return this.myNumber
+ return this.myNumber;
}
-}
-var myNewObj2 = new myConstructor()
-myNewObj2.getMyNumber() // = 5
+};
+var myNewObj2 = new MyConstructor();
+myNewObj2.getMyNumber(); // = 5
+myNewObj2.myNumber = 6
+myNewObj2.getMyNumber(); // = 6
// 字符串和数字等内置类型也有通过构造函数来创建的包装类型
-var myNumber = 12
-var myNumberObj = new Number(12)
-myNumber == myNumberObj // = true
+var myNumber = 12;
+var myNumberObj = new Number(12);
+myNumber == myNumberObj; // = true
// 但是它们并非严格等价
-typeof myNumber // = 'number'
-typeof myNumberObj // = 'object'
-myNumber === myNumberObj // = false
+typeof myNumber; // = 'number'
+typeof myNumberObj; // = 'object'
+myNumber === myNumberObj; // = false
if (0){
// 这段代码不会执行,因为0代表假
}
if (Number(0)){
- // 这段代码会执行,因为Number(0)代表真
+ // 这段代码*会*执行,因为Number(0)代表真
}
-// 但是,包装类型和内置类型共享一个原型
-// 这样你就可以给内置类型也增加一些功能
+// 不过,包装类型和内置类型共享一个原型,
+// 所以你实际可以给内置类型也增加一些功能,例如对string:
String.prototype.firstCharacter = function(){
- return this.charAt(0)
+ return this.charAt(0);
}
-"abc".firstCharacter() // = "a"
+"abc".firstCharacter(); // = "a"
-// 这个技巧可以用来用老版本的javascript子集来是实现新版本js的功能
+// 这个技巧经常用在“代码填充”中,来为老版本的javascript子集增加新版本js的特性,
// 这样就可以在老的浏览器中使用新功能了。
-// 比如,我们知道Object.create并没有在所有的版本中都实现
-// 但是我们仍然可以通过这个技巧来使用
+// 比如,我们知道Object.create并没有在所有的版本中都实现,
+// 但是我们仍然可以通过“代码填充”来实现兼容:
if (Object.create === undefined){ // 如果存在则不覆盖
Object.create = function(proto){
// 用正确的原型来创建一个临时构造函数
- var Constructor = function(){}
- Constructor.prototype = proto
+ var Constructor = function(){};
+ Constructor.prototype = proto;
// 之后用它来创建一个新的对象
- return new Constructor()
+ return new Constructor();
}
}
```
@@ -399,19 +477,23 @@ if (Object.create === undefined){ // 如果存在则不覆盖
## 更多阅读
[Mozilla 开发者
-网络](https://developer.mozilla.org/en-US/docs/Web/JavaScript) 提供了很好的
-Javascript文档,并且由于是wiki,所以你也可以自行编辑来分享你的知识。
+网络](https://developer.mozilla.org/en-US/docs/Web/JavaScript) 提供了优秀的介绍
+Javascript如何在浏览器中使用的文档。而且它是wiki,所以你也可以自行编辑来分享你的知识。
MDN的 [A re-introduction to
JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript)
-覆盖了这里提到的绝大多数话题,大多数只是Javascript这个语言本身。
+覆盖了这里提到的绝大多数话题的细节。该导引的大多数内容被限定在只是Javascript这个语言本身;
如果你想了解Javascript是如何在网页中被应用的,那么可以查看
[Document Object
Model](https://developer.mozilla.org/en-US/docs/Using_the_W3C_DOM_Level_1_Core)
+[Learn Javascript by Example and with Challenges](http://www.learneroo.com/modules/64/nodes/350) 是本参考的另一个版本,并包含了挑战习题。
+
[Javascript Garden](http://bonsaiden.github.io/JavaScript-Garden/) 是一个深入
-讲解所有Javascript反直觉部分的一本书
+讲解所有Javascript反直觉部分的导引。
+
+[JavaScript: The Definitive Guide](http://www.amazon.com/gp/product/0596805527/) 是一个经典的指导参考书。
除了这篇文章的直接贡献者之外,这篇文章也参考了这个网站上
Louie Dinh 的 Python 教程,以及 Mozilla开发者网络上的[JS
-Tutorial](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript)
+Tutorial](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript)。
diff --git a/zh-cn/swift-cn.html.markdown b/zh-cn/swift-cn.html.markdown
index 35f73dee..28001e3f 100644
--- a/zh-cn/swift-cn.html.markdown
+++ b/zh-cn/swift-cn.html.markdown
@@ -5,223 +5,587 @@ contributors:
- ["Grant Timmerman", "http://github.com/grant"]
translators:
- ["Xavier Yao", "http://github.com/xavieryao"]
+ - ["Joey Huang", "http://github.com/kamidox"]
lang: zh-cn
---
-Swift 是Apple 开发的用于iOS 和OS X 开发的编程语言。Swift 于2014年Apple WWDC (全球开发者大会)中被引入,用以与Objective-C 共存,同时对错误代码更具弹性。Swift 由Xcode 6 beta 中包含的LLVM编译器编译。
+Swift 是 Apple 开发的用于 iOS 和 OS X 开发的编程语言。Swift 于2014年 Apple WWDC (全球开发者大会)中被引入,用以与 Objective-C 共存,同时对错误代码更具弹性。Swift 由 Xcode 6 beta 中包含的 LLVM 编译器编译。
-参阅:Apple's [getting started guide](https://developer.apple.com/library/prerelease/ios/referencelibrary/GettingStarted/RoadMapiOS/index.html) ——一个完整的Swift 教程
+Swift 的官方语言教程 [Swift Programming Language](https://itunes.apple.com/us/book/swift-programming-language/id881256329) 可以从 iBooks 免费下载.
+
+亦可参阅:Apple's [getting started guide](https://developer.apple.com/library/prerelease/ios/referencelibrary/GettingStarted/RoadMapiOS/index.html) ——一个完整的Swift 教程
```swift
-//
-// 基础
+// 导入外部模块
+import UIKit
+
+//
+// MARK: 基础
//
+// XCODE 支持给注释代码作标记,这些标记会列在 XCODE 的跳转栏里,支持的标记为
+// MARK: 普通标记
+// TODO: TODO 标记
+// FIXME: FIXME 标记
+
println("Hello, world")
+
+// 变量 (var) 的值设置后可以随意改变
+// 常量 (let) 的值设置后不能改变
var myVariable = 42
+let øπΩ = "value" // 可以支持 unicode 变量名
+let π = 3.1415926
let myConstant = 3.1415926
-let explicitDouble: Double = 70
-let label = "some text " + String(myVariable) // Casting
-let piText = "Pi = \(myConstant)" // String interpolation
-var optionalString: String? = "optional" // Can be nil
-optionalString = nil
+let explicitDouble: Double = 70 // 明确指定变量类型为 Double ,否则编译器将自动推断变量类型
+let weak = "keyword"; let override = "another keyword" // 语句之间可以用分号隔开,语句未尾不需要分号
+let intValue = 0007 // 7
+let largeIntValue = 77_000 // 77000
+let label = "some text " + String(myVariable) // 类型转换
+let piText = "Pi = \(π), Pi 2 = \(π * 2)" // 格式化字符串
+
+// 条件编译
+// 使用 -D 定义编译开关
+#if false
+ println("Not printed")
+ let buildValue = 3
+#else
+ let buildValue = 7
+#endif
+println("Build value: \(buildValue)") // Build value: 7
+
+/*
+ Optionals 是 Swift 的新特性,它允许你存储两种状态的值给 Optional 变量:有效值或 None
+
+ Swift 要求所有的 Optinal 属性都必须有明确的值,如果为空,则必须明确设定为 nil
+
+ Optional<T> 是个枚举类型
+*/
+var someOptionalString: String? = "optional" // 可以是 nil
+// 下面的语句和上面完全等价,上面的写法更推荐,因为它更简洁,问号 (?) 是 Swift 提供的语法糖
+var someOptionalString2: Optional<String> = "optional"
+
+if someOptionalString != nil {
+ // 变量不为空
+ if someOptionalString!.hasPrefix("opt") {
+ println("has the prefix")
+ }
+
+ let empty = someOptionalString?.isEmpty
+}
+someOptionalString = nil
+
+// 显式解包 optional 变量
+var unwrappedString: String! = "Value is expected."
+// 下面语句和上面完全等价,感叹号 (!) 是个后缀运算符,这也是个语法糖
+var unwrappedString2: ImplicitlyUnwrappedOptional<String> = "Value is expected."
+
+if let someOptionalStringConstant = someOptionalString {
+ // 由于变量 someOptinalString 有值,不为空,所以 if 条件为真
+ if !someOptionalStringConstant.hasPrefix("ok") {
+ // does not have the prefix
+ }
+}
+
+// Swift 支持可保存任何数据类型的变量
+// AnyObject == id
+// 和 Objective-C `id` 不一样, AnyObject 可以保存任何类型的值 (Class, Int, struct, 等)
+var anyObjectVar: AnyObject = 7
+anyObjectVar = "Changed value to a string, not good practice, but possible."
+
+/*
+ 这里是注释
+
+ /*
+ 支持嵌套的注释
+ */
+*/
//
-// 数组与字典(关联数组)
+// Mark: 数组与字典(关联数组)
//
-// 数组
+/*
+ Array 和 Dictionary 是结构体,不是类,他们作为函数参数时,是用值传递而不是指针传递。
+ 可以用 `var` 和 `let` 来定义变量和常量。
+*/
+
+// Array
var shoppingList = ["catfish", "water", "lemons"]
shoppingList[1] = "bottle of water"
-let emptyArray = String[]()
+let emptyArray = [String]() // 使用 let 定义常量,此时 emptyArray 数组不能添加或删除内容
+let emptyArray2 = Array<String>() // 与上一语句等价,上一语句更常用
+var emptyMutableArray = [String]() // 使用 var 定义变量,可以向 emptyMutableArray 添加数组元素
// 字典
var occupations = [
- "Malcolm": "Captain",
- "kaylee": "Mechanic"
+ "Malcolm": "Captain",
+ "kaylee": "Mechanic"
]
-occupations["Jayne"] = "Public Relations"
-let emptyDictionary = Dictionary<String, Float>()
+occupations["Jayne"] = "Public Relations" // 修改字典,如果 key 不存在,自动添加一个字典元素
+let emptyDictionary = [String: Float]() // 使用 let 定义字典常量,字典常量不能修改里面的值
+let emptyDictionary2 = Dictionary<String, Float>() // 与上一语句类型等价,上一语句更常用
+var emptyMutableDictionary = [String: Float]() // 使用 var 定义字典变量
//
-// 控制流
+// MARK: 控制流
//
-// 用于数组的for 循环
+// 数组的 for 循环
let myArray = [1, 1, 2, 3, 5]
for value in myArray {
- if value == 1 {
- println("One!")
- } else {
- println("Not one!")
- }
+ if value == 1 {
+ println("One!")
+ } else {
+ println("Not one!")
+ }
}
-// 用于字典的for 循环
+// 字典的 for 循环
+var dict = ["one": 1, "two": 2]
for (key, value) in dict {
- println("\(key): \(value)")
+ println("\(key): \(value)")
}
-// 用于区间的for 循环
-for i in -1...1 { // [-1, 0, 1]
- println(i)
+// 区间的 loop 循环:其中 `...` 表示闭环区间,即[-1, 3];`..<` 表示半开闭区间,即[-1,3)
+for i in -1...shoppingList.count {
+ println(i)
}
-// 使用 .. 表示的区间不包含最后一个元素 [-1,0,1)
+shoppingList[1...2] = ["steak", "peacons"]
+// 可以使用 `..<` 来去掉最后一个元素
// while 循环
var i = 1
while i < 1000 {
- i *= 2
+ i *= 2
}
// do-while 循环
do {
- println("hello")
+ println("hello")
} while 1 == 2
-// Switch
+// Switch 语句
+// Swift 里的 Switch 语句功能异常强大,结合枚举类型,可以实现非常简洁的代码,可以把 switch 语句想象成 `if` 的语法糖
+// 它支持字符串,类实例或原生数据类型 (Int, Double, etc)
let vegetable = "red pepper"
switch vegetable {
case "celery":
- let vegetableComment = "Add some raisins and make ants on a log."
+ let vegetableComment = "Add some raisins and make ants on a log."
case "cucumber", "watercress":
- let vegetableComment = "That would make a good tea sandwich."
-case let x where x.hasSuffix("pepper"):
- let vegetableComment = "Is it a spicy \(x)?"
-default: // 必须 (为了覆盖所有可能的输入)
- let vegetableComment = "Everything tastes good in soup."
+ let vegetableComment = "That would make a good tea sandwich."
+case let localScopeValue where localScopeValue.hasSuffix("pepper"):
+ let vegetableComment = "Is it a spicy \(localScopeValue)?"
+default: // 在 Swift 里,switch 语句的 case 必须处理所有可能的情况,如果 case 无法全部处理,则必须包含 default语句
+ let vegetableComment = "Everything tastes good in soup."
}
//
-// 函数
+// MARK: 函数
//
-// 函数是一等类型,这意味着可以在函数中构建函数
-// 并且可以被传递
+// 函数是一个 first-class 类型,他们可以嵌套,可以作为函数参数传递
-// 函数
+// 函数文档可使用 reStructedText 格式直接写在函数的头部
+/**
+ A greet operation
+
+ - A bullet in docs
+ - Another bullet in the docs
+
+ :param: name A name
+ :param: day A day
+ :returns: A string containing the name and day value.
+*/
func greet(name: String, day: String) -> String {
- return "Hello \(name), today is \(day)."
+ return "Hello \(name), today is \(day)."
}
greet("Bob", "Tuesday")
-// 使用多元数组返回多返回值的函数
-func getGasPrices() -> (Double, Double, Double) {
- return (3.59, 3.69, 3.79)
+// 函数参数前带 `#` 表示外部参数名和内部参数名使用同一个名称。
+// 第二个参数表示外部参数名使用 `externalParamName` ,内部参数名使用 `localParamName`
+func greet2(#requiredName: String, externalParamName localParamName: String) -> String {
+ return "Hello \(requiredName), the day is \(localParamName)"
}
+greet2(requiredName:"John", externalParamName: "Sunday") // 调用时,使用命名参数来指定参数的值
-// 不定参数
-func setup(numbers: Int...) {}
+// 函数可以通过元组 (tuple) 返回多个值
+func getGasPrices() -> (Double, Double, Double) {
+ return (3.59, 3.69, 3.79)
+}
+let pricesTuple = getGasPrices()
+let price = pricesTuple.2 // 3.79
+// 通过下划线 (_) 来忽略不关心的值
+let (_, price1, _) = pricesTuple // price1 == 3.69
+println(price1 == pricesTuple.1) // true
+println("Gas price: \(price)")
+
+// 可变参数
+func setup(numbers: Int...) {
+ // 可变参数是个数组
+ let number = numbers[0]
+ let argCount = numbers.count
+}
-// 传递、返回函数
+// 函数变量以及函数作为返回值返回
func makeIncrementer() -> (Int -> Int) {
- func addOne(number: Int) -> Int {
- return 1 + number
- }
- return addOne
+ func addOne(number: Int) -> Int {
+ return 1 + number
+ }
+ return addOne
}
var increment = makeIncrementer()
increment(7)
+// 强制进行指针传递 (引用传递),使用 `inout` 关键字修饰函数参数
+func swapTwoInts(inout a: Int, inout b: Int) {
+ let tempA = a
+ a = b
+ b = tempA
+}
+var someIntA = 7
+var someIntB = 3
+swapTwoInts(&someIntA, &someIntB)
+println(someIntB) // 7
+
//
-// 闭包
+// MARK: 闭包
//
+var numbers = [1, 2, 6]
-// 函数是特殊的闭包({})
+// 函数是闭包的一个特例
-// 闭包示例.
-// `->` 分隔参数和返回类型
-// `in` 分隔闭包头和闭包体
+// 闭包实例
+// `->` 分隔了闭包的参数和返回值
+// `in` 分隔了闭包头 (包括参数及返回值) 和闭包体
+// 下面例子中,`map` 的参数是一个函数类型,它的功能是把数组里的元素作为参数,逐个调用 `map` 参数传递进来的函数。
numbers.map({
- (number: Int) -> Int in
- let result = 3 * number
- return result
- })
+ (number: Int) -> Int in
+ let result = 3 * number
+ return result
+})
-// 当类型已知时,可以这样做:
-var numbers = [1, 2, 6]
+// 当闭包的参数类型和返回值都是己知的情况下,且只有一个语句作为其返回值时,我们可以简化闭包的写法
numbers = numbers.map({ number in 3 * number })
+// 我们也可以使用 $0, $1 来指代第 1 个,第 2 个参数,上面的语句最终可简写为如下形式
+// numbers = numbers.map({ $0 * 3 })
+
+print(numbers) // [3, 6, 18]
+
+// 简洁的闭包
+numbers = sorted(numbers) { $0 > $1 }
+// 函数的最后一个参数可以放在括号之外,上面的语句是这个语句的简写形式
+// numbers = sorted(numbers, { $0 > $1 })
+
+print(numbers) // [18, 6, 3]
+
+// 超级简洁的闭包,因为 `<` 是个操作符函数
+numbers = sorted(numbers, < )
+
print(numbers) // [3, 6, 18]
//
-// 类
+// MARK: 结构体
//
-// 类的全部方法和属性都是public 的
-// 如果你在一个数据结构中只需储存数据,
-// 应使用 `struct`
+// 结构体和类非常类似,可以有属性和方法
-// 集成自`Shape` 类的简单的类`Square
-class Rect: Shape {
- var sideLength: Int = 1
-
- // Custom getter and setter property
- var perimeter: Int {
- get {
- return 4 * sideLength
- }
- set {
- sideLength = newValue / 4
+struct NamesTable {
+ let names = [String]()
+
+ // 自定义下标运算符
+ subscript(index: Int) -> String {
+ return names[index]
}
- }
+}
+
+// 结构体有一个自动生成的隐含的命名构造函数
+let namesTable = NamesTable(names: ["Me", "Them"])
+let name = namesTable[1]
+println("Name is \(name)") // Name is Them
+
+//
+// MARK: 类
+//
- init(sideLength: Int) {
- super.init()
- self.sideLength = sideLength
- }
+// 类和结构体的有三个访问控制级别,他们分别是 internal (默认), public, private
+// internal: 模块内部可以访问
+// public: 其他模块可以访问
+// private: 只有定义这个类或结构体的源文件才能访问
- func shrink() {
- if sideLength > 0 {
- --sideLength
+public class Shape {
+ public func getArea() -> Int {
+ return 0;
+ }
+}
+
+// 类的所有方法和属性都是 public 的
+// 如果你只是需要把数据保存在一个结构化的实例里面,应该用结构体
+
+internal class Rect: Shape {
+ // 值属性 (Stored properties)
+ var sideLength: Int = 1
+
+ // 计算属性 (Computed properties)
+ private var perimeter: Int {
+ get {
+ return 4 * sideLength
+ }
+ set {
+ // `newValue` 是个隐含的变量,它表示将要设置进来的新值
+ sideLength = newValue / 4
+ }
+ }
+
+ // 延时加载的属性,只有这个属性第一次被引用时才进行初始化,而不是定义时就初始化
+ // subShape 值为 nil ,直到 subShape 第一次被引用时才初始化为一个 Rect 实例
+ lazy var subShape = Rect(sideLength: 4)
+
+ // 监控属性值的变化。
+ // 当我们需要在属性值改变时做一些事情,可以使用 `willSet` 和 `didSet` 来设置监控函数
+ // `willSet`: 值改变之前被调用
+ // `didSet`: 值改变之后被调用
+ var identifier: String = "defaultID" {
+ // `willSet` 的参数是即将设置的新值,参数名可以指定,如果没有指定,就是 `newValue`
+ willSet(someIdentifier) {
+ println(someIdentifier)
+ }
+ // `didSet` 的参数是已经被覆盖掉的旧的值,参数名也可以指定,如果没有指定,就是 `oldValue`
+ didSet {
+ println(oldValue)
+ }
+ }
+
+ // 命名构造函数 (designated inits),它必须初始化所有的成员变量,
+ // 然后调用父类的命名构造函数继续初始化父类的所有变量。
+ init(sideLength: Int) {
+ self.sideLength = sideLength
+ // 必须显式地在构造函数最后调用父类的构造函数 super.init
+ super.init()
+ }
+
+ func shrink() {
+ if sideLength > 0 {
+ --sideLength
+ }
}
- }
+
+ // 函数重载使用 override 关键字
+ override func getArea() -> Int {
+ return sideLength * sideLength
+ }
+}
- override func getArea() -> Int {
- return sideLength * sideLength
- }
+// 类 `Square` 从 `Rect` 继承
+class Square: Rect {
+ // 便捷构造函数 (convenience inits) 是调用自己的命名构造函数 (designated inits) 的构造函数
+ // Square 自动继承了父类的命名构造函数
+ convenience init() {
+ self.init(sideLength: 5)
+ }
+ // 关于构造函数的继承,有以下几个规则:
+ // 1. 如果你没有实现任何命名构造函数,那么你就继承了父类的所有命名构造函数
+ // 2. 如果你重载了父类的所有命名构造函数,那么你就自动继承了所有的父类快捷构造函数
+ // 3. 如果你没有实现任何构造函数,那么你继承了父类的所有构造函数,包括命名构造函数和便捷构造函数
}
-var mySquare = new Square(sideLength: 5)
-print(mySquare.getArea()) // 25
+
+var mySquare = Square()
+println(mySquare.getArea()) // 25
mySquare.shrink()
-print(mySquare.sideLength) // 4
+println(mySquare.sideLength) // 4
+
+// 类型转换
+let aShape = mySquare as Shape
+
+// 使用三个等号来比较是不是同一个实例
+if mySquare === aShape {
+ println("Yep, it's mySquare")
+}
+
+class Circle: Shape {
+ var radius: Int
+ override func getArea() -> Int {
+ return 3 * radius * radius
+ }
+
+ // optional 构造函数,可能会返回 nil
+ init?(radius: Int) {
+ self.radius = radius
+ super.init()
+
+ if radius <= 0 {
+ return nil
+ }
+ }
+}
-// 如果你不需要自定义getter 和setter,
-// 但仍希望在获取或设置一个属性之前或之后运行
-// 一些代码,你可以使用`willSet` 和 `didSet`
+// 根据 Swift 类型推断,myCircle 是 Optional<Circle> 类型的变量
+var myCircle = Circle(radius: 1)
+println(myCircle?.getArea()) // Optional(3)
+println(myCircle!.getArea()) // 3
+var myEmptyCircle = Circle(radius: -1)
+println(myEmptyCircle?.getArea()) // "nil"
+if let circle = myEmptyCircle {
+ // 此语句不会输出,因为 myEmptyCircle 变量值为 nil
+ println("circle is not nil")
+}
//
-// 枚举类型
+// MARK: 枚举
//
-// 枚举类型可以是某种指定的类型,抑或自成一种类型
-// 像类一样,枚举类型可以包含方法
+// 枚举可以像类一样,拥有方法
enum Suit {
- case Spades, Hearts, Diamonds, Clubs
- func getIcon() -> String {
- switch self {
- case .Spades: return "♤"
- case .Hearts: return "♡"
- case .Diamonds: return "♢"
- case .Clubs: return "♧"
+ case Spades, Hearts, Diamonds, Clubs
+ func getIcon() -> String {
+ switch self {
+ case .Spades: return "♤"
+ case .Hearts: return "♡"
+ case .Diamonds: return "♢"
+ case .Clubs: return "♧"
+ }
}
- }
}
+// 当变量类型明确指定为某个枚举类型时,赋值时可以省略枚举类型
+var suitValue: Suit = .Hearts
+
+// 非整型的枚举类型需要在定义时赋值
+enum BookName: String {
+ case John = "John"
+ case Luke = "Luke"
+}
+println("Name: \(BookName.John.rawValue)")
+
+// 与特定数据类型关联的枚举
+enum Furniture {
+ // 和 Int 型数据关联的枚举记录
+ case Desk(height: Int)
+ // 和 String, Int 关联的枚举记录
+ case Chair(brand: String, height: Int)
+
+ func description() -> String {
+ switch self {
+ case .Desk(let height):
+ return "Desk with \(height) cm"
+ case .Chair(let brand, let height):
+ return "Chair of \(brand) with \(height) cm"
+ }
+ }
+}
+
+var desk: Furniture = .Desk(height: 80)
+println(desk.description()) // "Desk with 80 cm"
+var chair = Furniture.Chair(brand: "Foo", height: 40)
+println(chair.description()) // "Chair of Foo with 40 cm"
+
//
-// 其它
+// MARK: 协议
+// 与 Java 的 interface 类似
//
-// `协议(protocol)`: 与Java 的接口(Interface) 类似.
-// `扩展(extension)`: 为现有类型添加额外特性
-// 泛型: 与Java 相似。使用`where` 关键字指定
-// 泛型的要求.
+// 协议可以让遵循同一协议的类型实例拥有相同的属性,方法,类方法,操作符或下标运算符等
+// 下面代码定义一个协议,这个协议包含一个名为 enabled 的计算属性且包含 buildShape 方法
+protocol ShapeGenerator {
+ var enabled: Bool { get set }
+ func buildShape() -> Shape
+}
+
+// 协议声明时可以添加 @objc 前缀,添加 @objc 前缀后,
+// 可以使用 is, as, as? 等来检查协议兼容性
+// 需要注意,添加 @objc 前缀后,协议就只能被类来实现,
+// 结构体和枚举不能实现加了 @objc 的前缀
+// 只有添加了 @objc 前缀的协议才能声明 optional 方法
+// 一个类实现一个带 optional 方法的协议时,可以实现或不实现这个方法
+// optional 方法可以使用 optional 规则来调用
+@objc protocol TransformShape {
+ optional func reshaped()
+ optional func canReshape() -> Bool
+}
+
+class MyShape: Rect {
+ var delegate: TransformShape?
+
+ func grow() {
+ sideLength += 2
+
+ // 在 optional 属性,方法或下标运算符后面加一个问号,可以优雅地忽略 nil 值,返回 nil。
+ // 这样就不会引起运行时错误 (runtime error)
+ if let allow = self.delegate?.canReshape?() {
+ // 注意语句中的问号
+ self.delegate?.reshaped?()
+ }
+ }
+}
+
+
+//
+// MARK: 其它
+//
+
+// 扩展: 给一个已经存在的数据类型添加功能
+
+// 给 Square 类添加 `Printable` 协议的实现,现在其支持 `Printable` 协议
+extension Square: Printable {
+ var description: String {
+ return "Area: \(self.getArea()) - ID: \(self.identifier)"
+ }
+}
+
+println("Square: \(mySquare)") // Area: 16 - ID: defaultID
+
+// 也可以给系统内置类型添加功能支持
+extension Int {
+ var customProperty: String {
+ return "This is \(self)"
+ }
+
+ func multiplyBy(num: Int) -> Int {
+ return num * self
+ }
+}
+
+println(7.customProperty) // "This is 7"
+println(14.multiplyBy(3)) // 42
+
+// 泛型: 和 Java 及 C# 的泛型类似,使用 `where` 关键字来限制类型。
+// 如果只有一个类型限制,可以省略 `where` 关键字
+func findIndex<T: Equatable>(array: [T], valueToFind: T) -> Int? {
+ for (index, value) in enumerate(array) {
+ if value == valueToFind {
+ return index
+ }
+ }
+ return nil
+}
+let foundAtIndex = findIndex([1, 2, 3, 4], 3)
+println(foundAtIndex == 2) // true
+
+// 自定义运算符:
+// 自定义运算符可以以下面的字符打头:
+// / = - + * % < > ! & | ^ . ~
+// 甚至是 Unicode 的数学运算符等
+prefix operator !!! {}
+
+// 定义一个前缀运算符,使矩形的边长放大三倍
+prefix func !!! (inout shape: Square) -> Square {
+ shape.sideLength *= 3
+ return shape
+}
+
+// 当前值
+println(mySquare.sideLength) // 4
+
+// 使用自定义的 !!! 运算符来把矩形边长放大三倍
+!!!mySquare
+println(mySquare.sideLength) // 12
```
+