summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--asymptotic-notation.html.markdown139
-rw-r--r--c++.html.markdown12
-rw-r--r--c.html.markdown2
-rw-r--r--csharp.html.markdown123
-rw-r--r--css.html.markdown19
-rw-r--r--elixir.html.markdown5
-rw-r--r--es-es/haml-es.html.markdown159
-rw-r--r--git.html.markdown3
-rw-r--r--hack.html.markdown307
-rw-r--r--haskell.html.markdown53
-rw-r--r--java.html.markdown14
-rw-r--r--javascript.html.markdown66
-rw-r--r--nim.html.markdown14
-rw-r--r--objective-c.html.markdown23
-rw-r--r--ocaml.html.markdown17
-rw-r--r--perl6.html.markdown11
-rw-r--r--pt-br/c++-pt.html.markdown5
-rw-r--r--pt-br/swift-pt.html.markdown38
-rw-r--r--r.html.markdown8
-rw-r--r--racket.html.markdown48
-rw-r--r--ru-ru/json-ru.html.markdown61
-rw-r--r--ru-ru/lua-ru.html.markdown2
-rw-r--r--ru-ru/paren-ru.html.markdown196
-rw-r--r--ru-ru/python-ru.html.markdown109
-rw-r--r--ru-ru/python3-ru.html.markdown54
-rw-r--r--ru-ru/swift-ru.html.markdown589
-rw-r--r--ru-ru/xml-ru.html.markdown130
-rw-r--r--ruby.html.markdown17
-rw-r--r--scala.html.markdown2
-rw-r--r--swift.html.markdown61
-rwxr-xr-xtcl.html.markdown4
-rw-r--r--tmux.html.markdown2
-rw-r--r--typescript.html.markdown133
-rw-r--r--xml.html.markdown4
-rw-r--r--zh-cn/java-cn.html.markdown15
-rw-r--r--zh-cn/javascript-cn.html.markdown516
-rw-r--r--zh-cn/swift-cn.html.markdown590
37 files changed, 2935 insertions, 616 deletions
diff --git a/asymptotic-notation.html.markdown b/asymptotic-notation.html.markdown
new file mode 100644
index 00000000..e1f961f8
--- /dev/null
+++ b/asymptotic-notation.html.markdown
@@ -0,0 +1,139 @@
+---
+category: Algorithms & Data Structures
+name: Asymptotic Notation
+contributors:
+ - ["Jake Prather", "http://github.com/JakeHP"]
+---
+
+# Asymptotic Notations
+
+## What are they?
+
+Asymptotic Notations are languages that allow us to analyze an algorithm's running time by
+identifying its behavior as the input size for the algorithm increases. This is also known as
+an algorithm's growth rate. Does the algorithm suddenly become incredibly slow when the input
+size grows? Does it mostly maintain its quick run time as the input size increases?
+Asymptotic Notation gives us the ability to answer these questions.
+
+## Are there alternatives to answering these questions?
+
+One way would be to count the number of primitive operations at different input sizes.
+Though this is a valid solution, the amount of work this takes for even simple algorithms
+does not justify its use.
+
+Another way is to physically measure the amount of time an algorithm takes to complete
+given different input sizes. However, the accuracy and relativity (times obtained would
+only be relative to the machine they were computed on) of this method is bound to
+environmental variables such as computer hardware specifications, processing power, etc.
+
+## Types of Asymptotic Notation
+
+In the first section of this doc we described how an Asymptotic Notation identifies the
+behavior of an algorithm as the input size changes. Let us imagine an algorithm as a function
+f, n as the input size, and f(n) being the running time. So for a given algorithm f, with input
+size n you get some resultant run time f(n). This results in a graph where the Y axis is the
+runtime, X axis is the input size, and plot points are the resultants of the amount of time
+for a given input size.
+
+You can label a function, or algorithm, with an Asymptotic Notation in many different ways.
+Some examples are, you can describe an algorithm by its best case, worse case, or equivalent case.
+The most common is to analyze an algorithm by its worst case. You typically don't evaluate by best case because those conditions aren't what you're planning for. A very good example of this is sorting algorithms; specifically, adding elements to a tree structure. Best case for most algorithms could be as low as a single operation. However, in most cases, the element you're adding will need to be sorted appropriately through the tree, which could mean examining an entire branch. This is the worst case, and this is what we plan for.
+
+### Types of functions, limits, and simplification
+
+```
+Logarithmic Function - log n
+Linear Function - an + b
+Quadratic Function - an^2 + bn + c
+Polynomial Function - an^z + . . . + an^2 + a*n^1 + a*n^0, where z is some constant
+Exponential Function - a^n, where a is some constant
+```
+
+These are some basic function growth classifications used in various notations. The list starts at the slowest growing function (logarithmic, fastest execution time) and goes on to the fastest growing (exponential, slowest execution time). Notice that as 'n', or the input, increases in each of those functions, the result clearly increases much quicker in quadratic, polynomial, and exponential, compared to logarithmic and linear.
+
+One extremely important note is that for the notations about to be discussed you should do your best to use simplest terms. This means to disregard constants, and lower order terms, because as the input size (or n in our f(n)
+example) increases to infinity (mathematical limits), the lower order terms and constants are of little
+to no importance. That being said, if you have constants that are 2^9001, or some other ridiculous,
+unimaginable amount, realize that simplifying will skew your notation accuracy.
+
+Since we want simplest form, lets modify our table a bit...
+
+```
+Logarithmic - log n
+Linear - n
+Quadratic - n^2
+Polynomial - n^z, where z is some constant
+Exponential - a^n, where a is some constant
+```
+
+### 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).
+
+*Example 1*
+
+```
+f(n) = 3log n + 100
+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-O.
+
+```
+3log n + 100 <= c * log n
+```
+
+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-O has been met therefore `f(n)` is O(g(n)).
+
+*Example 2*
+
+```
+f(n) = 3*n^2
+g(n) = n
+```
+
+Is `f(n)` O(g(n))?
+Is `3 * n^2` O(n)?
+Let's look at the definition of Big-O.
+
+```
+3 * n^2 <= c * n
+```
+
+Is there some constant c that satisfies this for all n?
+No, there isn't. `f(n)` is NOT O(g(n)).
+
+### Big-Omega
+Big-Omega, commonly written as Ω, is an Asymptotic Notation for the best case, or a floor growth rate
+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-O is the primary notation used
+for general algorithm time complexity.
+
+### Ending Notes
+It's hard to keep this kind of topic short, and you should definitely go through the books and online
+resources listed. They go into much greater depth with definitions and examples.
+More where x='Algorithms & Data Structures' is on its way; we'll have a doc up on analyzing actual
+code examples soon.
+
+## Books
+
+* [Algorithms](http://www.amazon.com/Algorithms-4th-Robert-Sedgewick/dp/032157351X)
+* [Algorithm Design](http://www.amazon.com/Algorithm-Design-Foundations-Analysis-Internet/dp/0471383651)
+
+## Online Resources
+
+* [MIT](http://web.mit.edu/16.070/www/lecture/big_o.pdf)
+* [KhanAcademy](https://www.khanacademy.org/computing/computer-science/algorithms/asymptotic-notation/a/asymptotic-notation)
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/c.html.markdown b/c.html.markdown
index 7670824a..1696d28f 100644
--- a/c.html.markdown
+++ b/c.html.markdown
@@ -85,7 +85,7 @@ int main() {
// doubles are usually 64-bit floating-point numbers
double x_double = 0.0; // real numbers without any suffix are doubles
- // integer types may be unsigned (only positive)
+ // integer types may be unsigned (greater than or equal to zero)
unsigned short ux_short;
unsigned int ux_int;
unsigned long long ux_long_long;
diff --git a/csharp.html.markdown b/csharp.html.markdown
index 47dd9683..479b7f01 100644
--- a/csharp.html.markdown
+++ b/csharp.html.markdown
@@ -5,6 +5,7 @@ contributors:
- ["Max Yankov", "https://github.com/golergka"]
- ["Melvyn Laïly", "http://x2a.yt"]
- ["Shaun McCarthy", "http://www.shaunmccarthy.com"]
+ - ["Wouter Van Schandevijl", "http://github.com/laoujin"]
filename: LearnCSharp.cs
---
@@ -18,22 +19,29 @@ C# is an elegant and type-safe object-oriented language that enables developers
Multi-line comments look like this
*/
/// <summary>
-/// This is an XML documentation comment
+/// This is an XML documentation comment which can be used to generate external
+/// documentation or provide context help within an IDE
/// </summary>
+//public void MethodOrClassOrOtherWithParsableHelp() {}
-// Specify namespaces application will be using
+// Specify the namespaces this source code will be using
+// The namespaces below are all part of the standard .NET Framework Class Libary
using System;
using System.Collections.Generic;
-using System.Data.Entity;
using System.Dynamic;
using System.Linq;
-using System.Linq.Expressions;
using System.Net;
using System.Threading.Tasks;
using System.IO;
-// defines scope to organize code into "packages"
-namespace Learning
+// But this one is not:
+using System.Data.Entity;
+// In order to be able to use it, you need to add a dll reference
+// This can be done with the NuGet package manager: `Install-Package EntityFramework`
+
+// Namespaces define scope to organize code into "packages" or "modules"
+// Using this code from another source file: using Learning.CSharp;
+namespace Learning.CSharp
{
// Each .cs file should at least contain a class with the same name as the file
// you're allowed to do otherwise, but shouldn't for sanity.
@@ -125,7 +133,7 @@ on a new line! ""Wow!"", the masses cried";
// Use const or read-only to make a variable immutable
// const values are calculated at compile time
- const int HOURS_I_WORK_PER_WEEK = 9001;
+ const int HoursWorkPerWeek = 9001;
///////////////////////////////////////////////////
// Data Structures
@@ -242,8 +250,15 @@ on a new line! ""Wow!"", the masses cried";
int fooDoWhile = 0;
do
{
- //Iterated 100 times, fooDoWhile 0->99
+ // Start iteration 100 times, fooDoWhile 0->99
+ if (false)
+ continue; // skip the current iteration
+
fooDoWhile++;
+
+ if (fooDoWhile == 50)
+ break; // breaks from the loop completely
+
} while (fooDoWhile < 100);
//for loop structure => for(<start_statement>; <conditional>; <step>)
@@ -301,7 +316,7 @@ on a new line! ""Wow!"", the masses cried";
// Converting data
// Convert String To Integer
- // this will throw an Exception on failure
+ // this will throw a FormatException on failure
int.Parse("123");//returns an integer version of "123"
// try parse will default to type default on failure
@@ -315,6 +330,11 @@ on a new line! ""Wow!"", the masses cried";
Convert.ToString(123);
// or
tryInt.ToString();
+
+ // Casting
+ // Cast decimal 15 to a int
+ // and then implicitly cast to long
+ long x = (int) 15M;
}
///////////////////////////////////////
@@ -367,8 +387,12 @@ on a new line! ""Wow!"", the masses cried";
}
// Methods can have the same name, as long as the signature is unique
- public static void MethodSignatures(string maxCount)
+ // A method that differs only in return type is not unique
+ public static void MethodSignatures(
+ ref int maxCount, // Pass by reference
+ out int count)
{
+ count = 15; // out param must be assigned before control leaves the method
}
// GENERICS
@@ -400,6 +424,10 @@ on a new line! ""Wow!"", the masses cried";
MethodSignatures(3, 1, 3, "Some", "Extra", "Strings");
MethodSignatures(3, another: 3); // explicity set a parameter, skipping optional ones
+ // BY REF AND OUT PARAMETERS
+ int maxCount = 0, count; // ref params must have value
+ MethodSignatures(ref maxCount, out count);
+
// EXTENSION METHODS
int i = 3;
i.Print(); // Defined below
@@ -435,6 +463,31 @@ on a new line! ""Wow!"", the masses cried";
Func<int, int> square = (x) => x * x; // Last T item is the return value
Console.WriteLine(square(3)); // 9
+ // ERROR HANDLING - coping with an uncertain world
+ try
+ {
+ var funBike = PennyFarthing.CreateWithGears(6);
+
+ // will no longer execute because CreateWithGears throws an exception
+ string some = "";
+ if (true) some = null;
+ some.ToLower(); // throws a NullReferenceException
+ }
+ catch (NotSupportedException)
+ {
+ Console.WriteLine("Not so much fun now!");
+ }
+ catch (Exception ex) // catch all other exceptions
+ {
+ throw new ApplicationException("It hit the fan", ex);
+ // throw; // A rethrow that preserves the callstack
+ }
+ // catch { } // catch-all without capturing the Exception
+ finally
+ {
+ // executes after try or catch
+ }
+
// DISPOSABLE RESOURCES MANAGEMENT - let you handle unmanaged resources easily.
// Most of objects that access unmanaged resources (file handle, device contexts, etc.)
// implement the IDisposable interface. The using statement takes care of
@@ -595,10 +648,26 @@ on a new line! ""Wow!"", the masses cried";
public BikeBrand Brand; // After declaring an enum type, we can declare the field of this type
+ // Decorate an enum with the FlagsAttribute to indicate that multiple values can be switched on
+ [Flags] // Any class derived from Attribute can be used to decorate types, methods, parameters etc
+ public enum BikeAccessories
+ {
+ None = 0,
+ Bell = 1,
+ MudGuards = 2, // need to set the values manually!
+ Racks = 4,
+ Lights = 8,
+ FullPackage = Bell | MudGuards | Racks | Lights
+ }
+
+ // Usage: aBike.Accessories.HasFlag(Bicycle.BikeAccessories.Bell)
+ // Before .NET 4: (aBike.Accessories & Bicycle.BikeAccessories.Bell) == Bicycle.BikeAccessories.Bell
+ public BikeAccessories Accessories { get; set; }
+
// Static members belong to the type itself rather then specific object.
// You can access them without a reference to any object:
// Console.WriteLine("Bicycles created: " + Bicycle.bicyclesCreated);
- static public int BicyclesCreated = 0;
+ public static int BicyclesCreated { get; set; }
// readonly values are set at run time
// they can only be assigned upon declaration or in a constructor
@@ -682,7 +751,7 @@ on a new line! ""Wow!"", the masses cried";
// All though this is not entirely useful in this example, you
// could do bicycle[0] which yields "chris" to get the first passenger or
// bicycle[1] = "lisa" to set the passenger. (of this apparent quattrocycle)
- private string[] passengers = { "chris", "phil", "darren", "regina" }
+ private string[] passengers = { "chris", "phil", "darren", "regina" };
public string this[int i]
{
@@ -737,10 +806,17 @@ on a new line! ""Wow!"", the masses cried";
}
set
{
- throw new ArgumentException("You can't change gears on a PennyFarthing");
+ throw new InvalidOperationException("You can't change gears on a PennyFarthing");
}
}
+ public static PennyFarthing CreateWithGears(int gears)
+ {
+ var penny = new PennyFarthing(1, 1);
+ penny.Gear = gears; // Oops, can't do this!
+ return penny;
+ }
+
public override string Info()
{
string result = "PennyFarthing bicycle ";
@@ -784,7 +860,7 @@ on a new line! ""Wow!"", the masses cried";
/// EntityFramework Code First is awesome (similar to Ruby's ActiveRecord, but bidirectional)
/// http://msdn.microsoft.com/en-us/data/jj193542.aspx
/// </summary>
- public class BikeRepository : DbSet
+ public class BikeRepository : DbContext
{
public BikeRepository()
: base()
@@ -798,13 +874,15 @@ on a new line! ""Wow!"", the masses cried";
## Topics Not Covered
- * Flags
* Attributes
- * Static properties
- * Exceptions, Abstraction
- * ASP.NET (Web Forms/MVC/WebMatrix)
- * Winforms
- * Windows Presentation Foundation (WPF)
+ * async/await, yield, pragma directives
+ * Web Development
+ * ASP.NET MVC & WebApi (new)
+ * ASP.NET Web Forms (old)
+ * WebMatrix (tool)
+ * Desktop Development
+ * Windows Presentation Foundation (WPF) (new)
+ * Winforms (old)
## Further Reading
@@ -817,7 +895,4 @@ on a new line! ""Wow!"", the masses cried";
* [ASP.NET Web Matrix Tutorials](http://www.asp.net/web-pages/tutorials)
* [ASP.NET Web Forms Tutorials](http://www.asp.net/web-forms/tutorials)
* [Windows Forms Programming in C#](http://www.amazon.com/Windows-Forms-Programming-Chris-Sells/dp/0321116208)
-
-
-
-[C# Coding Conventions](http://msdn.microsoft.com/en-us/library/vstudio/ff926074.aspx)
+ * [C# Coding Conventions](http://msdn.microsoft.com/en-us/library/vstudio/ff926074.aspx)
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/elixir.html.markdown b/elixir.html.markdown
index 0a20e3df..fb5f183a 100644
--- a/elixir.html.markdown
+++ b/elixir.html.markdown
@@ -91,6 +91,11 @@ string.
<<1,2,3>> <> <<4,5>> #=> <<1,2,3,4,5>>
"hello " <> "world" #=> "hello world"
+# Ranges are represented as `start..end` (both inclusive)
+1..10 #=> 1..10
+lower..upper = 1..10 # Can use pattern matching on ranges as well
+[lower, upper] #=> [1, 10]
+
## ---------------------------
## -- Operators
## ---------------------------
diff --git a/es-es/haml-es.html.markdown b/es-es/haml-es.html.markdown
new file mode 100644
index 00000000..be90b8f3
--- /dev/null
+++ b/es-es/haml-es.html.markdown
@@ -0,0 +1,159 @@
+---
+language: haml
+filename: learnhaml-es.haml
+contributors:
+ - ["Simon Neveu", "https://github.com/sneveu"]
+translators:
+ - ["Camilo Garrido", "http://www.twitter.com/hirohope"]
+lang: es-es
+---
+
+Haml es un lenguage de marcas principalmente usado con Ruby, que de forma simple y limpia describe el HTML de cualquier documento web sin el uso de código en linea. Es una alternativa popular respecto a usar el lenguage de plantilla de Rails (.erb) y te permite embeber código Ruby en tus anotaciones.
+
+Apunta a reducir la repetición en tus anotaciones cerrando los tags por ti, basándose en la estructura de identación de tu código. El resultado es una anotación bien estructurada, que no se repite, lógica y fácil de leer.
+
+También puedes usar Haml en un proyecto independiente de Ruby, instalando la gema Haml en tu máquina y usando la línea de comandos para convertirlo en html.
+
+$ haml archivo_entrada.haml archivo_salida.html
+
+
+```haml
+/ -------------------------------------------
+/ Identación
+/ -------------------------------------------
+
+/
+ Por la importancia que la identación tiene en cómo tu código es traducido,
+ la identación debe ser consistente a través de todo el documento. Cualquier
+ diferencia en la identación lanzará un error. Es una práctica común usar dos
+ espacios, pero realmente depende de tí, mientras sea consistente.
+
+
+/ -------------------------------------------
+/ Comentarios
+/ -------------------------------------------
+
+/ Así es como un comentario se ve en Haml.
+
+/
+ Para escribir un comentario multilínea, identa tu código a comentar de tal forma
+ que sea envuelto por por una barra.
+
+
+-# Este es un comentario silencioso, significa que no será traducido al código en absoluto
+
+
+/ -------------------------------------------
+/ Elementos Html
+/ -------------------------------------------
+
+/ Para escribir tus tags, usa el signo de porcentaje seguido por el nombre del tag
+%body
+ %header
+ %nav
+
+/ Nota que no hay tags de cierre. El código anterior se traduciría como
+ <body>
+ <header>
+ <nav></nav>
+ </header>
+ </body>
+
+/ El tag div es un elemento por defecto, por lo que pueden ser escritos simplemente así
+.foo
+
+/ Para añadir contenido a un tag, añade el texto directamente después de la declaración
+%h1 Headline copy
+
+/ Para escribir contenido multilínea, anídalo.
+%p
+ Esto es mucho contenido que podríamos dividirlo en dos
+ líneas separadas.
+
+/
+ Puedes escapar html usando el signo ampersand y el signo igual ( &= ).
+ Esto convierte carácteres sensibles en html a su equivalente codificado en html.
+ Por ejemplo
+
+%p
+ &= "Sí & si"
+
+/ se traduciría en 'Sí &amp; si'
+
+/ Puedes desescapar html usando un signo de exclamación e igual ( != )
+%p
+ != "Así es como se escribe un tag párrafo <p></p>"
+
+/ se traduciría como 'Así es como se escribe un tag párrafo <p></p>'
+
+/ Clases CSS puedes ser añadidas a tus tags, ya sea encadenando .nombres-de-clases al tag
+%div.foo.bar
+
+/ o como parte de un hash Ruby
+%div{:class => 'foo bar'}
+
+/ Atributos para cualquier tag pueden ser añadidos en el hash
+%a{:href => '#', :class => 'bar', :title => 'Bar'}
+
+/ Para atributos booleanos asigna el valor verdadero 'true'
+%input{:selected => true}
+
+/ Para escribir atributos de datos, usa la llave :dato con su valor como otro hash
+%div{:data => {:attribute => 'foo'}}
+
+
+/ -------------------------------------------
+/ Insertando Ruby
+/ -------------------------------------------
+
+/
+ Para producir un valor Ruby como contenido de un tag, usa un signo igual
+ seguido por código Ruby
+
+%h1= libro.nombre
+
+%p
+ = libro.autor
+ = libro.editor
+
+
+/ Para correr un poco de código Ruby sin traducirlo en html, usa un guión
+- libros = ['libro 1', 'libro 2', 'libro 3']
+
+/ Esto te permite hacer todo tipo de cosas asombrosas, como bloques de Ruby
+- libros.shuffle.each_with_index do |libro, indice|
+ %h1= libro
+
+ if libro do
+ %p Esto es un libro
+
+/
+ Nuevamente, no hay necesidad de añadir los tags de cerrado en el código, ni siquiera para Ruby
+ La identación se encargará de ello por tí.
+
+
+/ -------------------------------------------
+/ Ruby en linea / Interpolación de Ruby
+/ -------------------------------------------
+
+/ Incluye una variable Ruby en una línea de texto plano usando #{}
+%p Tu juego con puntaje más alto es #{mejor_juego}
+
+
+/ -------------------------------------------
+/ Filtros
+/ -------------------------------------------
+
+/
+ Usa un signo dos puntos para definir filtros Haml, un ejemplo de filtro que
+ puedes usar es :javascript, el cual puede ser usado para escribir javascript en línea.
+
+:javascript
+ console.log('Este es un <script> en linea');
+
+```
+
+## Recusros adicionales
+
+- [¿Qué es HAML? (en inglés)](http://haml.info/) - Una buena introducción que hace mejor el trabajo de explicar los beneficios de usar haml.
+- [Documentación Oficial (en inglés)](http://haml.info/docs/yardoc/file.REFERENCE.html) - Si deseas ir un poco más profundo.
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 748a29da..2f807c5f 100644
--- a/haskell.html.markdown
+++ b/haskell.html.markdown
@@ -59,6 +59,7 @@ not False -- True
"Hello " ++ "world!" -- "Hello world!"
-- A string is a list of characters
+['H', 'e', 'l', 'l', 'o'] -- "Hello"
"This is a string" !! 0 -- 'T'
@@ -67,10 +68,21 @@ not False -- True
----------------------------------------------------
-- Every element in a list must have the same type.
--- Two lists that are the same
+-- These two lists are the same:
[1, 2, 3, 4, 5]
[1..5]
+-- Ranges are versatile.
+['A'..'F'] -- "ABCDEF"
+
+-- You can create a step in a range.
+[0,2..10] -- [0, 2, 4, 6, 8, 10]
+[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
@@ -90,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]
@@ -139,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)
@@ -172,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
@@ -310,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
@@ -330,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/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 aabd5e43..588ea86d 100644
--- a/javascript.html.markdown
+++ b/javascript.html.markdown
@@ -110,19 +110,19 @@ null === undefined; // = false
13 + !0; // 14
"13" + !0; // '13true'
-// You can access characters in a string with charAt
+// You can access characters in a string with `charAt`
"This is a string".charAt(0); // = 'T'
-// ...or use substring to get larger pieces
+// ...or use `substring` to get larger pieces.
"Hello world".substring(0, 5); // = "Hello"
-// length is a property, so don't use ()
+// `length` is a property, so don't use ().
"Hello".length; // = 5
-// There's also null and undefined
-null; // used to indicate a deliberate non-value
+// There's also `null` and `undefined`.
+null; // used to indicate a deliberate non-value
undefined; // used to indicate a value is not currently present (although
- // undefined is actually a value itself)
+ // `undefined` is actually a value itself)
// false, null, undefined, NaN, 0 and "" are falsy; everything else is truthy.
// Note that 0 is falsy and "0" is truthy, even though 0 == "0".
@@ -130,8 +130,9 @@ undefined; // used to indicate a value is not currently present (although
///////////////////////////////////
// 2. Variables, Arrays and Objects
-// Variables are declared with the var keyword. JavaScript is dynamically typed,
-// so you don't need to specify type. Assignment uses a single = character.
+// Variables are declared with the `var` keyword. JavaScript is dynamically
+// typed, so you don't need to specify type. Assignment uses a single `=`
+// character.
var someVar = 5;
// if you leave the var keyword off, you won't get an error...
@@ -165,7 +166,7 @@ myArray.length; // = 4
// Add/Modify at specific index
myArray[3] = "Hello";
-// JavaScript's objects are equivalent to 'dictionaries' or 'maps' in other
+// JavaScript's objects are equivalent to "dictionaries" or "maps" in other
// languages: an unordered collection of key-value pairs.
var myObj = {key1: "Hello", key2: "World"};
@@ -190,7 +191,7 @@ myObj.myFourthKey; // = undefined
// The syntax for this section is almost identical to Java's.
-// The if structure works as you'd expect.
+// The `if` structure works as you'd expect.
var count = 1;
if (count == 3){
// evaluated if count is 3
@@ -200,18 +201,18 @@ if (count == 3){
// evaluated if it's not either 3 or 4
}
-// As does while.
+// As does `while`.
while (true){
// An infinite loop!
}
// Do-while loops are like while loops, except they always run at least once.
-var input
+var input;
do {
input = getInput();
} while (!isValid(input))
-// the for loop is the same as C and Java:
+// The `for` loop is the same as C and Java:
// initialisation; continue condition; iteration.
for (var i = 0; i < 5; i++){
// will run 5 times
@@ -229,7 +230,7 @@ if (colour == "red" || colour == "blue"){
var name = otherName || "default";
-// switch statement checks for equality with ===
+// The `switch` statement checks for equality with `===`.
// use 'break' after each case
// or the cases after the correct one will be executed too.
grade = 'B';
@@ -252,14 +253,14 @@ switch (grade) {
///////////////////////////////////
// 4. Functions, Scope and Closures
-// JavaScript functions are declared with the function keyword.
+// JavaScript functions are declared with the `function` keyword.
function myFunction(thing){
return thing.toUpperCase();
}
myFunction("foo"); // = "FOO"
// Note that the value to be returned must start on the same line as the
-// 'return' keyword, otherwise you'll always return 'undefined' due to
+// `return` keyword, otherwise you'll always return `undefined` due to
// automatic semicolon insertion. Watch out for this when using Allman style.
function myFunction()
{
@@ -298,8 +299,8 @@ i; // = 5 - not undefined as you'd expect in a block-scoped language
// scope.
(function(){
var temporary = 5;
- // We can access the global scope by assiging to the 'global object', which
- // in a web browser is always 'window'. The global object may have a
+ // We can access the global scope by assiging to the "global object", which
+ // in a web browser is always `window`. The global object may have a
// different name in non-browser environments such as Node.js.
window.permanent = 10;
})();
@@ -312,7 +313,7 @@ permanent; // = 10
function sayHelloInFiveSeconds(name){
var prompt = "Hello, " + name + "!";
// Inner functions are put in the local scope by default, as if they were
- // declared with 'var'.
+ // declared with `var`.
function inner(){
alert(prompt);
}
@@ -320,7 +321,7 @@ function sayHelloInFiveSeconds(name){
// setTimeout is asynchronous, so the sayHelloInFiveSeconds function will
// exit immediately, and setTimeout will call inner afterwards. However,
// because inner is "closed over" sayHelloInFiveSeconds, inner still has
- // access to the 'prompt' variable when it is finally called.
+ // access to the `prompt` variable when it is finally called.
}
sayHelloInFiveSeconds("Adam"); // will open a popup with "Hello, Adam!" in 5s
@@ -336,7 +337,7 @@ var myObj = {
myObj.myFunc(); // = "Hello world!"
// When functions attached to an object are called, they can access the object
-// they're attached to using the this keyword.
+// they're attached to using the `this` keyword.
myObj = {
myString: "Hello world!",
myFunc: function(){
@@ -352,7 +353,7 @@ var myFunc = myObj.myFunc;
myFunc(); // = undefined
// Inversely, a function can be assigned to the object and gain access to it
-// through this, even if it wasn't attached when it was defined.
+// through `this`, even if it wasn't attached when it was defined.
var myOtherFunc = function(){
return this.myString.toUpperCase();
}
@@ -360,37 +361,38 @@ myObj.myOtherFunc = myOtherFunc;
myObj.myOtherFunc(); // = "HELLO WORLD!"
// We can also specify a context for a function to execute in when we invoke it
-// using 'call' or 'apply'.
+// using `call` or `apply`.
var anotherFunc = function(s){
return this.myString + s;
}
anotherFunc.call(myObj, " And Hello Moon!"); // = "Hello World! And Hello Moon!"
-// The 'apply' function is nearly identical, but takes an array for an argument list.
+// The `apply` function is nearly identical, but takes an array for an argument
+// list.
anotherFunc.apply(myObj, [" And Hello Sun!"]); // = "Hello World! And Hello Sun!"
-// This is useful when working with a function that accepts a sequence of arguments
-// and you want to pass an array.
+// This is useful when working with a function that accepts a sequence of
+// arguments and you want to pass an array.
Math.min(42, 6, 27); // = 6
Math.min([42, 6, 27]); // = NaN (uh-oh!)
Math.min.apply(Math, [42, 6, 27]); // = 6
-// But, 'call' and 'apply' are only temporary. When we want it to stick, we can use
-// bind.
+// But, `call` and `apply` are only temporary. When we want it to stick, we can
+// use `bind`.
var boundFunc = anotherFunc.bind(myObj);
boundFunc(" And Hello Saturn!"); // = "Hello World! And Hello Saturn!"
-// Bind can also be used to partially apply (curry) a function.
+// `bind` can also be used to partially apply (curry) a function.
var product = function(a, b){ return a * b; }
var doubler = product.bind(this, 2);
doubler(8); // = 16
-// When you call a function with the new keyword, a new object is created, and
+// When you call a function with the `new` keyword, a new object is created, and
// made available to the function via the this keyword. Functions designed to be
// called like that are called constructors.
@@ -405,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!"
@@ -436,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/objective-c.html.markdown b/objective-c.html.markdown
index caad49a5..56640a87 100644
--- a/objective-c.html.markdown
+++ b/objective-c.html.markdown
@@ -55,7 +55,7 @@ int main (int argc, const char * argv[])
id myObject2 = nil; // Weak typing
// %@ is an object
// 'description' is a convention to display the value of the Objects
- NSLog(@"%@ and %@", myObject1, [myObject2 description]); // Print "(null) and (null)"
+ NSLog(@"%@ and %@", myObject1, [myObject2 description]); // prints => "(null) and (null)"
// String
NSString *worldString = @"World";
@@ -128,9 +128,10 @@ int main (int argc, const char * argv[])
// May contain different data types, but must be an Objective-C object
NSArray *anArray = @[@1, @2, @3, @4];
NSNumber *thirdNumber = anArray[2];
- NSLog(@"Third number = %@", thirdNumber); // Print "Third number = 3"
- // NSMutableArray is mutable version of NSArray allowing to change items in array
- // and extend or shrink array object. Convenient, but not as efficient as NSArray
+ NSLog(@"Third number = %@", thirdNumber); // prints => "Third number = 3"
+ // NSMutableArray is a mutable version of NSArray, allowing you to change
+ // the items in the array and to extend or shrink the array object.
+ // Convenient, but not as efficient as NSArray.
NSMutableArray *mutableArray = [NSMutableArray arrayWithCapacity:2];
[mutableArray addObject:@"Hello"];
[mutableArray addObject:@"World"];
@@ -140,7 +141,7 @@ int main (int argc, const char * argv[])
// Dictionary object
NSDictionary *aDictionary = @{ @"key1" : @"value1", @"key2" : @"value2" };
NSObject *valueObject = aDictionary[@"A Key"];
- NSLog(@"Object = %@", valueObject); // Print "Object = (null)"
+ NSLog(@"Object = %@", valueObject); // prints => "Object = (null)"
// NSMutableDictionary also available as a mutable dictionary object
NSMutableDictionary *mutableDictionary = [NSMutableDictionary dictionaryWithCapacity:2];
[mutableDictionary setObject:@"value1" forKey:@"key1"];
@@ -210,7 +211,7 @@ int main (int argc, const char * argv[])
while (ii < 4)
{
NSLog(@"%d,", ii++); // ii++ increments ii in-place, after using its value
- } // => prints "0,"
+ } // prints => "0,"
// "1,"
// "2,"
// "3,"
@@ -220,7 +221,7 @@ int main (int argc, const char * argv[])
for (jj=0; jj < 4; jj++)
{
NSLog(@"%d,", jj);
- } // => prints "0,"
+ } // prints => "0,"
// "1,"
// "2,"
// "3,"
@@ -230,7 +231,7 @@ int main (int argc, const char * argv[])
for (NSNumber *value in values)
{
NSLog(@"%@,", value);
- } // => prints "0,"
+ } // prints => "0,"
// "1,"
// "2,"
// "3,"
@@ -238,7 +239,7 @@ int main (int argc, const char * argv[])
// Object for loop statement. Can be used with any Objective-C object type
for (id item in values) {
NSLog(@"%@,", item);
- } // => prints "0,"
+ } // prints => "0,"
// "1,"
// "2,"
// "3,"
@@ -255,7 +256,7 @@ int main (int argc, const char * argv[])
} @finally
{
NSLog(@"Finally. Time to clean up.");
- } // => prints "Exception: File Not Found on System"
+ } // prints => "Exception: File Not Found on System"
// "Finally. Time to clean up."
// NSError objects are useful for function arguments to populate on user mistakes.
@@ -627,7 +628,7 @@ int main (int argc, const char * argv[]) {
@end
// Instances of Car now have access to the protocol.
Car *carInstance = [[Car alloc] init];
-[[carInstance setEngineOn:NO];
+[carInstance setEngineOn:NO];
[carInstance turnOnEngine];
if ([carInstance engineOn]) {
NSLog(@"Car engine is on."); // prints => "Car engine is on."
diff --git a/ocaml.html.markdown b/ocaml.html.markdown
index f9db7080..b0027fea 100644
--- a/ocaml.html.markdown
+++ b/ocaml.html.markdown
@@ -144,11 +144,16 @@ x + y ;;
(* Alternatively you can use "let ... and ... in" construct.
This is especially useful for mutually recursive functions,
with ordinary "let .. in" the compiler will complain about
- unbound values.
- It's hard to come up with a meaningful but self-contained
- example of mutually recursive functions, but that syntax
- works for non-recursive definitions too. *)
-let a = 3 and b = 4 in a * b ;;
+ unbound values. *)
+let rec
+ is_even = function
+ | 0 -> true
+ | n -> is_odd (n-1)
+and
+ is_odd = function
+ | 0 -> false
+ | n -> is_even (n-1)
+;;
(* Anonymous functions use the following syntax: *)
let my_lambda = fun x -> x * x ;;
@@ -288,7 +293,7 @@ type int_list_list = int list_of_lists ;;
(* Types can also be recursive. Like in this type analogous to
built-in list of integers. *)
type my_int_list = EmptyList | IntList of int * my_int_list ;;
-let l = Cons (1, EmptyList) ;;
+let l = IntList (1, EmptyList) ;;
(*** Pattern matching ***)
diff --git a/perl6.html.markdown b/perl6.html.markdown
index 13f383fe..1b320028 100644
--- a/perl6.html.markdown
+++ b/perl6.html.markdown
@@ -157,7 +157,6 @@ sub named-def(:$def = 5) {
say $def;
}
named-def; #=> 5
-named-def(:10def); #=> 10
named-def(def => 15); #=> 15
# Since you can omit parenthesis to call a function with no arguments,
@@ -202,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
@@ -284,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 $_";
@@ -653,7 +652,7 @@ class A {
has Int $!private-field = 10;
method get-value {
- $.field + $!private-field + $n;
+ $.field + $!private-field;
}
method set-value($n) {
@@ -671,7 +670,7 @@ class A {
# Create a new instance of A with $.field set to 5 :
# Note: you can't set private-field from here (more later on).
my $a = A.new(field => 5);
-$a.get-value; #=> 18
+$a.get-value; #=> 15
#$a.field = 5; # This fails, because the `has $.field` is immutable
$a.other-field = 10; # This, however, works, because the public field
# is mutable (`rw`).
@@ -964,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/c++-pt.html.markdown b/pt-br/c++-pt.html.markdown
index 243627cb..61625ebe 100644
--- a/pt-br/c++-pt.html.markdown
+++ b/pt-br/c++-pt.html.markdown
@@ -9,8 +9,7 @@ translators:
lang: pt-br
---
-C++ é uma linguagem de programação de sistemas que,
-C++ is a systems programming language that,
+C++ é uma linguagem de programação de sistemas que,
[de acordo com seu inventor Bjarne Stroustrup](http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2014/Keynote),
foi concebida para
@@ -588,4 +587,4 @@ Leitura Adicional:
Uma referência atualizada da linguagem pode ser encontrada em
<http://cppreference.com/w/cpp>
-Uma fonte adicional pode ser encontrada em <http://cplusplus.com> \ No newline at end of file
+Uma fonte adicional pode ser encontrada em <http://cplusplus.com>
diff --git a/pt-br/swift-pt.html.markdown b/pt-br/swift-pt.html.markdown
index a29490b0..72a57e4a 100644
--- a/pt-br/swift-pt.html.markdown
+++ b/pt-br/swift-pt.html.markdown
@@ -1,7 +1,7 @@
---
language: swift
contributors:
- - ["Grant Timmerman", "http://github.com/grant"],
+ - ["Grant Timmerman", "http://github.com/grant"]
- ["Christopher Bess", "http://github.com/cbess"]
translators:
- ["Mariane Siqueira Machado", "https://twitter.com/mariane_sm"]
@@ -9,14 +9,14 @@ lang: pt-br
filename: learnswift.swift
---
-Swift é uma linguagem de programação para desenvolvimento de aplicações no iOS e OS X criada pela Apple. Criada para
+Swift é uma linguagem de programação para desenvolvimento de aplicações no iOS e OS X criada pela Apple. Criada para
coexistir com Objective-C e para ser mais resiliente a código com erros, Swift foi apresentada em 2014 na Apple's
developer conference WWDC. Foi construída com o compilador LLVM já incluído no Xcode 6 beta.
O livro oficial [Swift Programming Language] (https://itunes.apple.com/us/book/swift-programming-language/id881256329) da
Apple já está disponível via IBooks (apenas em inglês).
-Confira também o tutorial completo de Swift da Apple [getting started guide](https://developer.apple.com/library/prerelease/ios/referencelibrary/GettingStarted/LandingPage/index.html), também disponível apenas em inglês.
+Confira também o tutorial completo de Swift da Apple [getting started guide](https://developer.apple.com/library/prerelease/ios/referencelibrary/GettingStarted/RoadMapiOS/index.html), também disponível apenas em inglês.
```swift
// importa um módulo
@@ -59,9 +59,9 @@ let piText = "Pi = \(π), Pi 2 = \(π * 2)" // Interpolação de strings
println("Build value: \(buildValue)") // Build value: 7
/*
- Optionals fazem parte da linguagem e permitem que você armazene um
+ Optionals fazem parte da linguagem e permitem que você armazene um
valor `Some` (algo) ou `None` (nada).
-
+
Como Swift requer que todas as propriedades tenham valores, até mesmo nil deve
ser explicitamente armazenado como um valor Optional.
@@ -76,7 +76,7 @@ if someOptionalString != nil {
if someOptionalString!.hasPrefix("opt") {
println("has the prefix")
}
-
+
let empty = someOptionalString?.isEmpty
}
someOptionalString = nil
@@ -289,7 +289,7 @@ print(numbers) // [3, 6, 18]
// Estruturas e classes tem funcionalidades muito similares
struct NamesTable {
let names: [String]
-
+
// Custom subscript
subscript(index: Int) -> String {
return names[index]
@@ -319,7 +319,7 @@ public class Shape {
internal class Rect: Shape {
var sideLength: Int = 1
-
+
// Getter e setter personalizado
private var perimeter: Int {
get {
@@ -330,13 +330,13 @@ internal class Rect: Shape {
sideLength = newValue / 4
}
}
-
+
// Carregue uma propriedade sob demanda (lazy)
// subShape permanece nil (não inicializado) até seu getter ser chamado
lazy var subShape = Rect(sideLength: 4)
-
+
// Se você não precisa de um getter e setter personalizado,
- // mas ainda quer roda código antes e depois de configurar
+ // mas ainda quer roda código antes e depois de configurar
// uma propriedade, você pode usar `willSet` e `didSet`
var identifier: String = "defaultID" {
// o argumento `willSet` será o nome da variável para o novo valor
@@ -344,25 +344,25 @@ internal class Rect: Shape {
print(someIdentifier)
}
}
-
+
init(sideLength: Int) {
self.sideLength = sideLength
// sempre chame super.init por último quand inicializar propriedades personalizadas (custom)
super.init()
}
-
+
func shrink() {
if sideLength > 0 {
--sideLength
}
}
-
+
override func getArea() -> Int {
return sideLength * sideLength
}
}
-// Uma classe básica `Square` que estende `Rect`
+// Uma classe básica `Square` que estende `Rect`
class Square: Rect {
convenience init() {
self.init(sideLength: 5)
@@ -420,10 +420,10 @@ protocol ShapeGenerator {
class MyShape: Rect {
var delegate: TransformShape?
-
+
func grow() {
sideLength += 2
-
+
if let allow = self.delegate?.canReshape?() {
// test for delegate then for method
// testa por delegação e então por método
@@ -439,7 +439,7 @@ class MyShape: Rect {
// `extension`s: Adicionam uma funcionalidade extra para um tipo já existente.
-// Square agora "segue" o protocolo `Printable`
+// Square agora "segue" o protocolo `Printable`
extension Square: Printable {
var description: String {
return "Area: \(self.getArea()) - ID: \(self.identifier)"
@@ -453,7 +453,7 @@ extension Int {
var customProperty: String {
return "This is \(self)"
}
-
+
func multiplyBy(num: Int) -> Int {
return num * self
}
diff --git a/r.html.markdown b/r.html.markdown
index c555d748..d3d725d3 100644
--- a/r.html.markdown
+++ b/r.html.markdown
@@ -229,6 +229,13 @@ FALSE != FALSE # FALSE
FALSE != TRUE # TRUE
# Missing data (NA) is logical, too
class(NA) # "logical"
+# Use | and & for logic operations.
+# OR
+TRUE | FALSE # TRUE
+# AND
+TRUE & FALSE # FALSE
+# You can test if x is TRUE
+isTRUE(TRUE) # TRUE
# Here we get a logical vector with many elements:
c('Z', 'o', 'r', 'r', 'o') == "Zorro" # FALSE FALSE FALSE FALSE FALSE
c('Z', 'o', 'r', 'r', 'o') == "Z" # TRUE FALSE FALSE FALSE FALSE
@@ -252,6 +259,7 @@ levels(infert$education) # "0-5yrs" "6-11yrs" "12+ yrs"
# NULL
# "NULL" is a weird one; use it to "blank out" a vector
class(NULL) # NULL
+parakeet = c("beak", "feathers", "wings", "eyes")
parakeet
# =>
# [1] "beak" "feathers" "wings" "eyes"
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/json-ru.html.markdown b/ru-ru/json-ru.html.markdown
new file mode 100644
index 00000000..52af3696
--- /dev/null
+++ b/ru-ru/json-ru.html.markdown
@@ -0,0 +1,61 @@
+---
+language: json
+filename: learnjson-ru.json
+contributors:
+ - ["Anna Harren", "https://github.com/iirelu"]
+ - ["Marco Scannadinari", "https://github.com/marcoms"]
+translators:
+ - ["Dmitry Bessonov", "https://github.com/TheDmitry"]
+lang: ru-ru
+---
+
+JSON - это очень простой формат обмена данными, и это будет самый легкий
+курс из когда-либо представленных "Learn X in Y Minutes".
+
+В чистом виде у JSON нет фактических комментариев, но большинство парсеров примут
+комментарии в Си-стиле (//, /\* \*/). Для таких целей, конечно, все правильно
+будет на 100% с точки зрения JSON. К счастью, в нашем случае данные скажут сами за себя.
+
+```json
+{
+ "ключ": "значение",
+
+ "ключи": "должны всегда заключаться в двойные кавычки",
+ "числа": 0,
+ "строки": "Пρивет, миρ. Допускаются все unicode-символы вместе с \"экранированием\".",
+ "содержит логический тип?": true,
+ "ничего": null,
+
+ "большое число": 1.2e+100,
+
+ "объекты": {
+ "комментарий": "Большинство ваших структур будут представлять из себя объекты.",
+
+ "массив": [0, 1, 2, 3, "Массивы могут содержать в себе любой тип.", 5],
+
+ "другой объект": {
+ "комментарий": "Они могут быть вложенными, и это очень полезно."
+ }
+ },
+
+ "бессмыслие": [
+ {
+ "источники калия": ["бананы"]
+ },
+ [
+ [1, 0, 0, 0],
+ [0, 1, 0, 0],
+ [0, 0, 1, "нео"],
+ [0, 0, 0, 1]
+ ]
+ ],
+
+ "альтернативный стиль": {
+ "комментарий": "проверьте это!"
+ , "позиция запятой": "неважна, хоть и перед значением, все равно правильно"
+ , "еще один комментарий": "как хорошо"
+ },
+
+ "это было недолго": "И вы справились. Теперь вы знаете все о JSON."
+}
+```
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/paren-ru.html.markdown b/ru-ru/paren-ru.html.markdown
new file mode 100644
index 00000000..9b801e46
--- /dev/null
+++ b/ru-ru/paren-ru.html.markdown
@@ -0,0 +1,196 @@
+---
+language: Paren
+filename: learnparen-ru.paren
+contributors:
+ - ["KIM Taegyoon", "https://github.com/kimtg"]
+translators:
+ - ["Dmitry Bessonov", "https://github.com/TheDmitry"]
+lang: ru-ru
+---
+
+[Paren](https://bitbucket.org/ktg/paren) - это диалект языка Лисп. Он спроектирован как встроенный язык.
+
+Примеры взяты <http://learnxinyminutes.com/docs/racket/>.
+
+```scheme
+;;; Комментарии
+# комментарии
+
+;; Однострочные комментарии начинаются с точки с запятой или символа решетки
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 1. Примитивные типы данных и операторы
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;;; Числа
+123 ; int
+3.14 ; double
+6.02e+23 ; double
+(int 3.14) ; => 3 : int
+(double 123) ; => 123 : double
+
+;; Обращение к функции записывается так: (f x y z ...),
+;; где f - функция, а x, y, z, ... - операнды
+;; Если вы хотите создать буквальный список данных, используйте (quote), чтобы
+;; предотвратить ненужные вычисления
+(quote (+ 1 2)) ; => (+ 1 2)
+;; Итак, некоторые арифметические операции
+(+ 1 1) ; => 2
+(- 8 1) ; => 7
+(* 10 2) ; => 20
+(^ 2 3) ; => 8
+(/ 5 2) ; => 2
+(% 5 2) ; => 1
+(/ 5.0 2) ; => 2.5
+
+;;; Логический тип
+true ; обозначает истину
+false ; обозначает ложь
+(! true) ; => false
+(&& true false (prn "досюда не доходим")) ; => false
+(|| false true (prn "досюда не доходим")) ; => true
+
+;;; Символы - это числа (int).
+(char-at "A" 0) ; => 65
+(chr 65) ; => "A"
+
+;;; Строки - это массив символов с фиксированной длиной.
+"Привет, мир!"
+"Benjamin \"Bugsy\" Siegel" ; обратная косая черта экранирует символ
+"Foo\tbar\r\n" ; включает управляющие символы в стиле Cи: \t \r \n
+
+;; Строки тоже могут объединяться!
+(strcat "Привет " "мир!") ; => "Привет мир!"
+
+;; Строка может трактоваться подобно списку символов
+(char-at "Apple" 0) ; => 65
+
+;; Выводить информацию достаточно легко
+(pr "Я" "Paren. ") (prn "Приятно познакомиться!")
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 2. Переменные
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Вы можете создать или инициализировать переменную, используя (set)
+;; имя переменной может содержать любой символ, исключая: ();#"
+(set some-var 5) ; => 5
+some-var ; => 5
+
+;; Обращение к переменной, прежде не определенной, вызовет исключение
+; x ; => Неизвестная переменная: x : nil
+
+;; Локальное связывание: Используйте лямбда-вычисление! `a' и `b' связывается
+;; с `1' и `2' только в пределах (fn ...)
+((fn (a b) (+ a b)) 1 2) ; => 3
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 3. Коллекции
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;;; Списки
+
+;; Списки подобны динамическому массиву (vector). (произвольный доступ равен O(1).)
+(cons 1 (cons 2 (cons 3 (list)))) ; => (1 2 3)
+;; `list' - это удобный конструктор списков с переменным числом элементов
+(list 1 2 3) ; => (1 2 3)
+;; и quote может также использоваться для литеральных значений списка
+(quote (+ 1 2)) ; => (+ 1 2)
+
+;; Можно еще использовать `cons', чтобы добавить элемент в начало списка
+(cons 0 (list 1 2 3)) ; => (0 1 2 3)
+
+;; Списки являются основным типом, поэтому для них предусмотрено *много* функций
+;; немного примеров из них:
+(map inc (list 1 2 3)) ; => (2 3 4)
+(filter (fn (x) (== 0 (% x 2))) (list 1 2 3 4)) ; => (2 4)
+(length (list 1 2 3 4)) ; => 4
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 3. Функции
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Используйте `fn' для создания функций.
+;; Функция всегда возвращает значение своего последнего выражения
+(fn () "Привет Мир") ; => (fn () Привет Мир) : fn
+
+;; Используйте скобки, чтобы вызвать все функции, в том числе лямбда-выражение
+((fn () "Привет Мир")) ; => "Привет Мир"
+
+;; Назначить функцию переменной
+(set hello-world (fn () "Привет Мир"))
+(hello-world) ; => "Привет Мир"
+
+;; Вы можете сократить это, используя синтаксический сахар определения функции:
+(defn hello-world2 () "Привет Мир")
+
+;; Как и выше, () - это список аргументов для функции
+(set hello
+ (fn (name)
+ (strcat "Привет " name)))
+(hello "Стив") ; => "Привет Стив"
+
+;; ... или, что эквивалентно, используйте синтаксический сахар определения:
+(defn hello2 (name)
+ (strcat "Привет " name))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 4. Равенство
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; для чисел используйте `=='
+(== 3 3.0) ; => true
+(== 2 1) ; => false
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 5. Поток управления
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;;; Условный оператор
+
+(if true ; проверка выражения
+ "это - истина" ; тогда это выражение
+ "это - ложь") ; иначе другое выражение
+; => "это - истина"
+
+;;; Циклы
+
+;; Цикл for для чисел
+;; (for ИДЕНТИФИКАТОР НАЧАЛО КОНЕЦ ШАГ ВЫРАЖЕНИЕ ..)
+(for i 0 10 2 (pr i "")) ; => печатает 0 2 4 6 8 10
+(for i 0.0 10 2.5 (pr i "")) ; => печатает 0 2.5 5 7.5 10
+
+;; Цикл while
+((fn (i)
+ (while (< i 10)
+ (pr i)
+ (++ i))) 0) ; => печатает 0123456789
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 6. Изменение
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Используйте `set', чтобы назначить новое значение переменной или памяти
+(set n 5) ; => 5
+(set n (inc n)) ; => 6
+n ; => 6
+(set a (list 1 2)) ; => (1 2)
+(set (nth 0 a) 3) ; => 3
+a ; => (3 2)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 7. Макросы
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Макросы позволяют вам расширять синтаксис языка.
+;; Paren-макросы легкие.
+;; Фактически, (defn) - это макрос.
+(defmacro setfn (name ...) (set name (fn ...)))
+(defmacro defn (name ...) (def name (fn ...)))
+
+;; Давайте добавим инфиксную нотацию
+(defmacro infix (a op ...) (op a ...))
+(infix 1 + 2 (infix 3 * 4)) ; => 15
+
+;; Макросы приводят к неясному коду, т.е. вы можете затереть существующие переменные!
+;; Они являются кодопреобразующей конструкцией.
+```
diff --git a/ru-ru/python-ru.html.markdown b/ru-ru/python-ru.html.markdown
index d59d3e21..a0e2b474 100644
--- a/ru-ru/python-ru.html.markdown
+++ b/ru-ru/python-ru.html.markdown
@@ -10,20 +10,20 @@ filename: learnpython-ru.py
---
Язык Python был создан Гвидо ван Россумом в начале 90-х. Сейчас это один из
-самых популярных языков. Я люблю его за понятный и доходчивый синтаксис — это
-почти что исполняемый псевдокод.
+самых популярных языков. Я влюбился в Python за понятный и доходчивый синтаксис — это
+почти исполняемый псевдокод.
С благодарностью жду ваших отзывов: [@louiedinh](http://twitter.com/louiedinh)
или louiedinh [at] [почтовый сервис Google]
-Замечание: Эта статья относится к Python 2.7, но должно работать и в Python 2.x.
-Скоро будет версия и для Python 3!
+Замечание: Эта статья относится к Python 2.7, но должно работать и в других версиях Python 2.x.
+Чтобы изучить Python 3.x, обратитесь к статье по Python 3.
```python
# Однострочные комментарии начинаются с символа решётки.
""" Многострочный текст может быть
записан, используя 3 знака " и обычно используется
- в качестве комментария
+ в качестве встроенной документации
"""
####################################################
@@ -43,7 +43,7 @@ filename: learnpython-ru.py
# целых чисел, и результат автоматически округляется в меньшую сторону.
5 / 2 #=> 2
-# Чтобы научиться делить, сначала нужно немного узнать о числах
+# Чтобы делить правильно, сначала нужно немного узнать о числах
# с плавающей запятой.
2.0 # Это число с плавающей запятой
11.0 / 4.0 #=> 2.75 Вооот... Так гораздо лучше
@@ -59,14 +59,22 @@ filename: learnpython-ru.py
7 % 3 # => 1
# Возведение в степень
-2 ** 4 # => 16
+2**4 # => 16
# Приоритет операций указывается скобками
(1 + 3) * 2 #=> 8
-# Логические (булевы) значения являются примитивами
-True
-False
+# Логические операторы
+# Обратите внимание: ключевые слова «and» и «or» чувствительны к регистру букв
+True and False #=> False
+False or True #=> True
+
+# Обратите внимание, что логические операторы используются и с целыми числами
+0 and 2 #=> 0
+-5 or 0 #=> -5
+0 == False #=> True
+2 == True #=> False
+1 == True #=> True
# Для отрицания используется ключевое слово not
not True #=> False
@@ -86,7 +94,7 @@ not False #=> True
2 <= 2 #=> True
2 >= 2 #=> True
-# Сравнения могут быть соединены в цепь!
+# Сравнения могут быть записаны цепочкой!
1 < 2 < 3 #=> True
2 < 3 < 2 #=> False
@@ -94,9 +102,12 @@ not False #=> True
"Это строка."
'Это тоже строка.'
-# И строки тоже могут складываться!
+# И строки тоже можно складывать!
"Привет " + "мир!" #=> "Привет мир!"
+# ... или умножать
+"Привет" * 3 # => "ПриветПриветПривет"
+
# Со строкой можно работать, как со списком символов
"Это строка"[0] #=> 'Э'
@@ -122,7 +133,7 @@ None is None #=> True
# очень полезен при работе с примитивными типами, но
# зато просто незаменим при работе с объектами.
-# None, 0, и пустые строки/списки равны False.
+# None, 0 и пустые строки/списки равны False.
# Все остальные значения равны True
0 == False #=> True
"" == False #=> True
@@ -132,12 +143,14 @@ None is None #=> True
## 2. Переменные и коллекции
####################################################
-# У Python есть функция Print, доступная в версиях 2.7 и 3,
-print("Я Python. Приятно познакомиться!")
-# ...и старый оператор print, доступный в версиях 2.x, но удалённый в версии 3.
-print "И я тоже Python!"
+# В Python есть оператор print, доступный в версиях 2.x, но удалённый в версии 3
+print "Я Python. Приятно познакомиться!"
+# В Python также есть функция print(), доступная в версиях 2.7 и 3,
+# Но для версии 2.7 нужно добавить следующий импорт модуля (раскомментируйте)):
+# from __future__ import print_function
+print("Я тоже Python! ")
-# Необязательно объявлять переменные перед их инициализацией.
+# Объявлять переменные перед инициализацией не нужно.
some_var = 5 # По соглашению используется нижний_регистр_с_подчёркиваниями
some_var #=> 5
@@ -151,7 +164,7 @@ some_other_var # Выбрасывает ошибку именования
# Списки хранят последовательности
li = []
-# Можно сразу начать с заполненным списком
+# Можно сразу начать с заполненного списка
other_li = [4, 5, 6]
# Объекты добавляются в конец списка методом append
@@ -166,13 +179,17 @@ li.append(3) # [1, 2, 4, 3].
# Обращайтесь со списком, как с обычным массивом
li[0] #=> 1
+# Присваивайте новые значения уже инициализированным индексам с помощью =
+li[0] = 42
+li[0] # => 42
+li[0] = 1 # Обратите внимание: возвращаемся на исходное значение
# Обратимся к последнему элементу
li[-1] #=> 3
# Попытка выйти за границы массива приведёт к ошибке индекса
li[4] # Выдаёт IndexError
-# Можно обращаться к диапазону, используя "кусочный синтаксис" (slice syntax)
+# Можно обращаться к диапазону, используя так называемые срезы
# (Для тех, кто любит математику, это называется замкнуто-открытый интервал).
li[1:3] #=> [2, 4]
# Опускаем начало
@@ -183,14 +200,15 @@ li[:3] #=> [1, 2, 4]
li[::2] # =>[1, 4]
# Переворачиваем список
li[::-1] # => [3, 4, 2, 1]
-# Используйте сочетания всего вышеназванного для выделения более сложных кусков
+# Используйте сочетания всего вышеназванного для выделения более сложных срезов
# li[начало:конец:шаг]
# Удаляем произвольные элементы из списка оператором del
-del li[2] # [1, 2, 3]
+del li[2] # li теперь [1, 2, 3]
-# Вы можете складывать списки
+# Вы можете складывать, или, как ещё говорят, конкатенировать списки
li + other_li #=> [1, 2, 3, 4, 5, 6] — Замечание: li и other_li не изменяются
+# Обратите внимание: значения li и other_li при этом не изменились.
# Объединять списки можно методом extend
li.extend(other_li) # Теперь li содержит [1, 2, 3, 4, 5, 6]
@@ -226,7 +244,8 @@ empty_dict = {}
# Вот так описывается предзаполненный словарь
filled_dict = {"one": 1, "two": 2, "three": 3}
-# Значения ищутся по ключу с помощью оператора []
+# Значения извлекаются так же, как из списка, с той лишь разницей,
+# что индекс — у словарей он называется ключом — не обязан быть числом
filled_dict["one"] #=> 1
# Можно получить все ключи в виде списка с помощью метода keys
@@ -245,24 +264,33 @@ filled_dict.values() #=> [3, 2, 1]
# Попытка получить значение по несуществующему ключу выбросит ошибку ключа
filled_dict["four"] # KeyError
-# Чтобы избежать этого, используйте метод get
+# Чтобы избежать этого, используйте метод get()
filled_dict.get("one") #=> 1
filled_dict.get("four") #=> None
# Метод get также принимает аргумент по умолчанию, значение которого будет
# возвращено при отсутствии указанного ключа
filled_dict.get("one", 4) #=> 1
filled_dict.get("four", 4) #=> 4
+# Обратите внимание, что filled_dict.get("four") всё ещё => None
+# (get не устанавливает значение элемента словаря)
+
+# Присваивайте значение ключам так же, как и в списках
+filled_dict["four"] = 4 # теперь filled_dict["four"] => 4
-# Метод setdefault вставляет пару ключ-значение, только если такого ключа нет
+# Метод setdefault вставляет() пару ключ-значение, только если такого ключа нет
filled_dict.setdefault("five", 5) #filled_dict["five"] возвращает 5
filled_dict.setdefault("five", 6) #filled_dict["five"] по-прежнему возвращает 5
# Множества содержат... ну, в общем, множества
+# (которые похожи на списки, только в них не может быть дублирующихся элементов)
empty_set = set()
# Инициализация множества набором значений
some_set = set([1,2,2,3,4]) # some_set теперь равно set([1, 2, 3, 4])
+# Порядок сортировки не гарантируется, хотя иногда они выглядят отсортированными
+another_set = set([4, 3, 2, 2, 1]) # another_set теперь set([1, 2, 3, 4])
+
# Начиная с Python 2.7, вы можете использовать {}, чтобы объявить множество
filled_set = {1, 2, 2, 3, 4} # => {1, 2, 3, 4}
@@ -345,7 +373,7 @@ try:
# Чтобы выбросить ошибку, используется raise
raise IndexError("Это ошибка индекса")
except IndexError as e:
- # pass это просто отсутствие оператора. Обычно здесь происходит
+ # pass — это просто отсутствие оператора. Обычно здесь происходит
# восстановление после ошибки.
pass
except (TypeError, NameError):
@@ -362,7 +390,7 @@ else: # Необязательное выражение. Должно след
# Используйте def для создания новых функций
def add(x, y):
print("x равен %s, а y равен %s" % (x, y))
- return x + y # Возвращайте результат выражением return
+ return x + y # Возвращайте результат с помощью ключевого слова return
# Вызов функции с аргументами
add(5, 6) #=> выводит «x равен 5, а y равен 6» и возвращает 11
@@ -370,15 +398,17 @@ add(5, 6) #=> выводит «x равен 5, а y равен 6» и возвр
# Другой способ вызова функции — вызов с именованными аргументами
add(y=6, x=5) # Именованные аргументы можно указывать в любом порядке.
-# Вы можете определить функцию, принимающую изменяемое число аргументов
+# Вы можете определить функцию, принимающую переменное число аргументов,
+# которые будут интерпретированы как кортеж, если вы не используете *
def varargs(*args):
return args
varargs(1, 2, 3) #=> (1,2,3)
-# А также можете определить функцию, принимающую изменяемое число
-# именованных аргументов
+# А также можете определить функцию, принимающую переменное число
+# именованных аргументов, которые будут интерпретированы как словарь,
+# если вы не используете **
def keyword_args(**kwargs):
return kwargs
@@ -396,13 +426,21 @@ all_the_args(1, 2, a=3, b=4) выводит:
"""
# Вызывая функции, можете сделать наоборот!
-# Используйте символ * для передачи кортежей и ** для передачи словарей
+# Используйте символ * для распаковки кортежей и ** для распаковки словарей
args = (1, 2, 3, 4)
kwargs = {"a": 3, "b": 4}
all_the_args(*args) # эквивалентно foo(1, 2, 3, 4)
all_the_args(**kwargs) # эквивалентно foo(a=3, b=4)
all_the_args(*args, **kwargs) # эквивалентно foo(1, 2, 3, 4, a=3, b=4)
+# вы можете передавать переменное число позиционных или именованных аргументов
+# другим функциям, которые их принимают, распаковывая их с помощью
+# * или ** соответственно
+def pass_all_the_args(*args, **kwargs):
+ all_the_args(*args, **kwargs)
+ print varargs(*args)
+ print keyword_args(**kwargs)
+
# Область определения функций
x = 5
@@ -420,7 +458,7 @@ def setGlobalX(num):
setX(43)
setGlobalX(6)
-# В Python есть функции первого класса
+# В Python функции — «объекты первого класса»
def create_adder(x):
def adder(y):
return x + y
@@ -514,6 +552,9 @@ from math import *
# Можете сокращать имена модулей
import math as m
math.sqrt(16) == m.sqrt(16) #=> True
+# Вы также можете убедиться, что функции эквивалентны
+from math import sqrt
+math.sqrt == m.sqrt == sqrt # => True
# Модули в Python — это обычные Python-файлы. Вы
# можете писать свои модули и импортировать их. Название
@@ -544,7 +585,7 @@ def double_numbers(iterable):
# мы используем подчёркивание в конце
xrange_ = xrange(1, 900000000)
-# Будет удваивать все числа, пока результат не будет >= 30
+# Будет удваивать все числа, пока результат не превысит 30
for i in double_numbers(xrange_):
print(i)
if i >= 30:
diff --git a/ru-ru/python3-ru.html.markdown b/ru-ru/python3-ru.html.markdown
index 637c0157..fd95c876 100644
--- a/ru-ru/python3-ru.html.markdown
+++ b/ru-ru/python3-ru.html.markdown
@@ -10,7 +10,7 @@ filename: learnpython3-ru.py
---
Язык Python был создан Гвидо ван Россумом в начале 90-х. Сейчас это один из
-самых популярных языков. Я люблю его за понятный и доходчивый синтаксис — это
+самых популярных языков. Я влюбился в Python за понятный и доходчивый синтаксис — это
почти что исполняемый псевдокод.
С благодарностью жду ваших отзывов: [@louiedinh](http://twitter.com/louiedinh)
@@ -56,7 +56,7 @@ filename: learnpython3-ru.py
7 % 3 # => 1
# Возведение в степень
-2 ** 4 # => 16
+2**4 # => 16
# Приоритет операций указывается скобками
(1 + 3) * 2 #=> 8
@@ -69,6 +69,18 @@ False
not True #=> False
not False #=> True
+# Логические операторы
+# Обратите внимание: ключевые слова «and» и «or» чувствительны к регистру букв
+True and False #=> False
+False or True #=> True
+
+# Обратите внимание, что логические операторы используются и с целыми числами
+0 and 2 #=> 0
+-5 or 0 #=> -5
+0 == False #=> True
+2 == True #=> False
+1 == True #=> True
+
# Равенство — это ==
1 == 1 #=> True
2 == 1 #=> False
@@ -91,7 +103,7 @@ not False #=> True
"Это строка."
'Это тоже строка.'
-# И строки тоже могут складываться! Хотя лучше этого не делайте.
+# И строки тоже могут складываться! Хотя лучше не злоупотребляйте этим.
"Привет " + "мир!" #=> "Привет мир!"
# Со строкой можно работать, как со списком символов
@@ -134,10 +146,10 @@ bool({}) #=> False
## 2. Переменные и коллекции
####################################################
-# У Python есть функция Print
+# В Python есть функция Print
print("Я Python. Приятно познакомиться!")
-# Необязательно объявлять переменные перед их инициализацией.
+# Объявлять переменные перед инициализацией не нужно.
# По соглашению используется нижний_регистр_с_подчёркиваниями
some_var = 5
some_var #=> 5
@@ -149,7 +161,7 @@ some_unknown_var # Выбрасывает ошибку именования
# Списки хранят последовательности
li = []
-# Можно сразу начать с заполненным списком
+# Можно сразу начать с заполненного списка
other_li = [4, 5, 6]
# Объекты добавляются в конец списка методом append
@@ -170,7 +182,7 @@ li[-1] #=> 3
# Попытка выйти за границы массива приведёт к ошибке индекса
li[4] # Выдаёт IndexError
-# Можно обращаться к диапазону, используя "кусочный синтаксис" (slice syntax)
+# Можно обращаться к диапазону, используя так называемые срезы
# (Для тех, кто любит математику, это называется замкнуто-открытый интервал).
li[1:3] #=> [2, 4]
# Опускаем начало
@@ -181,13 +193,14 @@ li[:3] #=> [1, 2, 4]
li[::2] # =>[1, 4]
# Переворачиваем список
li[::-1] # => [3, 4, 2, 1]
-# Используйте сочетания всего вышеназванного для выделения более сложных кусков
+# Используйте сочетания всего вышеназванного для выделения более сложных срезов
# li[начало:конец:шаг]
# Удаляем произвольные элементы из списка оператором del
del li[2] # [1, 2, 3]
-# Вы можете складывать списки
+# Вы можете складывать, или, как ещё говорят, конкатенировать списки
+# Обратите внимание: значения li и other_li при этом не изменились.
li + other_li #=> [1, 2, 3, 4, 5, 6] — Замечание: li и other_li не изменяются
# Объединять списки можно методом extend
@@ -224,10 +237,11 @@ empty_dict = {}
# Вот так описывается предзаполненный словарь
filled_dict = {"one": 1, "two": 2, "three": 3}
-# Значения ищутся по ключу с помощью оператора []
+# Значения извлекаются так же, как из списка, с той лишь разницей,
+# что индекс — у словарей он называется ключом — не обязан быть числом
filled_dict["one"] #=> 1
-# Все значения в виде списка получаются с помощью метода keys().
+# Все ключи в виде списка получаются с помощью метода keys().
# Его вызов нужно обернуть в list(), так как обратно мы получаем
# итерируемый объект, о которых поговорим позднее.
list(filled_dict.keys()) # => ["three", "two", "one"]
@@ -247,7 +261,7 @@ list(filled_dict.values()) # => [3, 2, 1]
# Попытка получить значение по несуществующему ключу выбросит ошибку ключа
filled_dict["four"] # KeyError
-# Чтобы избежать этого, используйте метод get
+# Чтобы избежать этого, используйте метод get()
filled_dict.get("one") #=> 1
filled_dict.get("four") #=> None
# Метод get также принимает аргумент по умолчанию, значение которого будет
@@ -259,6 +273,10 @@ filled_dict.get("four", 4) #=> 4
filled_dict.setdefault("five", 5) #filled_dict["five"] возвращает 5
filled_dict.setdefault("five", 6) #filled_dict["five"] по-прежнему возвращает 5
+# Добавление элементов в словарь
+filled_dict.update({"four":4}) #=> {"one": 1, "two": 2, "three": 3, "four": 4}
+#filled_dict["four"] = 4 # Другой способ добавления элементов
+
# Удаляйте ключи из словаря с помощью оператора del
del filled_dict["one"] # Удаляет ключ «one» из словаря
@@ -345,7 +363,7 @@ try:
# Чтобы выбросить ошибку, используется raise
raise IndexError("Это ошибка индекса")
except IndexError as e:
- # pass это просто отсутствие оператора. Обычно здесь происходит
+ # pass — это просто отсутствие оператора. Обычно здесь происходит
# восстановление после ошибки.
pass
except (TypeError, NameError):
@@ -393,7 +411,7 @@ list(filled_dict.keys()) #=> Возвращает ["one", "two", "three"]
# Используйте def для создания новых функций
def add(x, y):
print("x равен %s, а y равен %s" % (x, y))
- return x + y # Возвращайте результат выражением return
+ return x + y # Возвращайте результат с помощью ключевого слова return
# Вызов функции с аргументами
add(5, 6) #=> выводит «x равен 5, а y равен 6» и возвращает 11
@@ -401,14 +419,14 @@ add(5, 6) #=> выводит «x равен 5, а y равен 6» и возвр
# Другой способ вызова функции — вызов с именованными аргументами
add(y=6, x=5) # Именованные аргументы можно указывать в любом порядке.
-# Вы можете определить функцию, принимающую изменяемое число аргументов
+# Вы можете определить функцию, принимающую переменное число аргументов
def varargs(*args):
return args
varargs(1, 2, 3) #=> (1,2,3)
-# А также можете определить функцию, принимающую изменяемое число
+# А также можете определить функцию, принимающую переменное число
# именованных аргументов
def keyword_args(**kwargs):
return kwargs
@@ -427,7 +445,7 @@ all_the_args(1, 2, a=3, b=4) выводит:
"""
# Вызывая функции, можете сделать наоборот!
-# Используйте символ * для передачи кортежей и ** для передачи словарей
+# Используйте символ * для распаковки кортежей и ** для распаковки словарей
args = (1, 2, 3, 4)
kwargs = {"a": 3, "b": 4}
all_the_args(*args) # эквивалентно foo(1, 2, 3, 4)
@@ -451,7 +469,7 @@ def setGlobalX(num):
setX(43)
setGlobalX(6)
-# В Python функции — «объекты первого класса». Это означает, что их можно использовать наравне с любыми другими значениями
+# В Python функции — «объекты первого класса»
def create_adder(x):
def adder(y):
return x + y
diff --git a/ru-ru/swift-ru.html.markdown b/ru-ru/swift-ru.html.markdown
new file mode 100644
index 00000000..77987bb3
--- /dev/null
+++ b/ru-ru/swift-ru.html.markdown
@@ -0,0 +1,589 @@
+---
+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"]
+lang: ru-ru
+---
+
+Swift - это язык программирования, созданный компанией Apple, для приложений
+под iOS и OS X. Разработанный, чтобы сосуществовать с Objective-C и
+быть более устойчивым к ошибочному коду, Swift был представлен в 2014 году на
+конференции разработчиков Apple, WWDC. Приложения на Swift собираются
+с помощью LLVM-компилятора, включенного в Xcode 6+.
+
+Официальная книга по [языку программирования Swift](https://itunes.apple.com/us/book/swift-programming-language/id881256329) от Apple доступна в iBooks.
+
+Смотрите еще [начальное руководство](https://developer.apple.com/library/prerelease/ios/referencelibrary/GettingStarted/RoadMapiOS/index.html) Apple, которое содержит полное учебное пособие по Swift.
+
+```swift
+// импорт модуля
+import UIKit
+
+//
+// MARK: Основы
+//
+
+// Xcode поддерживает маркеры, чтобы давать примечания своему коду
+// и вносить их в список обозревателя (Jump Bar)
+// MARK: Метка раздела
+// TODO: Сделайте что-нибудь вскоре
+// FIXME: Исправьте этот код
+
+println("Привет, мир")
+
+// переменные (var), значение которых можно изменить после инициализации
+// константы (let), значение которых нельзя изменить после инициализации
+
+var myVariable = 42
+let øπΩ = "значение" // именование переменной символами unicode
+let π = 3.1415926
+let convenience = "Ключевое слово" // контекстное имя переменной
+let weak = "Ключевое слово"; let override = "еще ключевое слово" // операторы
+ // могут быть отделены точкой с запятой
+let `class` = "Ключевое слово" // обратные апострофы позволяют использовать
+ // ключевые слова в именовании переменных
+let explicitDouble: Double = 70
+let intValue = 0007 // 7
+let largeIntValue = 77_000 // 77000
+let label = "некоторый текст " + String(myVariable) // Приведение типа
+let piText = "Pi = \(π), Pi 2 = \(π * 2)" // Вставка переменных в строку
+
+// Сборка особых значений
+// используя ключ -D сборки конфигурации
+#if false
+ println("Не печатается")
+ let buildValue = 3
+#else
+ let buildValue = 7
+#endif
+println("Значение сборки: \(buildValue)") // Значение сборки: 7
+
+/*
+ Опционалы - это особенность языка Swift, которая допускает вам сохранять
+ `некоторое` или `никакое` значения.
+
+ Язык Swift требует, чтобы каждое свойство имело значение, поэтому даже nil
+ должен быть явно сохранен как опциональное значение.
+
+ Optional<T> является перечислением.
+*/
+var someOptionalString: String? = "опционал" // Может быть nil
+// как и выше, только ? - это постфиксный оператор (синтаксический сахар)
+var someOptionalString2: Optional<String> = "опционал"
+
+if someOptionalString != nil {
+ // я не nil
+ if someOptionalString!.hasPrefix("opt") {
+ println("содержит префикс")
+ }
+
+ let empty = someOptionalString?.isEmpty
+}
+someOptionalString = nil
+
+// неявная развертка опциональной переменной
+var unwrappedString: String! = "Ожидаемое значение."
+// как и выше, только ! - постфиксный оператор (с еще одним синтаксическим сахаром)
+var unwrappedString2: ImplicitlyUnwrappedOptional<String> = "Ожидаемое значение."
+
+if let someOptionalStringConstant = someOptionalString {
+ // имеется некоторое значение, не nil
+ if !someOptionalStringConstant.hasPrefix("ok") {
+ // нет такого префикса
+ }
+}
+
+// Swift поддерживает сохранение значения любого типа
+// AnyObject == id
+// В отличие от `id` в Objective-C, AnyObject работает с любым значением (Class,
+// Int, struct и т.д.)
+var anyObjectVar: AnyObject = 7
+anyObjectVar = "Изменять значение на строку не является хорошей практикой, но возможно."
+
+/*
+ Комментируйте здесь
+
+ /*
+ Вложенные комментарии тоже поддерживаются
+ */
+*/
+
+//
+// MARK: Коллекции
+//
+
+/*
+ Массив (Array) и словарь (Dictionary) являются структурами (struct). Так
+ `let` и `var` также означают, что они изменяются (var) или не изменяются (let)
+ при объявлении переменных этих типов.
+*/
+
+// Массив
+var shoppingList = ["сом", "вода", "лимоны"]
+shoppingList[1] = "бутылка воды"
+let emptyArray = [String]() // let == неизменный
+let emptyArray2 = Array<String>() // как и выше
+var emptyMutableArray = [String]() // var == изменяемый
+
+
+// Словарь
+var occupations = [
+ "Malcolm": "Капитан",
+ "kaylee": "Техник"
+]
+occupations["Jayne"] = "Связи с общественностью"
+let emptyDictionary = [String: Float]() // let == неизменный
+let emptyDictionary2 = Dictionary<String, Float>() // как и выше
+var emptyMutableDictionary = [String: Float]() // var == изменяемый
+
+
+//
+// MARK: Поток управления
+//
+
+// цикл for для массива
+let myArray = [1, 1, 2, 3, 5]
+for value in myArray {
+ if value == 1 {
+ println("Один!")
+ } else {
+ println("Не один!")
+ }
+}
+
+// цикл for для словаря
+var dict = ["один": 1, "два": 2]
+for (key, value) in dict {
+ println("\(key): \(value)")
+}
+
+// цикл for для диапазона чисел
+for i in -1...shoppingList.count {
+ println(i)
+}
+shoppingList[1...2] = ["бифштекс", "орехи пекан"]
+// используйте ..< для исключения последнего числа
+
+// цикл while
+var i = 1
+while i < 1000 {
+ i *= 2
+}
+
+// цикл do-while
+do {
+ println("привет")
+} while 1 == 2
+
+// Переключатель
+// Очень мощный оператор, представляйте себе операторы `if` с синтаксическим
+// сахаром
+// Они поддерживают строки, объекты и примитивы (Int, Double, etc)
+let vegetable = "красный перец"
+switch vegetable {
+case "сельдерей":
+ let vegetableComment = "Добавьте немного изюма, имитируя муравьев на бревнышке."
+case "огурец", "кресс-салат":
+ let vegetableComment = "Было бы неплохо сделать бутерброд с чаем."
+case let localScopeValue where localScopeValue.hasSuffix("перец"):
+ let vegetableComment = "Это острый \(localScopeValue)?"
+default: // обязательный (чтобы предусмотреть все возможные вхождения)
+ let vegetableComment = "В супе все овощи вкусные."
+}
+
+
+//
+// MARK: Функции
+//
+
+// Функции являются типом первого класса, т.е. они могут быть вложены в функциях
+// и могут передаваться между собой
+
+// Функция с документированным заголовком Swift (формат reStructedText)
+
+/**
+ Операция приветствия
+
+ - Маркер в документировании
+ - Еще один маркер в документации
+
+ :param: name - это имя
+ :param: day - это день
+ :returns: Строка, содержащая значения name и day.
+*/
+func greet(name: String, day: String) -> String {
+ return "Привет \(name), сегодня \(day)."
+}
+greet("Боб", "вторник")
+
+// как и выше, кроме обращения параметров функции
+func greet2(#requiredName: String, externalParamName localParamName: String) -> String {
+ return "Привет \(requiredName), сегодня \(localParamName)"
+}
+greet2(requiredName:"Иван", externalParamName: "воскресенье")
+
+// Функция, которая возвращает множество элементов в кортеже
+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("Цена газа: \(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
+}
+var increment = makeIncrementer()
+increment(7)
+
+// передача по ссылке
+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` отделяет заголовок замыкания от тела замыкания
+numbers.map({
+ (number: Int) -> Int in
+ let result = 3 * number
+ return result
+})
+
+// Когда тип известен, как и выше, мы можем сделать так
+numbers = numbers.map({ number in 3 * number })
+// Или даже так
+//numbers = numbers.map({ $0 * 3 })
+
+print(numbers) // [3, 6, 18]
+
+// Хвостовое замыкание
+numbers = sorted(numbers) { $0 > $1 }
+
+print(numbers) // [18, 6, 3]
+
+// Суперсокращение, поскольку оператор < выполняет логический вывод типов
+
+numbers = sorted(numbers, < )
+
+print(numbers) // [3, 6, 18]
+
+//
+// MARK: Структуры
+//
+
+// Структуры и классы имеют очень похожие характеристики
+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: Классы
+//
+
+// Классы, структуры и их члены имеют трехуровневый контроль доступа
+// Уровни: internal (по умолчанию), public, private
+
+public class Shape {
+ public func getArea() -> Int {
+ return 0;
+ }
+}
+
+// Все методы и свойства класса являются открытыми (public).
+// Если вам необходимо содержать только данные
+// в структурированном объекте, вы должны использовать `struct`
+
+internal class Rect: Shape {
+ var sideLength: Int = 1
+
+ // Пользовательский сеттер и геттер
+ private var perimeter: Int {
+ get {
+ return 4 * sideLength
+ }
+ set {
+ // `newValue` - неявная переменная, доступная в сеттере
+ sideLength = newValue / 4
+ }
+ }
+
+ // Ленивая загрузка свойства
+ // свойство subShape остается равным nil (неинициализированным),
+ // пока не вызовется геттер
+ lazy var subShape = Rect(sideLength: 4)
+
+ // Если вам не нужны пользовательские геттеры и сеттеры,
+ // но все же хотите запустить код перед и после вызовов геттера или сеттера
+ // свойств, вы можете использовать `willSet` и `didSet`
+ var identifier: String = "defaultID" {
+ // аргумент у `willSet` будет именем переменной для нового значения
+ willSet(someIdentifier) {
+ print(someIdentifier)
+ }
+ }
+
+ init(sideLength: Int) {
+ self.sideLength = sideLength
+ // последним всегда вызывается super.init, когда init с параметрами
+ super.init()
+ }
+
+ func shrink() {
+ if sideLength > 0 {
+ --sideLength
+ }
+ }
+
+ override func getArea() -> Int {
+ return sideLength * sideLength
+ }
+}
+
+// Простой класс `Square` наследует `Rect`
+class Square: Rect {
+ convenience init() {
+ self.init(sideLength: 5)
+ }
+}
+
+var mySquare = Square()
+print(mySquare.getArea()) // 25
+mySquare.shrink()
+print(mySquare.sideLength) // 4
+
+// преобразование объектов
+let aShape = mySquare as Shape
+
+// сравнение экземпляров, в отличие от ==, которая проверяет эквивалентность
+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: Перечисления
+//
+
+// Перечисления могут быть определенного или своего типа.
+// Они могут содержать методы подобно классам.
+
+enum Suit {
+ 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 = "Иоанн"
+ case Luke = "Лука"
+}
+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: Протоколы
+//
+
+// `protocol` может потребовать, чтобы у соответствующих типов
+// были определенные свойства экземпляра, методы экземпляра, тип методов,
+// операторы и индексы.
+
+protocol ShapeGenerator {
+ var enabled: Bool { get set }
+ func buildShape() -> Shape
+}
+
+// Протоколы, объявленные с @objc, допускают необязательные функции,
+// которые позволяют вам проверять на соответствие
+@objc protocol TransformShape {
+ optional func reshaped()
+ optional func canReshape() -> Bool
+}
+
+class MyShape: Rect {
+ var delegate: TransformShape?
+
+ func grow() {
+ sideLength += 2
+ // Размещайте знак вопроса перед опционным свойством, методом
+ // или индексом, чтобы не учитывать nil-значение и возвратить nil
+ // вместо выбрасывания ошибки выполнения (т.н. "опционная цепочка")
+ if let allow = self.delegate?.canReshape?() {
+ // проверка делегата на выполнение метода
+ self.delegate?.reshaped?()
+ }
+ }
+}
+
+
+//
+// MARK: Прочее
+//
+
+// `extension`s: Добавляет расширенный функционал к существующему типу
+
+// Класс Square теперь "соответствует" протоколу `Printable`
+extension Square: Printable {
+ var description: String {
+ return "Площадь: \(self.getArea()) - ID: \(self.identifier)"
+ }
+}
+
+println("Объект Square: \(mySquare)")
+
+// Вы также можете расширить встроенные типы
+extension Int {
+ var customProperty: String {
+ return "Это \(self)"
+ }
+
+ func multiplyBy(num: Int) -> Int {
+ return num * self
+ }
+}
+
+println(7.customProperty) // "Это 7"
+println(14.multiplyBy(3)) // 42
+
+// Обобщения: Подобно языкам Java и C#. Используйте ключевое слово `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
+
+// Используя пользовательский оператор !!!, изменится длина стороны
+// путем увеличения размера в 3 раза
+!!!mySquare
+println(mySquare.sideLength) // 12
+```
diff --git a/ru-ru/xml-ru.html.markdown b/ru-ru/xml-ru.html.markdown
new file mode 100644
index 00000000..b0096b75
--- /dev/null
+++ b/ru-ru/xml-ru.html.markdown
@@ -0,0 +1,130 @@
+---
+language: xml
+filename: learnxml-ru.xml
+contributors:
+ - ["João Farias", "https://github.com/JoaoGFarias"]
+translators:
+ - ["Dmitry Bessonov", "https://github.com/TheDmitry"]
+lang: ru-ru
+---
+
+XML - это язык разметки, предназначенный для хранения и передачи данных.
+
+В отличие от HTML, XML не определяет, как отображать или форматировать данные, он только содержит их.
+
+* XML-Синтаксис
+
+```xml
+<!-- Комментарии в XML выглядят вот так -->
+
+<?xml version="1.0" encoding="UTF-8"?>
+<bookstore>
+ <book category="КУЛИНАРИЯ">
+ <title lang="ru">Итальянская кухня каждый день</title>
+ <author>Giada De Laurentiis</author>
+ <year>2005</year>
+ <price>30.00</price>
+ </book>
+ <book category="ДЕТИ">
+ <title lang="ru">Гарри Поттер</title>
+ <author>Дж. К. Роулинг</author>
+ <year>2005</year>
+ <price>29.99</price>
+ </book>
+ <book category="ВСЕМИРНАЯ ПАУТИНА">
+ <title lang="ru">Изучаем XML</title>
+ <author>Эрик Рэй</author>
+ <year>2003</year>
+ <price>39.95</price>
+ </book>
+</bookstore>
+
+<!-- Вышеописанный документ - типичный XML-файл.
+ Он начинается с определения, объявляющего о некоторых метаданных (необязательно).
+
+ XML использует древовидную структуру. У вышеописанного документа
+ корневой узел - 'bookstore', который содержит три дочерних узла - все 'book'-узлы.
+ Такие узлы содержат еще дочерние узлы и т.д.
+
+ Узлы создаются с помощью открывающих/закрывающих тегов,
+ а дочерние узлы - это узлы между открывающимися и закрывающимися тегами.-->
+
+
+<!-- XML содержит в себе два типа данных:
+ 1 - Атрибуты -> Это метаданные узлов.
+ Обычно XML-парсер использует эту информацию, чтобы хранить свойства данных.
+ Атрибут изображается путем вписывания его в скобки в пределах открытого тега
+ 2 - Элементы -> Это чистые данные.
+ Это то, что парсер извлечет из XML-файла.
+ Элементы идут между открытыми и закрытыми тегами без скобок. -->
+
+
+<!-- Ниже элемент с двумя атрибутами -->
+<file type="gif" id="4293">компьютер.gif</file>
+
+
+```
+
+* Хорошо отформатированный документ x Проверка достоверности
+
+XML-документ хорошо отформатирован, если он синтаксически верный.
+Впрочем, в документ возможно ввести больше ограничений,
+используя определения документа, вроде DTD и XML-схемы.
+
+XML-документ, который следует описанию документа, называется корректным,
+относительно этого документа.
+
+С таким инструментом вы можете проверить XML-данные вне логики приложения.
+
+```xml
+
+<!-- Ниже вы можете увидеть упрощенную версию документа книжного магазина,
+ с дополнением DTD-определения.-->
+
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE note SYSTEM "Bookstore.dtd">
+<bookstore>
+ <book category="КУЛИНАРИЯ">
+ <title >Итальянская кухня каждый день</title>
+ <price>30.00</price>
+ </book>
+</bookstore>
+
+<!-- Этот DTD может быть чем-то вроде:-->
+
+<!DOCTYPE note
+[
+<!ELEMENT bookstore (book+)>
+<!ELEMENT book (title,price)>
+<!ATTLIST book category CDATA "Литература">
+<!ELEMENT title (#PCDATA)>
+<!ELEMENT price (#PCDATA)>
+]>
+
+
+<!-- DTD начинается с объявления.
+ Затем объявляется корневой узел, требующий 1 или более дочерних узлов 'book'.
+ Каждый 'book' должен содержать точно один 'title' и 'price', и атрибут,
+ называемый 'category', со значением "Литература" по умолчанию.
+ Узлы 'title' и 'price' содержат анализируемые символьные данные.-->
+
+<!-- DTD может быть объявлен в самом XML-файле.-->
+
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE note
+[
+<!ELEMENT bookstore (book+)>
+<!ELEMENT book (title,price)>
+<!ATTLIST book category CDATA "Литература">
+<!ELEMENT title (#PCDATA)>
+<!ELEMENT price (#PCDATA)>
+]>
+
+<bookstore>
+ <book category="КУЛИНАРИЯ">
+ <title >Итальянская кухня каждый день</title>
+ <price>30.00</price>
+ </book>
+</bookstore>
+```
diff --git a/ruby.html.markdown b/ruby.html.markdown
index 7cf5bdc7..1883d1ad 100644
--- a/ruby.html.markdown
+++ b/ruby.html.markdown
@@ -60,8 +60,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 +73,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
@@ -280,9 +289,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/scala.html.markdown b/scala.html.markdown
index 61c735e3..ed1ddabb 100644
--- a/scala.html.markdown
+++ b/scala.html.markdown
@@ -453,7 +453,7 @@ def matchEverything(obj: Any): String = obj match {
// feature is so powerful that Scala lets you define whole functions as
// patterns:
val patternFunc: Person => String = {
- case Person("George", number") => s"George's number: $number"
+ case Person("George", number) => s"George's number: $number"
case Person(name, number) => s"Random person's number: $number"
}
diff --git a/swift.html.markdown b/swift.html.markdown
index 0d1d2df4..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
---
@@ -10,7 +11,7 @@ Swift is a programming language for iOS and OS X development created by Apple. D
The official [Swift Programming Language](https://itunes.apple.com/us/book/swift-programming-language/id881256329) book from Apple is now available via iBooks.
-See also Apple's [getting started guide](https://developer.apple.com/library/prerelease/ios/referencelibrary/GettingStarted/LandingPage/index.html), which has a complete tutorial on Swift.
+See also Apple's [getting started guide](https://developer.apple.com/library/prerelease/ios/referencelibrary/GettingStarted/RoadMapiOS/index.html), which has a complete tutorial on Swift.
```swift
// import a module
@@ -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
@@ -445,7 +497,10 @@ class MyShape: Rect {
func grow() {
sideLength += 2
-
+
+ // Place a question mark after an optional property, method, or
+ // subscript to gracefully ignore a nil value and return nil
+ // instead of throwing a runtime error ("optional chaining").
if let allow = self.delegate?.canReshape?() {
// test for delegate then for method
self.delegate?.reshaped?()
@@ -481,7 +536,7 @@ extension Int {
}
println(7.customProperty) // "This is 7"
-println(14.multiplyBy(2)) // 42
+println(14.multiplyBy(3)) // 42
// Generics: Similar to Java and C#. Use the `where` keyword to specify the
// requirements of the generics.
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/tmux.html.markdown b/tmux.html.markdown
index 9eb96303..2ccb067a 100644
--- a/tmux.html.markdown
+++ b/tmux.html.markdown
@@ -2,7 +2,7 @@
category: tool
tool: tmux
contributors:
- - ["wzsk", "https://github.com/wzsk"]
+ - ["mdln", "https://github.com/mdln"]
filename: LearnTmux.txt
---
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/java-cn.html.markdown b/zh-cn/java-cn.html.markdown
index f7d319e6..f08d3507 100644
--- a/zh-cn/java-cn.html.markdown
+++ b/zh-cn/java-cn.html.markdown
@@ -124,7 +124,7 @@ public class LearnJava {
// HashMaps
///////////////////////////////////////
- // 操作符
+ // 操作符
///////////////////////////////////////
System.out.println("\n->Operators");
@@ -161,10 +161,13 @@ public class LearnJava {
// 自增
int i = 0;
System.out.println("\n->Inc/Dec-rementation");
- System.out.println(i++); //i = 1 后自增
- System.out.println(++i); //i = 2 前自增
- System.out.println(i--); //i = 1 后自减
- System.out.println(--i); //i = 0 前自减
+ // ++ 和 -- 操作符使变量加或减1。放在变量前面或者后面的区别是整个表达
+ // 式的返回值。操作符在前面时,先加减,后取值。操作符在后面时,先取值
+ // 后加减。
+ System.out.println(i++); // 后自增 i = 1, 输出0
+ System.out.println(++i); // 前自增 i = 2, 输出2
+ System.out.println(i--); // 后自减 i = 1, 输出2
+ System.out.println(--i); // 前自减 i = 0, 输出0
///////////////////////////////////////
// 控制结构
@@ -192,7 +195,7 @@ public class LearnJava {
}
System.out.println("fooWhile Value: " + fooWhile);
- // Do While循环
+ // Do While循环
int fooDoWhile = 0;
do
{
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 b9696c72..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/LandingPage/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
```
+