This commit is contained in:
Elena Bolshakova 2015-06-10 11:34:14 +03:00
commit 193f66553f
98 changed files with 16040 additions and 1934 deletions

View File

@ -22,6 +22,11 @@ Send a pull request or open an issue any time of day or night.
**(e.g. [python/en] for English Python).** This will help everyone pick out things they
care about.
We're happy for any contribution in any form, but if you're making more than one major change
(i.e. translations for two different languages) it would be super cool of you to make a
separate pull request for each one so that someone can review them more effectively and/or
individually.
### Style Guidelines
* **Keep lines under 80 chars**

View File

@ -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)

View File

@ -10,6 +10,7 @@ contributors:
- ["Anton Strömkvist", "http://lutic.org/"]
- ["Rahil Momin", "https://github.com/iamrahil"]
- ["Gregrory Kielian", "https://github.com/gskielian"]
- ["Etan Reisner", "https://github.com/deryni"]
filename: LearnBash.sh
---
@ -31,32 +32,41 @@ echo Hello world!
echo 'This is the first line'; echo 'This is the second line'
# Declaring a variable looks like this:
VARIABLE="Some string"
Variable="Some string"
# But not like this:
VARIABLE = "Some string"
# Bash will decide that VARIABLE is a command it must execute and give an error
# because it couldn't be found.
Variable = "Some string"
# Bash will decide that Variable is a command it must execute and give an error
# because it can't be found.
# Or like this:
Variable= 'Some string'
# Bash will decide that 'Some string' is a command it must execute and give an
# error because it can't be found. (In this case the 'Variable=' part is seen
# as a variable assignment valid only for the scope of the 'Some string'
# command.)
# Using the variable:
echo $VARIABLE
echo "$VARIABLE"
echo '$VARIABLE'
echo $Variable
echo "$Variable"
echo '$Variable'
# When you use the variable itself — assign it, export it, or else — you write
# its name without $. If you want to use variable's value, you should use $.
# Note that ' (single quote) won't expand the variables!
# String substitution in variables
echo ${VARIABLE/Some/A}
# This will substitute the first occurance of "Some" with "A"
echo ${Variable/Some/A}
# This will substitute the first occurrence of "Some" with "A"
# Substring from a variable
echo ${VARIABLE:0:7}
Length=7
echo ${Variable:0:Length}
# This will return only the first 7 characters of the value
# Default value for variable
echo ${FOO:-"DefaultValueIfFOOIsMissingOrEmpty"}
# This works for null (FOO=), empty string (FOO=""), zero (FOO=0) returns 0
echo ${Foo:-"DefaultValueIfFooIsMissingOrEmpty"}
# This works for null (Foo=) and empty string (Foo=""); zero (Foo=0) returns 0.
# Note that it only returns default value and doesn't change variable value.
# Builtin variables:
# There are some useful builtin variables, like
@ -64,16 +74,16 @@ echo "Last program return value: $?"
echo "Script's PID: $$"
echo "Number of arguments: $#"
echo "Scripts arguments: $@"
echo "Scripts arguments seperated in different variables: $1 $2..."
echo "Scripts arguments separated in different variables: $1 $2..."
# Reading a value from input:
echo "What's your name?"
read NAME # Note that we didn't need to declare a new variable
echo Hello, $NAME!
read Name # Note that we didn't need to declare a new variable
echo Hello, $Name!
# We have the usual if structure:
# use 'man test' for more info about conditionals
if [ $NAME -ne $USER ]
if [ $Name -ne $USER ]
then
echo "Your name isn't your username"
else
@ -85,14 +95,14 @@ echo "Always executed" || echo "Only executed if first command fails"
echo "Always executed" && echo "Only executed if first command does NOT fail"
# To use && and || with if statements, you need multiple pairs of square brackets:
if [ $NAME == "Steve" ] && [ $AGE -eq 15 ]
if [ $Name == "Steve" ] && [ $Age -eq 15 ]
then
echo "This will run if $NAME is Steve AND $AGE is 15."
echo "This will run if $Name is Steve AND $Age is 15."
fi
if [ $NAME == "Daniya" ] || [ $NAME == "Zach" ]
if [ $Name == "Daniya" ] || [ $Name == "Zach" ]
then
echo "This will run if $NAME is Daniya OR Zach."
echo "This will run if $Name is Daniya OR Zach."
fi
# Expressions are denoted with the following format:
@ -134,7 +144,7 @@ python hello.py > /dev/null 2>&1
# if you want to append instead, use ">>":
python hello.py >> "output.out" 2>> "error.err"
# Overwrite output.txt, append to error.err, and count lines:
# Overwrite output.out, append to error.err, and count lines:
info bash 'Basic Shell Features' 'Redirections' > output.out 2>> error.err
wc -l output.out error.err
@ -142,7 +152,7 @@ wc -l output.out error.err
# see: man fd
echo <(echo "#helloworld")
# Overwrite output.txt with "#helloworld":
# Overwrite output.out with "#helloworld":
cat > output.out <(echo "#helloworld")
echo "#helloworld" > output.out
echo "#helloworld" | cat > output.out
@ -161,7 +171,7 @@ echo "There are $(ls | wc -l) items here."
echo "There are `ls | wc -l` items here."
# Bash uses a case statement that works similarly to switch in Java and C++:
case "$VARIABLE" in
case "$Variable" in
#List patterns for the conditions you want to meet
0) echo "There is a zero.";;
1) echo "There is a one.";;
@ -169,10 +179,10 @@ case "$VARIABLE" in
esac
# for loops iterate for as many arguments given:
# The contents of $VARIABLE is printed three times.
for VARIABLE in {1..3}
# The contents of $Variable is printed three times.
for Variable in {1..3}
do
echo "$VARIABLE"
echo "$Variable"
done
# Or write it the "traditional for loop" way:
@ -183,16 +193,16 @@ done
# They can also be used to act on files..
# This will run the command 'cat' on file1 and file2
for VARIABLE in file1 file2
for Variable in file1 file2
do
cat "$VARIABLE"
cat "$Variable"
done
# ..or the output from a command
# This will cat the output from ls.
for OUTPUT in $(ls)
for Output in $(ls)
do
cat "$OUTPUT"
cat "$Output"
done
# while loop:
@ -220,7 +230,7 @@ bar ()
}
# Calling your function
foo "My name is" $NAME
foo "My name is" $Name
# There are a lot of useful commands you should learn:
# prints last 10 lines of file.txt
@ -235,11 +245,13 @@ uniq -d file.txt
cut -d ',' -f 1 file.txt
# replaces every occurrence of 'okay' with 'great' in file.txt, (regex compatible)
sed -i 's/okay/great/g' file.txt
# print to stdout all lines of file.txt which match some regex, the example prints lines which begin with "foo" and end in "bar"
# print to stdout all lines of file.txt which match some regex
# The example prints lines which begin with "foo" and end in "bar"
grep "^foo.*bar$" file.txt
# pass the option "-c" to instead print the number of lines matching the regex
grep -c "^foo.*bar$" file.txt
# if you literally want to search for the string, and not the regex, use fgrep (or grep -F)
# if you literally want to search for the string,
# and not the regex, use fgrep (or grep -F)
fgrep "^foo.*bar$" file.txt

View File

@ -8,6 +8,8 @@ contributors:
Brainfuck (not capitalized except at the start of a sentence) is an extremely
minimal Turing-complete programming language with just 8 commands.
You can try brainfuck on your browser with [brainfuck-visualizer](http://fatiherikli.github.io/brainfuck-visualizer/).
```
Any character not "><+-.,[]" (excluding quotation marks) is ignored.

View File

@ -30,10 +30,9 @@ 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.
// 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 +50,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
@ -238,7 +239,10 @@ string& fooRef = foo; // This creates a reference to foo.
fooRef += ". Hi!"; // Modifies foo through the reference
cout << fooRef; // Prints "I am foo. Hi!"
fooRef = bar; // Error: references cannot be reassigned.
// Doesn't reassign "fooRef". This is the same as "foo = bar", and
// foo == "I am bar"
// after this line.
fooRef = bar;
const string& barRef = bar; // Create a const reference to bar.
// Like C, const values (and pointers and references) cannot be modified.
@ -284,7 +288,7 @@ public:
// Functions can also be defined inside the class body.
// Functions defined as such are automatically inlined.
void bark() const { std::cout << name << " barks!\n" }
void bark() const { std::cout << name << " barks!\n"; }
// Along with constructors, C++ provides destructors.
// These are called when an object is deleted or falls out of scope.
@ -296,7 +300,7 @@ public:
}; // A semicolon must follow the class definition.
// Class member functions are usually implemented in .cpp files.
void Dog::Dog()
Dog::Dog()
{
std::cout << "A dog has been constructed\n";
}
@ -319,7 +323,7 @@ void Dog::print() const
std::cout << "Dog is " << name << " and weighs " << weight << "kg\n";
}
void Dog::~Dog()
Dog::~Dog()
{
cout << "Goodbye " << name << "\n";
}
@ -328,7 +332,7 @@ int main() {
Dog myDog; // prints "A dog has been constructed"
myDog.setName("Barkley");
myDog.setWeight(10);
myDog.printDog(); // prints "Dog is Barkley and weighs 10 kg"
myDog.print(); // prints "Dog is Barkley and weighs 10 kg"
return 0;
} // prints "Goodbye Barkley"
@ -337,7 +341,7 @@ int main() {
// This class inherits everything public and protected from the Dog class
class OwnedDog : public Dog {
void setOwner(const std::string& dogsOwner)
void setOwner(const std::string& dogsOwner);
// Override the behavior of the print function for all OwnedDogs. See
// http://en.wikipedia.org/wiki/Polymorphism_(computer_science)#Subtyping
@ -421,13 +425,92 @@ int main () {
Point up (0,1);
Point right (1,0);
// This calls the Point + operator
// Point up calls the + (function) with right as its paramater
// Point up calls the + (function) with right as its parameter
Point result = up + right;
// Prints "Result is upright (1,1)"
cout << "Result is upright (" << result.x << ',' << result.y << ")\n";
return 0;
}
/////////////////////
// Templates
/////////////////////
// Templates in C++ are mostly used for generic programming, though they are
// much more powerful than generics constructs in other languages. It also
// supports explicit and partial specialization, functional-style type classes,
// and also it's Turing-complete.
// We start with the kind of generic programming you might be familiar with. To
// define a class or function that takes a type parameter:
template<class T>
class Box {
public:
// In this class, T can be used as any other type.
void insert(const T&) { ... }
};
// During compilation, the compiler actually generates copies of each template
// with parameters substituted, and so the full definition of the class must be
// present at each invocation. This is why you will see template classes defined
// entirely in header files.
// To instantiate a template class on the stack:
Box<int> intBox;
// and you can use it as you would expect:
intBox.insert(123);
// You can, of course, nest templates:
Box<Box<int> > boxOfBox;
boxOfBox.insert(intBox);
// Up until C++11, you must place a space between the two '>'s, otherwise '>>'
// will be parsed as the right shift operator.
// You will sometimes see
// template<typename T>
// instead. The 'class' keyword and 'typename' keyword are _mostly_
// interchangeable in this case. For full explanation, see
// http://en.wikipedia.org/wiki/Typename
// (yes, that keyword has its own Wikipedia page).
// Similarly, a template function:
template<class T>
void barkThreeTimes(const T& input)
{
input.bark();
input.bark();
input.bark();
}
// Notice that nothing is specified about the type parameters here. The compiler
// will generate and then type-check every invocation of the template, so the
// above function works with any type 'T' that has a const 'bark' method!
Dog fluffy;
fluffy.setName("Fluffy")
barkThreeTimes(fluffy); // Prints "Fluffy barks" three times.
// Template parameters don't have to be classes:
template<int Y>
void printMessage() {
cout << "Learn C++ in " << Y << " minutes!" << endl;
}
// And you can explicitly specialize templates for more efficient code. Of
// course, most real-world uses of specialization are not as trivial as this.
// Note that you still need to declare the function (or class) as a template
// even if you explicitly specified all parameters.
template<>
void printMessage<10>() {
cout << "Learn C++ faster in only 10 minutes!" << endl;
}
printMessage<20>(); // Prints "Learn C++ in 20 minutes!"
printMessage<10>(); // Prints "Learn C++ faster in only 10 minutes!"
/////////////////////
// Exception Handling
/////////////////////
@ -436,12 +519,13 @@ int main () {
// (see http://en.cppreference.com/w/cpp/error/exception)
// but any type can be thrown an as exception
#include <exception>
#include <stdexcept>
// All exceptions thrown inside the _try_ block can be caught by subsequent
// _catch_ handlers.
try {
// Do not allocate exceptions on the heap using _new_.
throw std::exception("A problem occurred");
throw std::runtime_error("A problem occurred");
}
// Catch exceptions by const reference if they are objects
catch (const std::exception& ex)
@ -489,7 +573,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)) {
@ -510,7 +594,7 @@ bool doSomethingWithAFile(const char* filename)
{
FILE* fh = fopen(filename, "r");
if (fh == nullptr)
reuturn false;
return false;
if (!doSomethingWithTheFile(fh))
goto failure;
@ -532,7 +616,7 @@ void doSomethingWithAFile(const char* filename)
{
FILE* fh = fopen(filename, "r"); // Open the file in read mode
if (fh == nullptr)
throw std::exception("Could not open the file.");
throw std::runtime_error("Could not open the file.");
try {
doSomethingWithTheFile(fh);
@ -550,7 +634,7 @@ void doSomethingWithAFile(const char* filename)
// Compare this to the use of C++'s file stream class (fstream)
// fstream uses its destructor to close the file.
// Recall from above that destructors are automatically called
// whenver an object falls out of scope.
// whenever an object falls out of scope.
void doSomethingWithAFile(const std::string& filename)
{
// ifstream is short for input file stream
@ -581,8 +665,56 @@ void doSomethingWithAFile(const std::string& filename)
// vector (i.e. self-resizing array), hash maps, and so on
// all automatically destroy their contents when they fall out of scope.
// - Mutexes using lock_guard and unique_lock
/////////////////////
// Fun stuff
/////////////////////
// Aspects of C++ that may be surprising to newcomers (and even some veterans).
// This section is, unfortunately, wildly incomplete; C++ is one of the easiest
// languages with which to shoot yourself in the foot.
// You can override private methods!
class Foo {
virtual void bar();
};
class FooSub : public Foo {
virtual void bar(); // overrides Foo::bar!
};
// 0 == false == NULL (most of the time)!
bool* pt = new bool;
*pt = 0; // Sets the value points by 'pt' to false.
pt = 0; // Sets 'pt' to the null pointer. Both lines compile without warnings.
// nullptr is supposed to fix some of that issue:
int* pt2 = new int;
*pt2 = nullptr; // Doesn't compile
pt2 = nullptr; // Sets pt2 to null.
// But somehow 'bool' type is an exception (this is to make `if (ptr)` compile).
*pt = nullptr; // This still compiles, even though '*pt' is a bool!
// '=' != '=' != '='!
// Calls Foo::Foo(const Foo&) or some variant copy constructor.
Foo f2;
Foo f1 = f2;
// Calls Foo::Foo(const Foo&) or variant, but only copies the 'Foo' part of
// 'fooSub'. Any extra members of 'fooSub' are discarded. This sometimes
// horrifying behavior is called "object slicing."
FooSub fooSub;
Foo f1 = fooSub;
// Calls Foo::operator=(Foo&) or variant.
Foo f1;
f1 = f2;
```
Futher Reading:
Further Reading:
An up-to-date language reference can be found at
<http://cppreference.com/w/cpp>

View File

@ -26,13 +26,15 @@ Multi-line comments look like this. They work in C89 as well.
Multi-line comments don't nest /* Be careful */ // comment ends on this line...
*/ // ...not this one!
// Constants: #define <keyword>
// Constants: #define <keyword>
#define DAYS_IN_YEAR 365
// Enumeration constants are also ways to declare constants.
enum days {SUN = 1, MON, TUE, WED, THU, FRI, SAT};
// Enumeration constants are also ways to declare constants.
// All statements must end with a semicolon
enum days {SUN = 1, MON, TUE, WED, THU, FRI, SAT};
// MON gets 2 automatically, TUE gets 3, etc.
// Import headers with #include
#include <stdlib.h>
#include <stdio.h>
@ -57,7 +59,6 @@ int main() {
// print output using printf, for "print formatted"
// %d is an integer, \n is a newline
printf("%d\n", 0); // => Prints 0
// All statements must end with a semicolon
///////////////////////////////////////
// Types
@ -84,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;
@ -233,7 +234,7 @@ int main() {
// same with j-- and --j
// Bitwise operators!
~0x0F; // => 0xF0 (bitwise negation, "1's complement")
~0x0F; // => 0xFFFFFFF0 (bitwise negation, "1's complement", example result for 32-bit int)
0x0F & 0xF0; // => 0x00 (bitwise AND)
0x0F | 0xF0; // => 0xFF (bitwise OR)
0x04 ^ 0x0F; // => 0x0B (bitwise XOR)
@ -241,7 +242,7 @@ int main() {
0x02 >> 1; // => 0x01 (bitwise right shift (by 1))
// Be careful when shifting signed integers - the following are undefined:
// - shifting into the sign bit of a signed integer (int a = 1 << 32)
// - shifting into the sign bit of a signed integer (int a = 1 << 31)
// - left-shifting a negative number (int a = -1 << 2)
// - shifting by an offset which is >= the width of the type of the LHS:
// int a = 1 << 32; // UB if int is 32 bits wide
@ -385,7 +386,8 @@ int main() {
// or when it's the argument of the `sizeof` or `alignof` operator:
int arraythethird[10];
int *ptr = arraythethird; // equivalent with int *ptr = &arr[0];
printf("%zu, %zu\n", sizeof arraythethird, sizeof ptr); // probably prints "40, 4" or "40, 8"
printf("%zu, %zu\n", sizeof arraythethird, sizeof ptr);
// probably prints "40, 4" or "40, 8"
// Pointers are incremented and decremented based on their type
@ -476,7 +478,7 @@ void testFunc() {
}
//make external variables private to source file with static:
static int j = 0; //other files using testFunc() cannot access variable i
static int j = 0; //other files using testFunc2() cannot access variable j
void testFunc2() {
extern int j;
}

View File

@ -109,7 +109,7 @@ You'll want to be familiar with Clojure. Make sure you understand everything in
(list x) ; -> (4)
;; It's typical to use helper functions with macros. Let's create a few to
;; help us support a (dumb) inline arithmatic syntax
;; help us support a (dumb) inline arithmetic syntax
(declare inline-2-helper)
(defn clean-arg [arg]
(if (seq? arg)

View File

@ -22,7 +22,7 @@ and often automatically.
; Clojure is written in "forms", which are just
; lists of things inside parentheses, separated by whitespace.
;
; The clojure reader assumes that the first thing is a
; The clojure reader assumes that the first thing is a
; function or macro to call, and the rest are arguments.
; The first call in a file should be ns, to set the namespace

View File

@ -573,13 +573,15 @@ nil ; for false - and the empty list
"While `condition` is true, `body` is executed.
`condition` is tested prior to each execution of `body`"
(let ((block-name (gensym)))
(let ((block-name (gensym)) (done (gensym)))
`(tagbody
,block-name
(unless ,condition
(go ,block-name))
(go ,done))
(progn
,@body)
,block-name)))
(go ,block-name)
,done)))
;; Let's look at the high-level version of this:

View File

@ -155,8 +155,8 @@ Now, your handlers may utilize query parameters:
```clojure
(defroutes myapp
(GET "/posts" req
(let [title (get (:params req) "title")
author (get (:params req) "author")]
(let [title (get (:params req) :title)
author (get (:params req) :author)]
(str "Title: " title ", Author: " author))))
```
@ -165,8 +165,8 @@ Or, for POST and PUT requests, form parameters as well
```clojure
(defroutes myapp
(POST "/posts" req
(let [title (get (:params req) "title")
author (get (:params req) "author")]
(let [title (get (:params req) :title)
author (get (:params req) :author)]
(str "Title: " title ", Author: " author))))
```

View File

@ -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
@ -678,6 +747,23 @@ on a new line! ""Wow!"", the masses cried";
private set;
}
// It's also possible to define custom Indexers on objects.
// 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" };
public string this[int i]
{
get {
return passengers[i];
}
set {
return passengers[i] = value;
}
}
//Method to display the attribute values of this Object.
public virtual string Info()
{
@ -720,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 ";
@ -767,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()
@ -781,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
@ -800,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)

View File

@ -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.

View File

@ -17,7 +17,7 @@ Beinahe alle der folgenden Beispiele können als Teile eines Shell-Skripts oder
```bash
#!/bin/bash
# Die erste Zeile des Scripts nennt sich Shebang in gibt dem System an, wie
# Die erste Zeile des Scripts nennt sich Shebang, dies gibt dem System an,
# wie das Script ausgeführt werden soll: http://de.wikipedia.org/wiki/Shebang
# Du hast es bestimmt schon mitgekriegt, Kommentare fangen mit # an. Das Shebang ist auch ein Kommentar

View File

@ -5,34 +5,34 @@ contributors:
- ["Joseph Adams", "https://github.com/jcla1"]
lang: de-de
---
Go wurde entwickelt um probleme zu lösen. Sie ist zwar nicht der neuste Trend in
der Informatik, aber sie ist eine der neusten und schnellsten Wege um Aufgabe in
Go wurde entwickelt, um Probleme zu lösen. Sie ist zwar nicht der neueste Trend in
der Informatik, aber sie ist einer der neuesten und schnellsten Wege, um Aufgabe in
der realen Welt zu lösen.
Sie hat vertraute Elemente von imperativen Sprachen mit statisher Typisierung
Sie hat vertraute Elemente von imperativen Sprachen mit statischer Typisierung
und kann schnell kompiliert und ausgeführt werden. Verbunden mit leicht zu
verstehenden Parallelitäts-Konstrukten, um die heute üblichen mehrkern
Prozessoren optimal nutzen zu können, eignet sich Go äußerst gut für große
Programmierprojekte.
Außerdem beinhaltet Go eine gut ausgestattete standard bibliothek und hat eine
aktive community.
Außerdem beinhaltet Go eine gut ausgestattete Standardbibliothek und hat eine
aktive Community.
```go
// Einzeiliger Kommentar
/* Mehr-
zeiliger Kommentar */
// Eine jede Quelldatei beginnt mit einer Packet-Klausel.
// "main" ist ein besonderer Packetname, da er ein ausführbares Programm
// Eine jede Quelldatei beginnt mit einer Paket-Klausel.
// "main" ist ein besonderer Pkaetname, da er ein ausführbares Programm
// einleitet, im Gegensatz zu jedem anderen Namen, der eine Bibliothek
// deklariert.
package main
// Ein "import" wird verwendet um Packte zu deklarieren, die in dieser
// Ein "import" wird verwendet, um Pakete zu deklarieren, die in dieser
// Quelldatei Anwendung finden.
import (
"fmt" // Ein Packet in der Go standard Bibliothek
"fmt" // Ein Paket in der Go Standardbibliothek
"net/http" // Ja, ein Webserver.
"strconv" // Zeichenkettenmanipulation
)
@ -42,10 +42,10 @@ import (
// Programms. Vergessen Sie nicht die geschweiften Klammern!
func main() {
// Println gibt eine Zeile zu stdout aus.
// Der Prefix "fmt" bestimmt das Packet aus welchem die Funktion stammt.
// Der Prefix "fmt" bestimmt das Paket aus welchem die Funktion stammt.
fmt.Println("Hello world!")
// Aufruf einer weiteren Funktion definiert innerhalb dieses Packets.
// Aufruf einer weiteren Funktion definiert innerhalb dieses Pakets.
beyondHello()
}
@ -54,7 +54,7 @@ func main() {
func beyondHello() {
var x int // Deklaration einer Variable, muss vor Gebrauch geschehen.
x = 3 // Zuweisung eines Werts.
// Kurze Deklaration: Benutzen Sie ":=" um die Typisierung automatisch zu
// Kurze Deklaration: Benutzen Sie ":=", um die Typisierung automatisch zu
// folgern, die Variable zu deklarieren und ihr einen Wert zu zuweisen.
y := 4
@ -70,7 +70,7 @@ func learnMultiple(x, y int) (sum, prod int) {
return x + y, x * y // Wiedergabe zweier Werte
}
// Überblick ueber einige eingebaute Typen und Literale.
// Überblick über einige eingebaute Typen und Literale.
func learnTypes() {
// Kurze Deklarationen sind die Norm.
s := "Lernen Sie Go!" // Zeichenketten-Typ
@ -111,7 +111,7 @@ Zeilenumbrüche beinhalten.` // Selber Zeichenketten-Typ
m["eins"] = 1
// Ungebrauchte Variablen sind Fehler in Go
// Der Unterstrich wird verwendet um einen Wert zu verwerfen.
// Der Unterstrich wird verwendet, um einen Wert zu verwerfen.
_, _, _, _, _, _, _, _, _ = s2, g, f, u, pi, n, a3, s4, bs
// Die Ausgabe zählt natürlich auch als Gebrauch
fmt.Println(s, c, a4, s3, d2, m)
@ -142,7 +142,7 @@ func learnFlowControl() {
if true {
fmt.Println("hab's dir ja gesagt!")
}
// Die Formattierung ist durch den Befehl "go fmt" standardisiert
// Die Formatierung ist durch den Befehl "go fmt" standardisiert
if false {
// nicht hier
} else {
@ -170,7 +170,7 @@ func learnFlowControl() {
continue // wird nie ausgeführt
}
// Wie bei for, bedeutet := in einer Bedingten Anweisung zunächst die
// Wie bei for, bedeutet := in einer bedingten Anweisung zunächst die
// Zuweisung und erst dann die Überprüfung der Bedingung.
if y := expensiveComputation(); y > x {
x = y
@ -217,8 +217,8 @@ func learnInterfaces() {
// Aufruf der String Methode von i, gleiche Ausgabe wie zuvor.
fmt.Println(i.String())
// Funktionen des fmt-Packets rufen die String() Methode auf um eine
// druckbare variante des Empfängers zu erhalten.
// Funktionen des fmt-Pakets rufen die String() Methode auf um eine
// druckbare Variante des Empfängers zu erhalten.
fmt.Println(p) // gleiche Ausgabe wie zuvor
fmt.Println(i) // und wieder die gleiche Ausgabe wie zuvor
@ -244,18 +244,18 @@ func learnErrorHandling() {
learnConcurrency()
}
// c ist ein Kannal, ein sicheres Kommunikationsmedium.
// c ist ein Kanal, ein sicheres Kommunikationsmedium.
func inc(i int, c chan int) {
c <- i + 1 // <- ist der "send" Operator, wenn ein Kannal auf der Linken ist
c <- i + 1 // <- ist der "send" Operator, wenn ein Kanal auf der Linken ist
}
// Wir verwenden "inc" um Zahlen parallel zu erhöhen.
func learnConcurrency() {
// Die selbe "make"-Funktion wie vorhin. Sie initialisiert Speicher für
// maps, slices und Kannäle.
// maps, slices und Kanäle.
c := make(chan int)
// Starte drei parallele "Goroutines". Die Zahlen werden parallel (concurrently)
// erhöht. Alle drei senden ihr Ergebnis in den gleichen Kannal.
// erhöht. Alle drei senden ihr Ergebnis in den gleichen Kanal.
go inc(0, c) // "go" ist das Statement zum Start einer neuen Goroutine
go inc(10, c)
go inc(-805, c)
@ -269,16 +269,16 @@ func learnConcurrency() {
// Start einer neuen Goroutine, nur um einen Wert zu senden
go func() { c <- 84 }()
go func() { cs <- "wortreich" }() // schon wider, diesmal für
go func() { cs <- "wortreich" }() // schon wieder, diesmal für
// "select" hat eine Syntax wie ein switch Statement, aber jeder Fall ist
// eine Kannaloperation. Es wählt eine Fall zufällig aus allen die
// kommunikationsbereit sind aus.
// eine Kanaloperation. Es wählt einen Fall zufällig aus allen, die
// kommunikationsbereit sind, aus.
select {
case i := <-c: // der empfangene Wert kann einer Variable zugewiesen werden
fmt.Printf("es ist ein: %T", i)
case <-cs: // oder der Wert kann verworfen werden
fmt.Println("es ist eine Zeichenkette!")
case <-cc: // leerer Kannal, nicht bereit für den Empfang
case <-cc: // leerer Kanal, nicht bereit für den Empfang
fmt.Println("wird nicht passieren.")
}
// Hier wird eine der beiden Goroutines fertig sein, die andere nicht.
@ -287,16 +287,16 @@ func learnConcurrency() {
learnWebProgramming() // Go kann es und Sie hoffentlich auch bald.
}
// Eine einzige Funktion aus dem http-Packet kann einen Webserver starten.
// Eine einzige Funktion aus dem http-Paket kann einen Webserver starten.
func learnWebProgramming() {
// Der erste Parameter von "ListenAndServe" ist eine TCP Addresse an die
// Der erste Parameter von "ListenAndServe" ist eine TCP Addresse, an die
// sich angeschlossen werden soll.
// Der zweite Parameter ist ein Interface, speziell: ein http.Handler
err := http.ListenAndServe(":8080", pair{})
fmt.Println(err) // Fehler sollte man nicht ignorieren!
}
// Wir lassen "pair" das http.Handler Interface erfüllen indem wir seine einzige
// Wir lassen "pair" das http.Handler Interface erfüllen, indem wir seine einzige
// Methode implementieren: ServeHTTP
func (p pair) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// Senden von Daten mit einer Methode des http.ResponseWriter
@ -313,6 +313,6 @@ Auch zu empfehlen ist die Spezifikation von Go, die nach heutigen Standards sehr
kurz und auch gut verständlich formuliert ist. Auf der Leseliste von Go-Neulingen
ist außerdem der Quelltext der [Go standard Bibliothek](http://golang.org/src/pkg/).
Gut documentiert, demonstriert sie leicht zu verstehendes und im idiomatischen Stil
verfasstes Go. Erreichbar ist der Quelltext auch durch das Klicken der Funktions-
Namen in der [offiziellen Dokumentation von Go](http://golang.org/pkg/).
verfasstes Go. Erreichbar ist der Quelltext auch durch das Klicken der Funktionsnamen
in der [offiziellen Dokumentation von Go](http://golang.org/pkg/).

View File

@ -149,7 +149,7 @@ li[0] #=> 1
# Das letzte Element ansehen
li[-1] #=> 3
# Bei Zugriffen außerhal der Liste kommt es jedoch zu einem IndexError
# Bei Zugriffen außerhalb der Liste kommt es jedoch zu einem IndexError
li[4] # Raises an IndexError
# Wir können uns Ranges mit Slice-Syntax ansehen
@ -188,7 +188,7 @@ tup[:2] #=> (1, 2)
# Wir können Tupel (oder Listen) in Variablen entpacken
a, b, c = (1, 2, 3) # a ist jetzt 1, b ist jetzt 2 und c ist jetzt 3
# Tuple werden standardmäßig erstellt, wenn wir uns die Klammern sparen
# Tupel werden standardmäßig erstellt, wenn wir uns die Klammern sparen
d, e, f = 4, 5, 6
# Es ist kinderleicht zwei Werte zu tauschen
e, d = d, e # d is now 5 and e is now 4

138
de-de/yaml-de.html.markdown Normal file
View File

@ -0,0 +1,138 @@
---
language: yaml
filename: learnyaml.yaml
contributors:
- ["Adam Brenecki", "https://github.com/adambrenecki"]
translators:
- ["Ruben M.", https://github.com/switchhax]
---
YAML ist eine Sprache zur Datenserialisierung, die sofort von Menschenhand geschrieben und gelesen werden kann.
YAML ist eine Erweiterung von JSON, mit der Erweiterung von syntaktisch wichtigen Zeilenumbrüche und Einrückung sowie in Python. Anders als in Python erlaubt YAML keine Tabulator-Zeichen.
```yaml
# Kommentare in YAML schauen so aus.
#################
# SKALARE TYPEN #
#################
# Unser Kernobjekt (für das ganze Dokument) wird das Assoziative Datenfeld (Map) sein,
# welches equivalent zu einem Hash oder einem Objekt einer anderen Sprache ist.
Schlüssel: Wert
nochn_Schlüssel: Hier kommt noch ein Wert hin.
eine_Zahl: 100
wissenschaftliche_Notation: 1e+12
boolean: true
null_Wert: null
Schlüssel mit Leerzeichen: value
# Strings müssen nicht immer mit Anführungszeichen umgeben sein, können aber:
jedoch: "Ein String in Anführungzeichen"
"Ein Schlüssel in Anführungszeichen": "Nützlich, wenn du einen Doppelpunkt im Schluessel haben willst."
# Mehrzeilige Strings schreibst du am besten als 'literal block' (| gefolgt vom Text)
# oder ein 'folded block' (> gefolgt vom text).
literal_block: |
Dieser ganze Block an Text ist der Wert vom Schlüssel literal_block,
mit Erhaltung der Zeilenumbrüche.
Das Literal fährt solange fort bis dieses unverbeult ist und die vorherschende Einrückung wird
gekürzt.
Zeilen, die weiter eingerückt sind, behalten den Rest ihrer Einrückung -
diese Zeilen sind mit 4 Leerzeichen eingerückt.
folded_style: >
Dieser ganze Block an Text ist der Wert vom Schlüssel folded_style, aber diesmal
werden alle Zeilenumbrüche durch ein Leerzeichen ersetzt.
Freie Zeilen, wie obendrüber, werden in einen Zeilenumbruch verwandelt.
Weiter eingerückte Zeilen behalten ihre Zeilenumbrüche -
diese Textpassage wird auf zwei Zeilen sichtbar sein.
####################
# COLLECTION TYPEN #
####################
# Verschachtelung wird duch Einrückung erzielt.
eine_verschachtelte_map:
schlüssel: wert
nochn_Schlüssel: Noch ein Wert.
noch_eine_verschachtelte_map:
hallo: hallo
# Schlüssel müssen nicht immer String sein.
0.25: ein Float-Wert als Schluessel
# Schlüssel können auch mehrzeilig sein, ? symbolisiert den Anfang des Schlüssels
? |
Dies ist ein Schlüssel,
der mehrzeilig ist.
: und dies ist sein Wert
# YAML erlaubt auch Collections als Schlüssel, doch viele Programmiersprachen
# werden sich beklagen.
# Folgen (equivalent zu Listen oder Arrays) schauen so aus:
eine_Folge:
- Artikel 1
- Artikel 2
- 0.5 # Folgen können verschiedene Typen enthalten.
- Artikel 4
- schlüssel: wert
nochn_schlüssel: nochn_wert
-
- Dies ist eine Folge
- innerhalb einer Folge
# Weil YAML eine Erweiterung von JSON ist, können JSON-ähnliche Maps und Folgen
# geschrieben werden:
json_map: {"schlüssel": "wert"}
json_seq: [3, 2, 1, "Start"]
############################
# EXTRA YAML EIGENSCHAFTEN #
############################
# YAML stellt zusätzlich Verankerung zu Verfügung, welche es einfach machen
# Inhalte im Dokument zu vervielfältigen. Beide Schlüssel werden den selben Wert haben.
verankerter_inhalt: &anker_name Dieser String wird als Wert beider Schlüssel erscheinen.
anderer_anker: *anker_name
# YAML hat auch Tags, mit denen man explizit Typangaben angibt.
explicit_string: !!str 0.5
# Manche Parser implementieren sprachspezifische Tags wie dieser hier für Pythons
# komplexe Zahlen.
python_komplexe_Zahlen: !!python/komplex 1+2j
####################
# EXTRA YAML TYPEN #
####################
# Strings and Zahlen sind nicht die einzigen Skalare, welche YAML versteht.
# ISO-formatierte Datumsangaben and Zeiangaben können ebenso geparsed werden.
DatumZeit: 2001-12-15T02:59:43.1Z
DatumZeit_mit_Leerzeichen: 2001-12-14 21:59:43.10 -5
Datum: 2002-12-14
# Der !!binary Tag zeigt das ein String base64 verschlüsselt ist.
# Representation des Binären Haufens
gif_datei: !!binary |
R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5
OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+
+f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC
AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs=
# YAML bietet auch Mengen (Sets), welche so ausschauen
menge:
? artikel1
? artikel2
? artikel3
# Wie in Python sind Mengen nicht anderes als Maps nur mit null als Wert; das Beispiel oben drüber ist equivalent zu:
menge:
artikel1: null
artikel2: null
artikel3: null
```

View File

@ -29,7 +29,7 @@ filename: learn-emacs-lisp.el
;; I hereby decline any responsability. Have fun!
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;
;; Fire up Emacs.
;;
;; Hit the `q' key to dismiss the welcome message.
@ -42,9 +42,9 @@ filename: learn-emacs-lisp.el
;; The scratch buffer is the default buffer when opening Emacs.
;; You are never editing files: you are editing buffers that you
;; can save to a file.
;;
;;
;; "Lisp interaction" refers to a set of commands available here.
;;
;;
;; Emacs has a built-in set of commands available in every buffer,
;; and several subsets of commands available when you activate a
;; specific mode. Here we use the `lisp-interaction-mode', which
@ -109,7 +109,7 @@ filename: learn-emacs-lisp.el
;; The empty parentheses in the function's definition means that
;; it does not accept arguments. But always using `my-name' is
;; boring, let's tell the function to accept one argument (here
;; the argument is called "name"):
;; the argument is called "name"):
(defun hello (name) (insert "Hello " name))
;; `C-xC-e' => hello
@ -305,7 +305,7 @@ filename: learn-emacs-lisp.el
(defun boldify-names ()
(switch-to-buffer-other-window "*test*")
(goto-char (point-min))
(while (re-search-forward "Bonjour \\([^!]+\\)!" nil 't)
(while (re-search-forward "Bonjour \\(.+\\)!" nil 't)
(add-text-properties (match-beginning 1)
(match-end 1)
(list 'face 'bold)))
@ -318,7 +318,7 @@ filename: learn-emacs-lisp.el
;; The regular expression is "Bonjour \\(.+\\)!" and it reads:
;; the string "Bonjour ", and
;; a group of | this is the \\( ... \\) construct
;; any character not ! | this is the [^!]
;; any character | this is the .
;; possibly repeated | this is the +
;; and the "!" string.

View File

@ -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
## ---------------------------

View File

@ -18,7 +18,7 @@ filename: learnerlang.erl
% Periods (`.`) (followed by whitespace) separate entire functions and
% expressions in the shell.
% Semicolons (`;`) separate clauses. We find clauses in several contexts:
% function definitions and in `case`, `if`, `try..catch` and `receive`
% function definitions and in `case`, `if`, `try..catch`, and `receive`
% expressions.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -27,20 +27,20 @@ filename: learnerlang.erl
Num = 42. % All variable names must start with an uppercase letter.
% Erlang has single assignment variables, if you try to assign a different value
% to the variable `Num`, youll get an error.
% Erlang has single-assignment variables; if you try to assign a different
% value to the variable `Num`, youll get an error.
Num = 43. % ** exception error: no match of right hand side value 43
% In most languages, `=` denotes an assignment statement. In Erlang, however,
% `=` denotes a pattern matching operation. `Lhs = Rhs` really means this:
% evaluate the right side (Rhs), and then match the result against the pattern
% on the left side (Lhs).
% `=` denotes a pattern-matching operation. `Lhs = Rhs` really means this:
% evaluate the right side (`Rhs`), and then match the result against the
% pattern on the left side (`Lhs`).
Num = 7 * 6.
% Floating point number.
% Floating-point number.
Pi = 3.14159.
% Atoms, are used to represent different non-numerical constant values. Atoms
% Atoms are used to represent different non-numerical constant values. Atoms
% start with lowercase letters, followed by a sequence of alphanumeric
% characters or the underscore (`_`) or at (`@`) sign.
Hello = hello.
@ -53,34 +53,34 @@ AtomWithSpace = 'some atom with space'.
% Tuples are similar to structs in C.
Point = {point, 10, 45}.
% If we want to extract some values from a tuple, we use the pattern matching
% If we want to extract some values from a tuple, we use the pattern-matching
% operator `=`.
{point, X, Y} = Point. % X = 10, Y = 45
% We can use `_` as a placeholder for variables that were not interested in.
% The symbol `_` is called an anonymous variable. Unlike regular variables,
% several occurrences of _ in the same pattern dont have to bind to the same
% value.
% several occurrences of `_` in the same pattern dont have to bind to the
% same value.
Person = {person, {name, {first, joe}, {last, armstrong}}, {footsize, 42}}.
{_, {_, {_, Who}, _}, _} = Person. % Who = joe
% We create a list by enclosing the list elements in square brackets and
% separating them with commas.
% The individual elements of a list can be of any type.
% The first element of a list is the head of the list. If you imagine removing the
% head from the list, whats left is called the tail of the list.
% The first element of a list is the head of the list. If you imagine removing
% the head from the list, whats left is called the tail of the list.
ThingsToBuy = [{apples, 10}, {pears, 6}, {milk, 3}].
% If `T` is a list, then `[H|T]` is also a list, with head `H` and tail `T`.
% The vertical bar (`|`) separates the head of a list from its tail.
% `[]` is the empty list.
% We can extract elements from a list with a pattern matching operation. If we
% We can extract elements from a list with a pattern-matching operation. If we
% have a nonempty list `L`, then the expression `[X|Y] = L`, where `X` and `Y`
% are unbound variables, will extract the head of the list into `X` and the tail
% of the list into `Y`.
[FirstThing|OtherThingsToBuy] = ThingsToBuy.
% FirstThing = {apples, 10}
% OtherThingsToBuy = {pears, 6}, {milk, 3}
% OtherThingsToBuy = [{pears, 6}, {milk, 3}]
% There are no strings in Erlang. Strings are really just lists of integers.
% Strings are enclosed in double quotation marks (`"`).
@ -117,17 +117,19 @@ c(geometry). % {ok,geometry}
geometry:area({rectangle, 10, 5}). % 50
geometry:area({circle, 1.4}). % 6.15752
% In Erlang, two functions with the same name and different arity (number of arguments)
% in the same module represent entirely different functions.
% In Erlang, two functions with the same name and different arity (number of
% arguments) in the same module represent entirely different functions.
-module(lib_misc).
-export([sum/1]). % export function `sum` of arity 1 accepting one argument: list of integers.
-export([sum/1]). % export function `sum` of arity 1
% accepting one argument: list of integers.
sum(L) -> sum(L, 0).
sum([], N) -> N;
sum([H|T], N) -> sum(T, H+N).
% Funs are "anonymous" functions. They are called this way because they have no
% name. However they can be assigned to variables.
Double = fun(X) -> 2*X end. % `Double` points to an anonymous function with handle: #Fun<erl_eval.6.17052888>
% Funs are "anonymous" functions. They are called this way because they have
% no name. However, they can be assigned to variables.
Double = fun(X) -> 2 * X end. % `Double` points to an anonymous function
% with handle: #Fun<erl_eval.6.17052888>
Double(2). % 4
% Functions accept funs as their arguments and can return funs.
@ -140,8 +142,9 @@ Triple(5). % 15
% The notation `[F(X) || X <- L]` means "the list of `F(X)` where `X` is taken
% from the list `L`."
L = [1,2,3,4,5].
[2*X || X <- L]. % [2,4,6,8,10]
% A list comprehension can have generators and filters which select subset of the generated values.
[2 * X || X <- L]. % [2,4,6,8,10]
% A list comprehension can have generators and filters, which select subset of
% the generated values.
EvenNumbers = [N || N <- [1, 2, 3, 4], N rem 2 == 0]. % [2, 4]
% Guards are constructs that we can use to increase the power of pattern
@ -155,17 +158,24 @@ max(X, Y) -> Y.
% A guard is a series of guard expressions, separated by commas (`,`).
% The guard `GuardExpr1, GuardExpr2, ..., GuardExprN` is true if all the guard
% expressions `GuardExpr1, GuardExpr2, ...` evaluate to true.
% expressions `GuardExpr1`, `GuardExpr2`, ..., `GuardExprN` evaluate to `true`.
is_cat(A) when is_atom(A), A =:= cat -> true;
is_cat(A) -> false.
is_dog(A) when is_atom(A), A =:= dog -> true;
is_dog(A) -> false.
% A `guard sequence` is either a single guard or a series of guards, separated
%by semicolons (`;`). The guard sequence `G1; G2; ...; Gn` is true if at least
% one of the guards `G1, G2, ...` evaluates to true.
is_pet(A) when is_dog(A); is_cat(A) -> true;
is_pet(A) -> false.
% A guard sequence is either a single guard or a series of guards, separated
% by semicolons (`;`). The guard sequence `G1; G2; ...; Gn` is true if at
% least one of the guards `G1`, `G2`, ..., `Gn` evaluates to `true`.
is_pet(A) when is_atom(A), (A =:= dog) or (A =:= cat) -> true;
is_pet(A) -> false.
% Warning: not all valid Erlang expressions can be used as guard expressions;
% in particular, our `is_cat` and `is_dog` functions cannot be used within the
% guard sequence in `is_pet`'s definition. For a description of the
% expressions allowed in guard sequences, refer to this
% [section](http://erlang.org/doc/reference_manual/expressions.html#id81912)
% of the Erlang reference manual.
% Records provide a method for associating a name with a particular element in a
% tuple.
@ -188,7 +198,7 @@ X = #todo{}.
X1 = #todo{status = urgent, text = "Fix errata in book"}.
% #todo{status = urgent, who = joe, text = "Fix errata in book"}
X2 = X1#todo{status = done}.
% #todo{status = done,who = joe,text = "Fix errata in book"}
% #todo{status = done, who = joe, text = "Fix errata in book"}
% `case` expressions.
% `filter` returns a list of all elements `X` in a list `L` for which `P(X)` is
@ -206,11 +216,11 @@ max(X, Y) ->
if
X > Y -> X;
X < Y -> Y;
true -> nil;
true -> nil
end.
% Warning: at least one of the guards in the `if` expression must evaluate to true;
% otherwise, an exception will be raised.
% Warning: at least one of the guards in the `if` expression must evaluate to
% `true`; otherwise, an exception will be raised.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -218,7 +228,7 @@ max(X, Y) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Exceptions are raised by the system when internal errors are encountered or
% explicitly in code by calling `throw(Exception)`, `exit(Exception)` or
% explicitly in code by calling `throw(Exception)`, `exit(Exception)`, or
% `erlang:error(Exception)`.
generate_exception(1) -> a;
generate_exception(2) -> throw(a);
@ -227,7 +237,7 @@ generate_exception(4) -> {'EXIT', a};
generate_exception(5) -> erlang:error(a).
% Erlang has two methods of catching an exception. One is to enclose the call to
% the function, which raised the exception within a `try...catch` expression.
% the function that raises the exception within a `try...catch` expression.
catcher(N) ->
try generate_exception(N) of
Val -> {N, normal, Val}
@ -241,23 +251,24 @@ catcher(N) ->
% exception, it is converted into a tuple that describes the error.
catcher(N) -> catch generate_exception(N).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% 4. Concurrency
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Erlang relies on the actor model for concurrency. All we need to write
% concurrent programs in erlang are three primitives: spawning processes,
% concurrent programs in Erlang are three primitives: spawning processes,
% sending messages and receiving messages.
% To start a new process we use the `spawn` function, which takes a function
% To start a new process, we use the `spawn` function, which takes a function
% as argument.
F = fun() -> 2 + 2 end. % #Fun<erl_eval.20.67289768>
spawn(F). % <0.44.0>
% `spawn` returns a pid (process identifier), you can use this pid to send
% messages to the process. To do message passing we use the `!` operator.
% For all of this to be useful we need to be able to receive messages. This is
% `spawn` returns a pid (process identifier); you can use this pid to send
% messages to the process. To do message passing, we use the `!` operator.
% For all of this to be useful, we need to be able to receive messages. This is
% achieved with the `receive` mechanism:
-module(calculateGeometry).
@ -272,12 +283,13 @@ calculateArea() ->
io:format("We can only calculate area of rectangles or circles.")
end.
% Compile the module and create a process that evaluates `calculateArea` in the shell
% Compile the module and create a process that evaluates `calculateArea` in the
% shell.
c(calculateGeometry).
CalculateArea = spawn(calculateGeometry, calculateArea, []).
CalculateArea ! {circle, 2}. % 12.56000000000000049738
% The shell is also a process, you can use `self` to get the current pid
% The shell is also a process; you can use `self` to get the current pid.
self(). % <0.41.0>
```

159
es-es/haml-es.html.markdown Normal file
View File

@ -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.

View File

@ -12,7 +12,7 @@ such as Open Firmware. It's also used by NASA.
Note: This article focuses predominantly on the Gforth implementation of
Forth, but most of what is written here should work elsewhere.
```forth
```
\ This is a comment
( This is also a comment but it's only used when defining words )

View File

@ -13,7 +13,7 @@ Brainfuck (sans majuscule à part au début dune phrase) est un langage
Turing-complet extrêmement simple avec seulement 8 commandes.
```
Tout caractère en dehors de "><+-.,[]" (en dehors des guillements) est ignoré.
Tout caractère en dehors de "><+-.,[]" (en dehors des guillemets) est ignoré.
Brainfuck est représenté par un tableau de 30 000 cellules initialisées à 0 et
un pointeur de données pointant sur la cellule courante.

439
fr-fr/go-fr.html.markdown Normal file
View File

@ -0,0 +1,439 @@
---
name: Go
category: language
language: Go
lang: fr-fr
filename: learngo.go
contributors:
- ["Sonia Keys", "https://github.com/soniakeys"]
- ["Christopher Bess", "https://github.com/cbess"]
- ["Jesse Johnson", "https://github.com/holocronweaver"]
- ["Quint Guvernator", "https://github.com/qguv"]
- ["Jose Donizetti", "https://github.com/josedonizetti"]
- ["Alexej Friesen", "https://github.com/heyalexej"]
- ["Jean-Philippe Monette", "http://blogue.jpmonette.net/"]
---
Go a été créé dans l'optique de développer de façon efficace. Ce n'est pas la
dernière tendance en ce qui est au développement, mais c'est la nouvelle façon
de régler des défis réels de façon rapide.
Le langage possède des concepts familiers à la programmation impérative avec
typage. Il est rapide à compiler et exécuter, ajoute une concurrence facile à
comprendre, pour les processeurs multi coeurs d'aujourd'hui et apporte des
fonctionnalités facilitant le développement à grande échelle.
Développer avec Go, c'est bénéficier d'une riche bibliothèque standard et d'une
communauté active.
```go
// Commentaire ligne simple
/* Commentaire
multiligne */
// Un paquet débute avec une clause "package"
// "Main" est un nom spécial déclarant un paquet de type exécutable plutôt
// qu'une bibliothèque
package main
// "Import" déclare les paquets référencés dans ce fichier.
import (
"fmt" // Un paquet dans la bibliothèque standard.
"io/ioutil" // Implémente des fonctions utilitaires I/O.
m "math" // Bibliothèque mathématique utilisant un alias local "m".
"net/http" // Un serveur Web!
"strconv" // Bibliothèque pour convertir les chaînes de caractères.
)
// Une définition de fonction. La fonction "main" est spéciale - c'est le point
// d'entrée du binaire.
func main() {
// Println retournera la valeur à la console.
// Associez la fonction avec son paquet respectif, fmt.
fmt.Println("Hello world!")
// Appelez une fonction différente à partir de ce paquet.
beyondHello()
}
// Les fonctions ont des paramètres entre parenthèses.
// Les parenthèses sont nécessaires avec ou sans paramètre.
func beyondHello() {
var x int // Déclaration de variable. Les variables doivent être déclarées
// avant leur utilisation.
x = 3 // Assignation de valeur.
// Les déclarations courtes utilisent := pour inférer le type, déclarer et
// assigner.
y := 4
sum, prod := learnMultiple(x, y) // La fonction retourne deux valeurs.
fmt.Println("sum:", sum, "prod:", prod) // Affichage simple.
learnTypes() // < y minutes, en savoir plus!
}
// Les fonctions peuvent avoir des paramètres et plusieurs valeurs retournées.
func learnMultiple(x, y int) (sum, prod int) {
return x + y, x * y // Deux valeurs retournées.
}
// Quelques types inclus et littéraux.
func learnTypes() {
// Une déclaration courte infère généralement le type désiré.
str := "Learn Go!" // Type string.
s2 := `Une chaîne de caractères peut contenir des
sauts de ligne.` // Chaîne de caractère.
// Littéral non-ASCII. Les sources Go utilisent le charset UTF-8.
g := 'Σ' // type rune, un alias pour le type int32, contenant un caractère
// unicode.
f := 3.14195 // float64, un nombre flottant IEEE-754 de 64-bit.
c := 3 + 4i // complex128, considéré comme deux float64 par le compilateur.
// Syntaxe "var" avec une valeur d'initialisation.
var u uint = 7 // Non signé, mais la taille dépend selon l'entier.
var pi float32 = 22. / 7
// Conversion avec syntaxe courte.
n := byte('\n') // byte est un alias du type uint8.
// Les tableaux ont une taille fixe déclarée à la compilation.
var a4 [4]int // Un tableau de 4 ints, tous initialisés à 0.
a3 := [...]int{3, 1, 5} // Un tableau initialisé avec une taille fixe de 3
// éléments, contenant les valeurs 3, 1 et 5.
// Les slices ont des tailles dynamiques. Les tableaux et slices ont chacun
// des avantages, mais les cas d'utilisation des slices sont plus fréquents.
s3 := []int{4, 5, 9} // Comparable à a3.
s4 := make([]int, 4) // Alloue un slice de 4 ints, initialisés à 0.
var d2 [][]float64 // Déclaration seulement, sans allocation de mémoire.
bs := []byte("a slice") // Conversion d'une chaîne en slice de bytes.
// Parce qu'elles sont dynamiques, les slices peuvent être jointes sur
// demande. Pour joindre un élément à une slice, la fonction standard append()
// est utilisée. Le premier argument est la slice à utiliser. Habituellement,
// la variable tableau est mise à jour sur place, voir ci-bas.
s := []int{1, 2, 3} // Le résultat est une slice de taille 3.
s = append(s, 4, 5, 6) // Ajout de 3 valeurs. La taille est de 6.
fmt.Println(s) // La valeur est de [1 2 3 4 5 6]
// Pour ajouter une slice à une autre, au lieu d'utiliser une liste de valeurs
// atomiques, il est possible de mettre en argument une référence de
// slice littérale grâce aux points de suspension.
s = append(s, []int{7, 8, 9}...) // Le deuxième argument est une slice
// littérale.
fmt.Println(s) // La slice contient [1 2 3 4 5 6 7 8 9]
p, q := learnMemory() // Déclare p, q comme étant des pointeurs de type int.
fmt.Println(*p, *q) // * suit un pointeur. Ceci retourne deux ints.
// Les maps sont des tableaux associatifs de taille dynamique, comme les
// hash ou les types dictionnaires de certains langages.
m := map[string]int{"trois": 3, "quatre": 4}
m["un"] = 1
// Les valeurs inutilisées sont considérées comme des erreurs en Go.
// Un tiret bas permet d'ignorer une valeur inutilisée, évitant une erreur.
_, _, _, _, _, _, _, _, _, _ = str, s2, g, f, u, pi, n, a3, s4, bs
// Cependant, son affichage en console est considéré comme une utilisation,
// ce qui ne sera pas considéré comme une erreur à la compilation.
fmt.Println(s, c, a4, s3, d2, m)
learnFlowControl() // De retour dans le flux.
}
// Il est possible, à l'opposé de plusieurs autres langages, de retourner des
// variables par leur nom à partir de fonctions.
// Assigner un nom à un type retourné par une fonction permet de retrouver sa
// valeur ainsi que d'utiliser le mot-clé "return" uniquement, sans plus.
func learnNamedReturns(x, y int) (z int) {
z = x * y
return // z est implicite, car la variable a été définie précédemment.
}
// La récupération de la mémoire est automatique en Go. Le langage possède des
// pointeurs, mais aucune arithmétique des pointeurs (*(a + b) en C). Vous
// pouvez produire une erreur avec un pointeur nil, mais pas en incrémentant un
// pointeur.
func learnMemory() (p, q *int) {
// Les valeurs retournées p et q auront le type pointeur int.
p = new(int) // Fonction standard "new" alloue la mémoire.
// Le int alloué est initialisé à 0, p n'est plus nil.
s := make([]int, 20) // Alloue 20 ints en un seul bloc de mémoire.
s[3] = 7 // Assigne l'un des entiers.
r := -2 // Déclare une autre variable locale.
return &s[3], &r // & retourne l'adresse d'un objet.
}
func expensiveComputation() float64 {
return m.Exp(10)
}
func learnFlowControl() {
// Bien que les "if" requièrent des accolades, les parenthèses ne sont pas
// nécessaires pour contenir le test booléen.
if true {
fmt.Println("voilà!")
}
// Le formatage du code est standardisé par la commande shell "go fmt."
if false {
// bing.
} else {
// bang.
}
// Utilisez "switch" au lieu des "if" en chaîne
x := 42.0
switch x {
case 0:
case 1:
case 42:
// Les "case" n'ont pas besoin de "break;".
case 43:
// Non-exécuté.
}
// Comme les "if", les "for" n'utilisent pas de parenthèses.
// Les variables déclarées dans les "for" et les "if" sont locales à leur
// portée.
for x := 0; x < 3; x++ { // ++ est une incrémentation.
fmt.Println("itération ", x)
}
// x == 42 ici.
// "For" est le seul type de boucle en Go, mais possède différentes formes.
for { // Boucle infinie
break // C'est une farce
continue // Non atteint.
}
// Vous pouvez utiliser une "range" pour itérer dans un tableau, une slice, une
// chaîne, une map ou un canal. Les "range" retournent un canal ou deux
// valeurs (tableau, slice, chaîne et map).
for key, value := range map[string]int{"une": 1, "deux": 2, "trois": 3} {
// pour chaque pair dans une map, affichage de la valeur et clé
fmt.Printf("clé=%s, valeur=%d\n", key, value)
}
// À l'opposé du "for", := dans un "if" signifie la déclaration et
// l'assignation y en premier, et ensuite y > x
if y := expensiveComputation(); y > x {
x = y
}
// Les fonctions littérales sont des fermetures.
xBig := func() bool {
return x > 10000
}
fmt.Println("xBig:", xBig()) // true (la valeur e^10 a été assignée à x).
x = 1.3e3 // Ceci fait x == 1300
fmt.Println("xBig:", xBig()) // Maintenant false.
// De plus, les fonctions littérales peuvent être définies et appelées
// sur la même ligne, agissant comme argument à cette fonction, tant que:
// a) la fonction littérale est appelée suite à (),
// b) le résultat correspond au type de l'argument.
fmt.Println("Ajoute + multiplie deux nombres : ",
func(a, b int) int {
return (a + b) * 2
}(10, 2)) // Appelle la fonction avec les arguments 10 et 2
// => Ajoute + double deux nombres : 24
// Quand vous en aurez besoin, vous allez l'adorer.
goto love
love:
learnFunctionFactory() // func retournant func correspondant à fun(3)(3).
learnDefer() // Un survol de cette instruction importante.
learnInterfaces() // Incontournable !
}
func learnFunctionFactory() {
// Les deux syntaxes sont identiques, bien que la seconde soit plus pratique.
fmt.Println(sentenceFactory("été")("Une matinée d'", "agréable!"))
d := sentenceFactory("été")
fmt.Println(d("Une matinée d'", "agréable!"))
fmt.Println(d("Une soirée d'", "relaxante!"))
}
// Le décorateur est un patron de conception commun dans d'autres langages.
// Il est possible de faire de même en Go avec des fonctions littérales
// acceptant des arguments.
func sentenceFactory(mystring string) func(before, after string) string {
return func(before, after string) string {
return fmt.Sprintf("%s %s %s", before, mystring, after) // nouvelle chaîne
}
}
func learnDefer() (ok bool) {
// Les déclarations différées sont exécutées avant la sortie d'une fonction.
defer fmt.Println("les déclarations différées s'exécutent en ordre LIFO.")
defer fmt.Println("\nCette ligne est affichée en premier parce que")
// Les déclarations différées sont utilisées fréquemment pour fermer un
// fichier, afin que la fonction ferme le fichier en fin d'exécution.
return true
}
// Défini Stringer comme étant une interface avec une méthode, String.
type Stringer interface {
String() string
}
// Défini pair comme étant une structure contenant deux entiers, x et y.
type pair struct {
x, y int
}
// Défini une méthode associée au type pair. Pair implémente maintenant Stringer
func (p pair) String() string { // p s'appelle le "destinataire"
// Sprintf est une autre fonction publique dans le paquet fmt.
// La syntaxe avec point permet de faire référence aux valeurs de p.
return fmt.Sprintf("(%d, %d)", p.x, p.y)
}
func learnInterfaces() {
// La syntaxe avec accolade défini une "structure littérale". Celle-ci
// s'évalue comme étant une structure. La syntaxe := déclare et initialise p
// comme étant une instance.
p := pair{3, 4}
fmt.Println(p.String()) // Appelle la méthode String de p, de type pair.
var i Stringer // Déclare i instance de l'interface Stringer.
i = p // Valide, car pair implémente Stringer.
// Appelle la méthode String de i, de type Stringer. Retourne la même valeur
// que ci-haut.
fmt.Println(i.String())
// Les fonctions dans le paquet fmt appellent la méthode String, demandant
// aux objets d'afficher une représentation de leur structure.
fmt.Println(p) // Affiche la même chose que ci-haut. Println appelle la
// méthode String.
fmt.Println(i) // Affiche la même chose que ci-haut.
learnVariadicParams("apprentissage", "génial", "ici!")
}
// Les fonctions peuvent être définie de façon à accepter un ou plusieurs
// paramètres grâce aux points de suspension, offrant une flexibilité lors de
// son appel.
func learnVariadicParams(myStrings ...interface{}) {
// Itère chaque paramètre dans la range.
// Le tiret bas sert à ignorer l'index retourné du tableau.
for _, param := range myStrings {
fmt.Println("paramètre:", param)
}
// Passe une valeur variadique comme paramètre variadique.
fmt.Println("paramètres:", fmt.Sprintln(myStrings...))
learnErrorHandling()
}
func learnErrorHandling() {
// ", ok" idiome utilisée pour définir si l'opération s'est déroulée avec
// succès ou non
m := map[int]string{3: "trois", 4: "quatre"}
if x, ok := m[1]; !ok { // ok sera faux, car 1 n'est pas dans la map.
fmt.Println("inexistant")
} else {
fmt.Print(x) // x serait la valeur, si elle se trouvait dans la map.
}
// Une erreur ne retourne qu'un "ok", mais également plus d'information
// par rapport à un problème survenu.
if _, err := strconv.Atoi("non-int"); err != nil { // _ discarte la valeur
// retourne: 'strconv.ParseInt: parsing "non-int": invalid syntax'
fmt.Println(err)
}
// Nous réviserons les interfaces un peu plus tard. Pour l'instant,
learnConcurrency()
}
// c est un canal, un objet permettant de communiquer en simultané de façon
// sécurisée.
func inc(i int, c chan int) {
c <- i + 1 // <- est l'opérateur "envoi" quand un canal apparaît à
// gauche.
}
// Nous utiliserons inc pour incrémenter des nombres en même temps.
func learnConcurrency() {
// La fonction "make" utilisée précédemment pour générer un slice. Elle
// alloue et initialise les slices, maps et les canaux.
c := make(chan int)
// Démarrage de trois goroutines simultanées. Les nombres seront incrémentés
// simultanément, peut-être en paralèle si la machine le permet et configurée
// correctement. Les trois utilisent le même canal.
go inc(0, c) // go est une instruction démarrant une nouvelle goroutine.
go inc(10, c)
go inc(-805, c)
// Lis et affiche trois résultats du canal - impossible de savoir dans quel
// ordre !
fmt.Println(<-c, <-c, <-c) // Canal à droite, <- est l'opérateur de
// "réception".
cs := make(chan string) // Un autre canal, celui-ci gère des chaînes.
ccs := make(chan chan string) // Un canal de canaux de chaînes.
go func() { c <- 84 }() // Démarre une nouvelle goroutine, pour
// envoyer une valeur.
go func() { cs <- "wordy" }() // De nouveau, pour cs cette fois-ci.
// Select possède une syntaxe similaire au switch, mais chaque cas requiert
// une opération impliquant un canal. Il sélectionne un cas aléatoirement
// prêt à communiquer.
select {
case i := <-c: // La valeur reçue peut être assignée à une variable,
fmt.Printf("c'est un %T", i)
case <-cs: // ou la valeur reçue peut être ignorée.
fmt.Println("c'est une chaîne")
case <-ccs: // Un canal vide, indisponible à la communication.
fmt.Println("ne surviendra pas.")
}
// À ce point, une valeur a été prise de c ou cs. L'une des deux goroutines
// démarrée plus haut a complétée, la seconde restera bloquée.
learnWebProgramming() // Go permet la programmation Web.
}
// Une seule fonction du paquet http démarre un serveur Web.
func learnWebProgramming() {
// Le premier paramètre de ListenAndServe est une adresse TCP à écouter.
// Le second est une interface, de type http.Handler.
go func() {
err := http.ListenAndServe(":8080", pair{})
fmt.Println(err) // n'ignorez pas les erreurs !
}()
requestServer()
}
// Implémente la méthode ServeHTTP de http.Handler à pair, la rendant compatible
// avec les opérations utilisant l'interface http.Handler.
func (p pair) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// Répondez à une requête à l'aide de la méthode http.ResponseWriter.
w.Write([]byte("Vous avez appris Go en Y minutes!"))
}
func requestServer() {
resp, err := http.Get("http://localhost:8080")
fmt.Println(err)
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
fmt.Printf("\nLe serveur Web a dit: `%s`", string(body))
}
```
## En savoir plus
La référence Go se trouve sur [le site officiel de Go](http://golang.org/).
Vous pourrez y suivre le tutoriel interactif et en apprendre beaucoup plus.
Une lecture de la documentation du langage est grandement conseillée. C'est
facile à lire et très court (comparé aux autres langages).
Vous pouvez exécuter et modifier le code sur [Go playground](https://play.golang.org/p/tnWMjr16Mm). Essayez de le modifier et de l'exécuter à partir de votre navigateur! Prennez en note que vous pouvez utiliser [https://play.golang.org](https://play.golang.org) comme un [REPL](https://en.wikipedia.org/wiki/Read-eval-print_loop) pour tester et coder dans votre navigateur, sans même avoir à installer Go.
Sur la liste de lecteur des étudiants de Go se trouve le [code source de la
librairie standard](http://golang.org/src/pkg/). Bien documentée, elle démontre
le meilleur de la clarté de Go, le style ainsi que ses expressions. Sinon, vous
pouvez cliquer sur le nom d'une fonction dans [la
documentation](http://golang.org/pkg/) et le code source apparaît!
Une autre excellente ressource pour apprendre est [Go par l'exemple](https://gobyexample.com/).

View File

@ -0,0 +1,62 @@
---
language: json
filename: learnjson-fr.json
contributors:
- ["Anna Harren", "https://github.com/iirelu"]
- ["Marco Scannadinari", "https://github.com/marcoms"]
translators:
- ["Alois de Gouvello","https://github.com/aloisdg"]
lang: fr-fr
---
Comme JSON est un format d'échange de données extrêmement simple, ce Apprendre X en Y minutes
est susceptible d'être le plus simple jamais réalisé.
JSON dans son état le plus pur n'a aucun commentaire, mais la majorité des parseurs accepterons
les commentaires du langage C (`//`, `/* */`). Pour les besoins de ce document, cependant,
tout sera du JSON 100% valide. Heureusement, il s'explique par lui-même.
```json
{
"Clé": "valeur",
"Clés": "devront toujours être entourées par des guillemets",
"nombres": 0,
"chaînes de caractères": "Hellø, wørld. Tous les caractères Unicode sont autorisés, accompagné d'un \"caractère d'échappement\".",
"a des booléens ?": true,
"rien": null,
"grand nombre": 1.2e+100,
"objets": {
"commentaire": "La majorité de votre strucutre sera des objets.",
"tableau": [0, 1, 2, 3, "Les tableaux peuvent contenir n'importe quoi.", 5],
"un autre objet": {
"commentaire": "Ces choses peuvent être imbriquées. C'est très utile."
}
},
"bêtises": [
{
"sources de potassium": ["bananes"]
},
[
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, "neo"],
[0, 0, 0, 1]
]
],
"style alternatif": {
"commentaire": "regarde ça !"
, "position de la virgule": "n'a pas d'importance - aussi longtemps qu'elle est avant la valeur, alors elle est valide."
, "un autre commentaire": "comme c'est gentil"
},
"C'était court": "Et, vous avez terminé. Maintenant, vous savez tout ce que JSON a à offrir."
}
```

746
fr-fr/r-fr.html.markdown Normal file
View File

@ -0,0 +1,746 @@
---
language: R
contributors:
- ["e99n09", "http://github.com/e99n09"]
- ["isomorphismes", "http://twitter.com/isomorphisms"]
translators:
- ["Anne-Catherine Dehier", "https://github.com/spellart"]
filename: learnr-fr.r
---
R est un langage de programmation statistique. Il dispose de nombreuses
bibliothèques pour le téléchargement et le nettoyage d'ensembles de données,
l'exécution de procédures statistiques, et la réalisation de graphiques.
On peut également exécuter des commmandes `R` au sein d'un document LaTeX.
```r
# Les commentaires commencent avec des symboles numériques.
# Il n'est pas possible de faire des commentaires multilignes,
# mais on peut placer plusieurs commentaires les uns en dessous
# des autres comme ceci.
# Sur Mac, taper COMMAND-ENTER pour exécuter une ligne
# et sur Windows taper CTRL-ENTER
########################################################################
# Les choses que vous pouvez faire sans rien comprendre
# à la programmation
########################################################################
# Dans cette section, nous vous montrons quelques trucs cools que vous
# pouvez faire avec R sans rien comprendre à la programmation.
# Ne vous inquiétez pas si vous ne comprenez pas tout ce que le code fait.
# Profitez simplement !
data() # parcours les ensembles de données préchargées
data(rivers) # récupère ceci : "Lengths of Major North American Rivers"
ls() # notez que "rivers" apparaît maintenant dans votre espace de travail
head(rivers) # donne un aperçu des données
# 735 320 325 392 524 450
length(rivers) # Combien de rivers ont été mesurées ?
# 141
summary(rivers) # Quelles sont les principales données statistiques ?
# Min. 1st Qu. Median Mean 3rd Qu. Max.
# 135.0 310.0 425.0 591.2 680.0 3710.0
# Fait un diagramme à tiges et à feuilles (visualisation de données de
# types histogramme)
stem(rivers)
# Le point décimal est de 2 chiffres à droite du |
#
# 0 | 4
# 2 | 011223334555566667778888899900001111223333344455555666688888999
# 4 | 111222333445566779001233344567
# 6 | 000112233578012234468
# 8 | 045790018
# 10 | 04507
# 12 | 1471
# 14 | 56
# 16 | 7
# 18 | 9
# 20 |
# 22 | 25
# 24 | 3
# 26 |
# 28 |
# 30 |
# 32 |
# 34 |
# 36 | 1
stem(log(rivers)) # Notez que les données ne sont ni normales
# ni lognormales !
# Prenez-ça, la courbe en cloche
# Le point décimal est à 1 chiffre à gauche du |
#
# 48 | 1
# 50 |
# 52 | 15578
# 54 | 44571222466689
# 56 | 023334677000124455789
# 58 | 00122366666999933445777
# 60 | 122445567800133459
# 62 | 112666799035
# 64 | 00011334581257889
# 66 | 003683579
# 68 | 0019156
# 70 | 079357
# 72 | 89
# 74 | 84
# 76 | 56
# 78 | 4
# 80 |
# 82 | 2
# Fait un histogramme :
hist(rivers, col="#333333", border="white", breaks=25) # amusez-vous avec ces paramètres
hist(log(rivers), col="#333333", border="white", breaks=25) # vous ferez plus de tracés plus tard
# Ici d'autres données qui viennent préchargées. R en a des tonnes.
data(discoveries)
plot(discoveries, col="#333333", lwd=3, xlab="Year",
main="Number of important discoveries per year")
plot(discoveries, col="#333333", lwd=3, type = "h", xlab="Year",
main="Number of important discoveries per year")
# Plutôt que de laisser l'ordre par défaut (par année)
# Nous pourrions aussi trier pour voir ce qu'il y a de typique
sort(discoveries)
# [1] 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2
# [26] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3
# [51] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4
# [76] 4 4 4 4 5 5 5 5 5 5 5 6 6 6 6 6 6 7 7 7 7 8 9 10 12
stem(discoveries, scale=2)
#
# Le point décimale est à la |
#
# 0 | 000000000
# 1 | 000000000000
# 2 | 00000000000000000000000000
# 3 | 00000000000000000000
# 4 | 000000000000
# 5 | 0000000
# 6 | 000000
# 7 | 0000
# 8 | 0
# 9 | 0
# 10 | 0
# 11 |
# 12 | 0
max(discoveries)
# 12
summary(discoveries)
# Min. 1st Qu. Median Mean 3rd Qu. Max.
# 0.0 2.0 3.0 3.1 4.0 12.0
# Lance un dé plusieurs fois
round(runif(7, min=.5, max=6.5))
# 1 4 6 1 4 6 4
# Vos numéros diffèreront des miens à moins que nous mettions
# le même random.seed(31337)
# Dessine à partir d'une normale Gaussienne 9 fois
rnorm(9)
# [1] 0.07528471 1.03499859 1.34809556 -0.82356087 0.61638975 -1.88757271
# [7] -0.59975593 0.57629164 1.08455362
##############################################################
# les types de données et l'arithmétique de base
##############################################################
# Maintenant pour la partie orientée programmation du tutoriel.
# Dans cette section vous rencontrerez les types de données importants de R :
# les entiers, les numériques, les caractères, les logiques, et les facteurs.
# LES ENTIERS
# Les entiers de type long sont écrits avec L
5L # 5
class(5L) # "integer"
# (Essayez ?class pour plus d'informations sur la fonction class().)
# Avec R, chaque valeur seule, comme 5L, est considérée comme
# un vecteur de longueur 1
length(5L) # 1
# On peut avoir un vecteur d'entiers avec une longueur > 1 :
c(4L, 5L, 8L, 3L) # 4 5 8 3
length(c(4L, 5L, 8L, 3L)) # 4
class(c(4L, 5L, 8L, 3L)) # "integer"
# LES NUMÉRIQUES
# Un "numeric" est un nombre à virgule flottante d'une précision double
5 # 5
class(5) # "numeric"
# Encore une fois, tout dans R est un vecteur ;
# Vous pouvez faire un vecteur numérique avec plus d'un élément
c(3,3,3,2,2,1) # 3 3 3 2 2 1
# Vous pouvez aussi utiliser la notation scientifique
5e4 # 50000
6.02e23 # nombre d'Avogadro
1.6e-35 # longueur de Planck
# Vous pouvez également avoir des nombres infiniments grands ou petits
class(Inf) # "numeric"
class(-Inf) # "numeric"
# Vous pouvez utiliser "Inf", par exemple, dans integrate(dnorm, 3, Inf);
# Ça permet d'éviter de réaliser une table de la loi normale.
# ARITHMÉTIQUES DE BASE
# Vous pouvez faire de l'arithmétique avec des nombres
# Faire des opérations arithmétiques en mixant des entiers
# et des numériques
# donne un autre numérique
10L + 66L # 76 # un entier plus un entier donne un entier
53.2 - 4 # 49.2 # un numérique moins un numérique donne un numérique
2.0 * 2L # 4 # un numérique multiplié par un entier donne un numérique
3L / 4 # 0.75 # un entier sur un numérique donne un numérique
3 %% 2 # 1 # le reste de deux numériques est un autre numérique
# Les opérations arithmétiques illégales donnent un "Not A Number" :
0 / 0 # NaN
class(NaN) # "numeric"
# Vous pouvez faire des opérations arithmétiques avec deux vecteurs d'une
# longueur plus grande que 1, à condition que la longueur du plus grand
# vecteur soit un multiple entier du plus petit
c(1,2,3) + c(1,2,3) # 2 4 6
# LES CARACTÈRES
# Il n'y a pas de différences entre les chaînes de caractères et
# les caractères en R
"Horatio" # "Horatio"
class("Horatio") # "character"
class('H') # "character"
# Ceux-ci sont tous les deux des vecteurs de longueur 1
# Ici un plus long :
c('alef', 'bet', 'gimmel', 'dalet', 'he')
# =>
# "alef" "bet" "gimmel" "dalet" "he"
length(c("Call","me","Ishmael")) # 3
# Vous pouvez utiliser des expressions rationnelles sur les vecteurs de caractères :
substr("Fortuna multis dat nimis, nulli satis.", 9, 15) # "multis "
gsub('u', 'ø', "Fortuna multis dat nimis, nulli satis.") # "Fortøna møltis dat nimis, nølli satis."
# R possède plusieurs vecteurs de caractères préconstruits :
letters
# =>
# [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s"
# [20] "t" "u" "v" "w" "x" "y" "z"
month.abb # "Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov" "Dec"
# LES TYPES BOOLÉENS
# En R, un "logical" est un booléen
class(TRUE) # "logical"
class(FALSE) # "logical"
# Leur comportement est normal
TRUE == TRUE # TRUE
TRUE == FALSE # FALSE
FALSE != FALSE # FALSE
FALSE != TRUE # TRUE
# Les données manquantes (NA) sont logiques également
class(NA) # "logical"
# On utilise | et & pour les operations logiques.
# OR
TRUE | FALSE # TRUE
# AND
TRUE & FALSE # FALSE
# Vous pouvez tester si x est TRUE
isTRUE(TRUE) # TRUE
# Ici nous avons un vecteur de type logique avec plusieurs éléments :
c('Z', 'o', 'r', 'r', 'o') == "Zorro" # FALSE FALSE FALSE FALSE FALSE
c('Z', 'o', 'r', 'r', 'o') == "Z" # TRUE FALSE FALSE FALSE FALSE
# LES FACTEURS
# Les facteurs sont généralement utilisés pour y stocker des
# variables qualitatives (catégorielles).
# Les facteurs peuvent être ordonnés (comme le niveau scolaire
# des enfants) ou non ordonnés (comme le sexe)
factor(c("female", "female", "male", NA, "female"))
# female female male <NA> female
# Les niveaux : female male
# Les facteurs possèdent un attribut appelé niveau ("level").
# Les niveaux sont des vecteurs contenant toutes les valeurs
# que peuvent prendre les données catégorielles.
# Notez que les données manquantes n'entrent pas dans le niveau
levels(factor(c("male", "male", "female", NA, "female"))) # "female" "male"
# Si le vecteur de facteurs a une longueur 1, ses niveaux seront
# de longueur 1 également
length(factor("male")) # 1
length(levels(factor("male"))) # 1
# On rencontre communément des facteurs dans des "data frame",
# un type de données que nous couvrirons plus tard
data(infert) # "Infertility after Spontaneous and Induced Abortion"
levels(infert$education) # "0-5yrs" "6-11yrs" "12+ yrs"
# NULL
# "NULL" est bizarre ; on l'utilise pour effacer un vecteur
class(NULL) # NULL
parakeet = c("beak", "feathers", "wings", "eyes")
parakeet
# =>
# [1] "beak" "feathers" "wings" "eyes"
parakeet <- NULL
parakeet
# =>
# NULL
# LES CONVERSIONS DE TYPES
# Les conversions de types servent à forcer une valeur à prendre
# un type différent
as.character(c(6, 8)) # "6" "8"
as.logical(c(1,0,1,1)) # TRUE FALSE TRUE TRUE
# Si vous mettez des éléments de différents types dans un vecteur,
# des coercitions bizarres se produisent :
c(TRUE, 4) # 1 4
c("dog", TRUE, 4) # "dog" "TRUE" "4"
as.numeric("Bilbo")
# =>
# [1] NA
# Message d'avertissement :
# NAs est introduit par coercition
# Notez également : ce n'étaient que des types de données basiques
# Il y a beaucoup d'autres types de données, comme les dates,
# les séries temporelles, etc ...
#######################################
# Variables, boucles , if/else
#######################################
# Une variable est comme une boîte dans laquelle on garde une valeur
# pour l'utiliser plus tard.
# Nous appellons ça "assigner" une valeur à une variable.
# Avoir des variables nous permet d'écrire des boucles, des fonctions, et
# des instructions conditionnelles (if/else)
# LES VARIABLES
# Beaucoup de façons d'assigner des choses :
x = 5 # c'est correct
y <- "1" # c'est préféré
TRUE -> z # ça marche mais c'est bizarre
# LES BOUCLES
# Il y a les boucles for :
for (i in 1:4) {
print(i)
}
# Il y a les boucles while :
a <- 10
while (a > 4) {
cat(a, "...", sep = "")
a <- a - 1
}
# Gardez à l'esprit que les boucles for et while s'exécutent lentement
# en R.
# Des opérations sur la totalité d'un vecteur (ex une ligne entière,
# une colonne entière),
# ou les fonctions de type apply() (nous en parlerons plus tard),
# sont préférées.
# IF/ELSE
# Encore une fois assez standard
if (4 > 3) {
print("4 is greater than 3")
} else {
print("4 is not greater than 3")
}
# =>
# [1] "4 is greater than 3"
# LES FONCTIONS
# se définissent comme ceci :
jiggle <- function(x) {
x = x + rnorm(1, sd=.1) # ajoute un peu de bruit (contrôlé)
return(x)
}
# Appelées comme n'importe quelles autres fonction R :
jiggle(5) # 5±ε. After set.seed(2716057), jiggle(5)==5.005043
##########################################################################
# Les structures de données : les vecteurs, les matrices,
# les data frames et les tableaux
##########################################################################
# À UNE DIMENSION
# Commençons par le tout début, et avec quelque chose que
# vous connaissez déjà : les vecteurs.
vec <- c(8, 9, 10, 11)
vec # 8 9 10 11
# Nous demandons des éléments spécifiques en les mettant entre crochets
# (Notez que R commence à compter à partir de 1)
vec[1] # 8
letters[18] # "r"
LETTERS[13] # "M"
month.name[9] # "September"
c(6, 8, 7, 5, 3, 0, 9)[3] # 7
# Nous pouvons également rechercher des indices de composants spécifiques,
which(vec %% 2 == 0) # 1 3
# Récupèrer seulement les premières ou dernières entrées du vecteur,
head(vec, 1) # 8
tail(vec, 2) # 10 11
# ou vérifier si un certaine valeur est dans le vecteur
any(vec == 10) # TRUE
# Si un index "dépasse" vous obtiendrez NA :
vec[6] # NA
# Vous pouvez trouver la longueur de votre vecteur avec length()
length(vec) # 4
# Vous pouvez réaliser des opérations sur des vecteurs entiers ou des
# sous-ensembles de vecteurs
vec * 4 # 16 20 24 28
vec[2:3] * 5 # 25 30
any(vec[2:3] == 8) # FALSE
# Et R a beaucoup de méthodes statistiques pré-construites pour les vecteurs :
mean(vec) # 9.5
var(vec) # 1.666667
sd(vec) # 1.290994
max(vec) # 11
min(vec) # 8
sum(vec) # 38
# Quelques fonctions préconstruites sympas supplémentaires :
5:15 # 5 6 7 8 9 10 11 12 13 14 15
seq(from=0, to=31337, by=1337)
# =>
# [1] 0 1337 2674 4011 5348 6685 8022 9359 10696 12033 13370 14707
# [13] 16044 17381 18718 20055 21392 22729 24066 25403 26740 28077 29414 30751
# À DEUX DIMENSIONS (TOUT DANS UNE CLASSE)
# Vous pouvez créer une matrice à partir d'entrées du même type comme ceci :
mat <- matrix(nrow = 3, ncol = 2, c(1,2,3,4,5,6))
mat
# =>
# [,1] [,2]
# [1,] 1 4
# [2,] 2 5
# [3,] 3 6
# Différemment du vecteur, la classe d'une matrice est "matrix",
# peut importe ce qu'elle contient
class(mat) # => "matrix"
# Récupérer la première ligne
mat[1,] # 1 4
# Réaliser une opération sur la première colonne
3 * mat[,1] # 3 6 9
# Demander une cellule spécifique
mat[3,2] # 6
# Transposer la matrice entière
t(mat)
# =>
# [,1] [,2] [,3]
# [1,] 1 2 3
# [2,] 4 5 6
# La multiplication de matrices
mat %*% t(mat)
# =>
# [,1] [,2] [,3]
# [1,] 17 22 27
# [2,] 22 29 36
# [3,] 27 36 45
# cbind() colle des vecteurs ensemble en colonne pour faire une matrice
mat2 <- cbind(1:4, c("dog", "cat", "bird", "dog"))
mat2
# =>
# [,1] [,2]
# [1,] "1" "dog"
# [2,] "2" "cat"
# [3,] "3" "bird"
# [4,] "4" "dog"
class(mat2) # matrix
# Encore une fois regardez ce qui se passe !
# Parce que les matrices peuvent contenir des entrées de toutes sortes de
# classes, tout sera converti en classe caractère
c(class(mat2[,1]), class(mat2[,2]))
# rbind() colle des vecteurs ensemble par lignes pour faire une matrice
mat3 <- rbind(c(1,2,4,5), c(6,7,0,4))
mat3
# =>
# [,1] [,2] [,3] [,4]
# [1,] 1 2 4 5
# [2,] 6 7 0 4
# Ah, tout de la même classe. Pas de coercitions. Beaucoup mieux.
# À DEUX DIMENSIONS (DE CLASSES DIFFÉRENTES)
# Pour des colonnes de différents types, utiliser une data frame
# Cette structure de données est si utile pour la programmation statistique,
# qu'une version a été ajoutée à Python dans le paquet "pandas".
students <- data.frame(c("Cedric","Fred","George","Cho","Draco","Ginny"),
c(3,2,2,1,0,-1),
c("H", "G", "G", "R", "S", "G"))
names(students) <- c("name", "year", "house") # name the columns
class(students) # "data.frame"
students
# =>
# name year house
# 1 Cedric 3 H
# 2 Fred 2 G
# 3 George 2 G
# 4 Cho 1 R
# 5 Draco 0 S
# 6 Ginny -1 G
class(students$year) # "numeric"
class(students[,3]) # "factor"
# Trouver les dimensions
nrow(students) # 6
ncol(students) # 3
dim(students) # 6 3
# La fonction data.frame() convertit les vecteurs caractères en vecteurs de
# facteurs par défaut; désactiver cette fonction en règlant
# stringsAsFactors = FALSE quand vous créer la data.frame
?data.frame
# Il y a plusieurs façons de subdiviser les data frames,
# toutes subtilement différentes
students$year # 3 2 2 1 0 -1
students[,2] # 3 2 2 1 0 -1
students[,"year"] # 3 2 2 1 0 -1
# Une version améliorée de la structure data.frame est data.table.
# Si vous travaillez avec des données volumineuses ou des panels, ou avez
# besoin de fusionner quelques ensembles de données, data.table peut être
# un bon choix. Ici un tour éclair :
install.packages("data.table") # télécharge le paquet depuis CRAN
require(data.table) # le charge
students <- as.data.table(students)
students # regardez la différence à l'impression
# =>
# name year house
# 1: Cedric 3 H
# 2: Fred 2 G
# 3: George 2 G
# 4: Cho 1 R
# 5: Draco 0 S
# 6: Ginny -1 G
students[name=="Ginny"] # obtiens les lignes avec name == "Ginny"
# =>
# name year house
# 1: Ginny -1 G
students[year==2] # obtiens les lignes avec year == 2
# =>
# name year house
# 1: Fred 2 G
# 2: George 2 G
# data.table facilite la fusion entre deux ensembles de données
# Faisons une autre data.table pour fusionner students
founders <- data.table(house=c("G","H","R","S"),
founder=c("Godric","Helga","Rowena","Salazar"))
founders
# =>
# house founder
# 1: G Godric
# 2: H Helga
# 3: R Rowena
# 4: S Salazar
setkey(students, house)
setkey(founders, house)
students <- founders[students] # merge les deux ensembles de données qui matchent "house"
setnames(students, c("house","houseFounderName","studentName","year"))
students[,order(c("name","year","house","houseFounderName")), with=F]
# =>
# studentName year house houseFounderName
# 1: Fred 2 G Godric
# 2: George 2 G Godric
# 3: Ginny -1 G Godric
# 4: Cedric 3 H Helga
# 5: Cho 1 R Rowena
# 6: Draco 0 S Salazar
# data.table facilite le résumé des tableaux
students[,sum(year),by=house]
# =>
# house V1
# 1: G 3
# 2: H 3
# 3: R 1
# 4: S 0
# Pour supprimer une colonne d'une data.frame ou data.table,
# assignez-lui la valeur NULL
students$houseFounderName <- NULL
students
# =>
# studentName year house
# 1: Fred 2 G
# 2: George 2 G
# 3: Ginny -1 G
# 4: Cedric 3 H
# 5: Cho 1 R
# 6: Draco 0 S
# Supprimer une ligne en subdivisant
# En utilisant data.table :
students[studentName != "Draco"]
# =>
# house studentName year
# 1: G Fred 2
# 2: G George 2
# 3: G Ginny -1
# 4: H Cedric 3
# 5: R Cho 1
# En utilisant data.frame :
students <- as.data.frame(students)
students[students$house != "G",]
# =>
# house houseFounderName studentName year
# 4 H Helga Cedric 3
# 5 R Rowena Cho 1
# 6 S Salazar Draco 0
# MULTI-DIMENSIONNELLE (TOUS ÉLÉMENTS D'UN TYPE)
# Les arrays créent des tableaux de n dimensions.
# Tous les éléments doivent être du même type.
# Vous pouvez faire un tableau à 2 dimensions (une sorte de matrice)
array(c(c(1,2,4,5),c(8,9,3,6)), dim=c(2,4))
# =>
# [,1] [,2] [,3] [,4]
# [1,] 1 4 8 3
# [2,] 2 5 9 6
# Vous pouvez aussi utiliser array pour faire des matrices à 3 dimensions :
array(c(c(c(2,300,4),c(8,9,0)),c(c(5,60,0),c(66,7,847))), dim=c(3,2,2))
# =>
# , , 1
#
# [,1] [,2]
# [1,] 2 8
# [2,] 300 9
# [3,] 4 0
#
# , , 2
#
# [,1] [,2]
# [1,] 5 66
# [2,] 60 7
# [3,] 0 847
# LES LISTES (MULTI-DIMENSIONNELLES, ÉVENTUELLEMMENT DÉCHIRÉES,
# DE DIFFÉRENTS TYPES)
# Enfin, R a des listes (de vecteurs)
list1 <- list(time = 1:40)
list1$price = c(rnorm(40,.5*list1$time,4)) # random
list1
# Vous pouvez obtenir des éléments de la liste comme ceci
list1$time # une façon
list1[["time"]] # une autre façon
list1[[1]] # encore une façon différente
# =>
# [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
# [34] 34 35 36 37 38 39 40
# Vous pouvez subdiviser les éléments d'une liste comme n'importe quel vecteur
list1$price[4]
# Les listes ne sont pas les structures de données les plus efficaces
# à utiliser avec R ;
# À moins d'avoir une très bonne raison, vous devriez utiliser data.frames
# Les listes sont souvent retournées par des fonctions qui effectuent
# des régressions linéaires.
##########################################
# La famille de fonction apply()
##########################################
# Vous vous rappelez mat ?
mat
# =>
# [,1] [,2]
# [1,] 1 4
# [2,] 2 5
# [3,] 3 6
# Utilisez apply(X, MARGIN, FUN) pour appliquer la fonction FUN à la matrice X
# sur les lignes (MAR = 1) ou les colonnes (MAR = 2)
# R exécute FUN à chaque lignes (ou colonnes) de X, beaucoup plus rapidement
# que le ferait une boucle for ou while
apply(mat, MAR = 2, jiggle)
# =>
# [,1] [,2]
# [1,] 3 15
# [2,] 7 19
# [3,] 11 23
# D'autres fonctions : ?lapply, ?sapply
# Ne soyez pas trop intimidé ; tout le monde reconnaît que c'est un peu déroutant
# Le paquet plyr vise à remplacer (et améliorer !) la famille *apply().
install.packages("plyr")
require(plyr)
?plyr
############################
# Charger des données
############################
# "pets.csv" est un fichier sur internet
# (mais il pourrait être tout aussi facilement sur votre ordinateur)
pets <- read.csv("http://learnxinyminutes.com/docs/pets.csv")
pets
head(pets, 2) # first two rows
tail(pets, 1) # last row
# Pour sauvegarder une data frame ou une matrice en fichier .csv
write.csv(pets, "pets2.csv") # to make a new .csv file
# définir le répertoire de travail avec setwd(), le récupérer avec getwd()
# Essayez ?read.csv et ?write.csv pour plus d'informations
################
# Les tracés
################
# LES FONCTIONS DE TRACÉ PRÉCONSTRUITES
# Les diagrammes de dispersion !
plot(list1$time, list1$price, main = "fake data")
# Les régressions !
linearModel <- lm(price ~ time, data = list1)
linearModel # sort le résultat de la régression
# Tracer une ligne de regression sur une tracé existant
abline(linearModel, col = "red")
# Obtenir une variété de diagnostiques sympas
plot(linearModel)
# Les histogrammes !
hist(rpois(n = 10000, lambda = 5), col = "thistle")
# Les diagrammes en bâtons !
barplot(c(1,4,5,1,2), names.arg = c("red","blue","purple","green","yellow"))
# GGPLOT2
# Mais ceux-ci ne sont même pas les plus jolis tracés de R
# Essayez le paquet ggplot2 pour d'avantages de graphiques
install.packages("ggplot2")
require(ggplot2)
?ggplot2
pp <- ggplot(students, aes(x=house))
pp + geom_histogram()
ll <- as.data.table(list1)
pp <- ggplot(ll, aes(x=time,price))
pp + geom_point()
# ggplot2 a une documentation excellente
#(disponible sur http://docs.ggplot2.org/current/)
```
## Comment obtenir R ?
* Obtiens R et R GUI depuis [http://www.r-project.org/](http://www.r-project.org/)
* [RStudio](http://www.rstudio.com/ide/) est un autre GUI

View File

@ -268,7 +268,7 @@ end
# implicitement la valeur de la dernière instruction évaluée
double(2) #=> 4
# Les paranthèses sont facultative
# Les parenthèses sont facultatives
# lorsqu'il n'y a pas d'ambiguïté sur le résultat
double 3 #=> 6

View File

@ -0,0 +1,174 @@
---
language: TypeScript
contributors:
- ["Philippe Vlérick", "https://github.com/pvlerick"]
translators:
- ["Alois de Gouvello", "https://github.com/aloisdg"]
filename: learntypescript-fr.ts
lang: fr-fr
---
TypeScript est un langage visant à faciliter le développement d'applications larges et scalables, écrites en JavaScript.
TypeScript ajoute des concepts classiques comme les classes, les modules, les interfaces, les génériques et le typage statique (optionnel) à JavaScript.
C'est une surcouche de JavaScript : tout le code JavaScript est valide en TypeScript ce qui permet de l'ajouter de façon transparente à n'importe quel projet. Le code TypeScript est transcompilé en JavaScript par le compilateur.
Cet article se concentrera seulement sur la syntaxe supplémentaire de TypeScript, plutôt que celle de [JavaScript] (../javascript/).
Pour tester le compilateur de TypeScript, rendez-vous au [Playground] (http://www.typescriptlang.org/Playground) où vous pourrez coder, profiter d'une autocomplétion et accéder directement au rendu JavaScript.
```js
// Il y a 3 types basiques en TypeScript
var isDone: boolean = false;
var lines: number = 42;
var name: string = "Anders";
// Si nous ne pouvons pas déterminer le type, on utilise `Any`
var notSure: any = 4;
notSure = "maybe a string instead";
notSure = false; // ok, définitivement un booléen
// Pour les collections, il y a les tableaux typés et les tableaux génériques
var list: number[] = [1, 2, 3]; // Un tableaux typé
var list: Array<number> = [1, 2, 3]; // un tableau générique
// Pour les énumeration
enum Color { Red, Green, Blue };
var c: Color = Color.Green;
// Enfin, `void` est utilisé dans le cas spécifique
// d'une fonction ne retournant rien
function bigHorribleAlert(): void {
alert("Je suis une petite boîte ennuyeuse !");
}
// Les fonctions sont des entités de première classe. Le langage supporte
// les expressions lambda et utilise l'inférence de type
// Les fonctions ci-dessous sont équivalentes, une signature identique
// sera inférée par le compilateur, et le même JavaScript sera généré
var f1 = function(i: number): number { return i * i; }
// Retourne un type inféré
var f2 = function(i: number) { return i * i; }
var f3 = (i: number): number => { return i * i; }
// Retourne un type inféré
var f4 = (i: number) => { return i * i; }
// Retourne un type inféré, ici le mot clé `return` n'est pas nécessaire
var f5 = (i: number) => i * i;
// Les interfaces sont structurées, tout les objets qui ont ces propriétés
// sont compatible avec l'interface
interface Person {
name: string;
// Les propriétés optionnelles sont identifiées avec un "?"
age?: number;
// Et bien sûr, les fonctions
move(): void;
}
// Un objet implémentant l'interface "Person" peut être traité comme
// une Person car il a les propriétés "name" et "move"
var p: Person = { name: "Bobby", move: () => {} };
// Des objets implémentants la propriété optionnelle :
// valide car "age" est un nombre
var validPerson: Person = { name: "Bobby", age: 42, move: () => {} };
// invalide car "age" n'est pas un nombre
var invalidPerson: Person = { name: "Bobby", age: true };
// Les interfaces peuvent aussi décrire un type de fonction
interface SearchFunc {
(source: string, subString: string): boolean;
}
// Seul les types des paramètres sont importants. Les noms ne le sont pas.
var mySearch: SearchFunc;
mySearch = function(src: string, sub: string) {
return src.search(sub) != -1;
}
// Les membres des classes sont publiques par défaut.
class Point {
// Propriétés
x: number;
// Constructeur - Les mots clés "public" et "private" dans ce contexte
// génèrent le code de la propriété et son initialisation dans le
// constructeur. Ici, "y" sera défini de la même façon que "x",
// mais avec moins de code. Les valeurs par défaut sont supportées.
constructor(x: number, public y: number = 0) {
this.x = x;
}
// Fonctions
dist() { return Math.sqrt(this.x * this.x + this.y * this.y); }
// Membres statiques
static origin = new Point(0, 0);
}
var p1 = new Point(10 ,20);
var p2 = new Point(25); // y sera 0
// Héritage
class Point3D extends Point {
constructor(x: number, y: number, public z: number = 0) {
// Un appel explicite au constructeur de la super classe
// est obligatoire.
super(x, y);
}
// Redéfinition
dist() {
var d = super.dist();
return Math.sqrt(d * d + this.z * this.z);
}
}
// Modules, "." peut être utilisé comme un séparateur de sous modules.
module Geometry {
export class Square {
constructor(public sideLength: number = 0) {
}
area() {
return Math.pow(this.sideLength, 2);
}
}
}
var s1 = new Geometry.Square(5);
// Alias local pour référencer un module
import G = Geometry;
var s2 = new G.Square(10);
// Génériques
// Classes
class Tuple<T1, T2> {
constructor(public item1: T1, public item2: T2) {
}
}
// Interfaces
interface Pair<T> {
item1: T;
item2: T;
}
// Et fonctions
var pairToTuple = function<T>(p: Pair<T>) {
return new Tuple(p.item1, p.item2);
};
var tuple = pairToTuple({ item1:"hello", item2:"world"});
// Inclure des références à un fichier :
/// <reference path="jquery.d.ts" />
```
## Lectures complémentaires
* [Site officiel de TypeScript] (http://www.typescriptlang.org/)
* [Spécification du langage TypeScript (pdf)] (http://go.microsoft.com/fwlink/?LinkId=267238)
* [Anders Hejlsberg - Introducing TypeScript on Channel 9] (http://channel9.msdn.com/posts/Anders-Hejlsberg-Introducing-TypeScript)
* [Code source sur GitHub] (https://github.com/Microsoft/TypeScript)
* [Definitely Typed - repository for type definitions] (http://definitelytyped.org/)

View File

@ -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

View File

@ -64,7 +64,11 @@ func beyondHello() {
learnTypes() // < y minutes, learn more!
}
// Functions can have parameters and (multiple!) return values.
/* <- multiline comment
Functions can have parameters and (multiple!) return values.
Here `x`, `y` are the arguments and `sum`, `prod` is the signature (what's returned).
Note that `x` and `sum` receive the type `int`.
*/
func learnMultiple(x, y int) (sum, prod int) {
return x + y, x * y // Return two values.
}
@ -83,7 +87,7 @@ can include line breaks.` // Same string type.
f := 3.14195 // float64, an IEEE-754 64-bit floating point number.
c := 3 + 4i // complex128, represented internally with two float64's.
// Var syntax with an initializers.
// var syntax with initializers.
var u uint = 7 // Unsigned, but implementation dependent size as with int.
var pi float32 = 22. / 7
@ -177,8 +181,14 @@ func learnFlowControl() {
case 1:
case 42:
// Cases don't "fall through".
/*
There is a `fallthrough` keyword however, see:
https://github.com/golang/go/wiki/Switch#fall-through
*/
case 43:
// Unreached.
default:
// Default case is optional.
}
// Like if, for doesn't use parens either.
// Variables declared in for and if are local to their scope.

View File

@ -405,7 +405,7 @@ assert sum(2,5) == 7
## Further resources
[Groovy documentation](http://groovy.codehaus.org/Documentation)
[Groovy documentation](http://www.groovy-lang.org/documentation.html)
[Groovy web console](http://groovyconsole.appspot.com/)

307
hack.html.markdown Normal file
View File

@ -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.

View File

@ -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
@ -193,19 +202,20 @@ foo = (*5) . (+10)
foo 5 -- 75
-- fixing precedence
-- Haskell has another function called `$`. This changes the precedence
-- so that everything to the left of it gets computed first and then applied
-- to everything on the right. You can use `$` (often in combination with `.`)
-- to get rid of a lot of parentheses:
-- Haskell has another operator called `$`. This operator applies a function
-- to a given parameter. In contrast to standard function application, which
-- has highest possible priority of 10 and is left-associative, the `$` operator
-- has priority of 0 and is right-associative. Such a low priority means that
-- the expression on its right is applied as the parameter to the function on its left.
-- before
(even (fib 7)) -- true
(even (fib 7)) -- false
-- after
even . fib $ 7 -- true
even . fib $ 7 -- false
-- equivalently
even $ fib 7 -- true
even $ fib 7 -- false
----------------------------------------------------
-- 5. Type signatures
@ -272,7 +282,7 @@ foldl (\x y -> 2*x + y) 4 [1,2,3] -- 43
foldr (\x y -> 2*x + y) 4 [1,2,3] -- 16
-- This is now the same as
(2 * 3 + (2 * 2 + (2 * 1 + 4)))
(2 * 1 + (2 * 2 + (2 * 3 + 4)))
----------------------------------------------------
-- 7. Data Types
@ -310,13 +320,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 +340,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!"

View File

@ -3,6 +3,7 @@ language: haxe
filename: LearnHaxe3.hx
contributors:
- ["Justin Donaldson", "https://github.com/jdonaldson/"]
- ["Dan Korostelev", "https://github.com/nadako/"]
---
Haxe is a web-oriented language that provides platform support for C++, C#,
@ -34,16 +35,20 @@ references.
/*
This is your first actual haxe code coming up, it's declaring an empty
package. A package isn't necessary, but it's useful if you want to create a
namespace for your code (e.g. org.module.ClassName).
namespace for your code (e.g. org.yourapp.ClassName).
Omitting package declaration is the same as declaring an empty package.
*/
package; // empty package, no namespace.
/*
Packages define modules for your code. Each module (e.g. org.module) must
be lower case, and should exist as a folder structure containing the class.
Class (and type) names must be capitalized. E.g, the class "org.module.Foo"
should have the folder structure org/module/Foo.hx, as accessible from the
compiler's working directory or class path.
Packages are directories that contain modules. Each module is a .hx file
that contains types defined in a package. Package names (e.g. org.yourapp)
must be lower case while module names are capitalized. A module contain one
or more types whose names are also capitalized.
E.g, the class "org.yourapp.Foo" should have the folder structure org/module/Foo.hx,
as accessible from the compiler's working directory or class path.
If you import code from other files, it must be declared before the rest of
the code. Haxe provides a lot of common default classes to get you started:
@ -53,6 +58,12 @@ import haxe.ds.ArraySort;
// you can import many classes/modules at once with "*"
import haxe.ds.*;
// you can import static fields
import Lambda.array;
// you can also use "*" to import all static fields
import Math.*;
/*
You can also import classes in a special way, enabling them to extend the
functionality of other classes like a "mixin". More on 'using' later.
@ -172,7 +183,8 @@ class LearnHaxe3{
Regexes are also supported, but there's not enough space to go into
much detail.
*/
trace((~/foobar/.match('foo')) + " is the value for (~/foobar/.match('foo')))");
var re = ~/foobar/;
trace(re.match('foo') + " is the value for (~/foobar/.match('foo')))");
/*
Arrays are zero-indexed, dynamic, and mutable. Missing values are
@ -311,7 +323,7 @@ class LearnHaxe3{
var l = 0;
do{
trace("do statement always runs at least once");
} while (i > 0);
} while (l > 0);
// for loop
/*
@ -328,7 +340,7 @@ class LearnHaxe3{
// (more on ranges later as well)
var n = ['foo', 'bar', 'baz'];
for (val in 0...n.length){
trace(val + " is the value for val (an index for m)");
trace(val + " is the value for val (an index for n)");
}
@ -363,7 +375,7 @@ class LearnHaxe3{
case "rex" : favorite_thing = "shoe";
case "spot" : favorite_thing = "tennis ball";
default : favorite_thing = "some unknown treat";
// case _ : "some unknown treat"; // same as default
// case _ : favorite_thing = "some unknown treat"; // same as default
}
// The "_" case above is a "wildcard" value
// that will match anything.
@ -383,13 +395,9 @@ class LearnHaxe3{
*/
// if statements
var k = if (true){
10;
} else {
20;
}
var k = if (true) 10 else 20;
trace("K equals ", k); // outputs 10
trace("k equals ", k); // outputs 10
var other_favorite_thing = switch(my_dog_name) {
case "fido" : "teddy";
@ -484,11 +492,13 @@ class LearnHaxe3{
// we can read this variable
trace(foo_instance.public_read + " is the value for foo_instance.public_read");
// but not write it
// foo_instance.public_write = 4; // this will throw an error if uncommented:
// foo_instance.public_read = 4; // this will throw an error if uncommented:
// trace(foo_instance.public_write); // as will this.
trace(foo_instance + " is the value for foo_instance"); // calls the toString method
trace(foo_instance.toString() + " is the value for foo_instance.toString()"); // same thing
// calls the toString method:
trace(foo_instance + " is the value for foo_instance");
// same thing:
trace(foo_instance.toString() + " is the value for foo_instance.toString()");
/*
@ -516,8 +526,8 @@ class LearnHaxe3{
*/
class FooClass extends BarClass implements BarInterface{
public var public_any:Int; // public variables are accessible anywhere
public var public_read (default,null): Int; // use this style to only enable public read
public var public_write (null, default): Int; // or public write
public var public_read (default, null): Int; // enable only public read
public var public_write (null, default): Int; // or only public write
public var property (get, set): Int; // use this style to enable getters/setters
// private variables are not available outside the class.
@ -526,9 +536,10 @@ class FooClass extends BarClass implements BarInterface{
// a public constructor
public function new(arg:Int){
super(); // call the constructor of the parent object, since we extended BarClass
// call the constructor of the parent object, since we extended BarClass:
super();
this.public_any= 0;
this.public_any = 0;
this._private = arg;
}
@ -628,6 +639,7 @@ enum ComplexEnum{
ComplexEnumEnum(c:ComplexEnum);
}
// Note: The enum above can include *other* enums as well, including itself!
// Note: This is what's called *Algebraic data type* in some other languages.
class ComplexEnumTest{
public static function example(){

View File

@ -83,7 +83,7 @@ True ; => True
(greet "bilbo") ;=> "hello bilbo"
; functions can take optional arguments as well as keyword arguments
(defn foolist [arg1 &optional [arg2 2]]
(defn foolists [arg1 &optional [arg2 2]]
[arg1 arg2])
(foolists 3) ;=> [3 2]

275
it-it/bash-it.html.markdown Normal file
View File

@ -0,0 +1,275 @@
---
category: tool
tool: bash
contributors:
- ["Max Yankov", "https://github.com/golergka"]
- ["Darren Lin", "https://github.com/CogBear"]
- ["Alexandre Medeiros", "http://alemedeiros.sdf.org"]
- ["Denis Arh", "https://github.com/darh"]
- ["akirahirose", "https://twitter.com/akirahirose"]
- ["Anton Strömkvist", "http://lutic.org/"]
- ["Rahil Momin", "https://github.com/iamrahil"]
- ["Gregrory Kielian", "https://github.com/gskielian"]
filename: LearnBash.sh
translators:
- ["Robert Margelli", "http://github.com/sinkswim/"]
lang: it-it
---
Bash è il nome della shell di unix, la quale è stata distribuita anche come shell del sistema oprativo GNU e la shell di default su Linux e Mac OS X.
Quasi tutti gli esempi sottostanti possono fare parte di uno shell script o eseguiti direttamente nella shell.
[Per saperne di piu'.](http://www.gnu.org/software/bash/manual/bashref.html)
```bash
#!/bin/bash
# La prima riga dello script è lo shebang il quale dice al sistema come eseguire
# lo script: http://it.wikipedia.org/wiki/Shabang
# Come avrai già immaginato, i commenti iniziano con #. Lo shebang stesso è un commento.
# Semplice esempio ciao mondo:
echo Ciao mondo!
# Ogni comando inizia su una nuova riga, o dopo un punto e virgola:
echo 'Questa è la prima riga'; echo 'Questa è la seconda riga'
# Per dichiarare una variabile:
VARIABILE="Una stringa"
# Ma non così:
VARIABILE = "Una stringa"
# Bash stabilirà che VARIABILE è un comando da eseguire e darà un errore
# perchè non esiste.
# Usare la variabile:
echo $VARIABILE
echo "$VARIABILE"
echo '$VARIABILE'
# Quando usi la variabile stessa - assegnala, esportala, oppure — scrivi
# il suo nome senza $. Se vuoi usare il valore della variabile, devi usare $.
# Nota che ' (singolo apice) non espande le variabili!
# Sostituzione di stringhe nelle variabili
echo ${VARIABILE/Una/A}
# Questo sostituirà la prima occorrenza di "Una" con "La"
# Sottostringa di una variabile
echo ${VARIABILE:0:7}
# Questo ritornerà solamente i primi 7 caratteri
# Valore di default per la variabile
echo ${FOO:-"ValoreDiDefaultSeFOOMancaOÈ Vuoto"}
# Questo funziona per null (FOO=), stringa vuota (FOO=""), zero (FOO=0) ritorna 0
# Variabili builtin:
# Ci sono delle variabili builtin molto utili, come
echo "Valore di ritorno dell'ultimo programma eseguito: $?"
echo "PID dello script: $$"
echo "Numero di argomenti: $#"
echo "Argomenti dello script: $@"
echo "Argomenti dello script separati in variabili distinte: $1 $2..."
# Leggere un valore di input:
echo "Come ti chiami?"
read NOME # Nota che non abbiamo dovuto dichiarare una nuova variabile
echo Ciao, $NOME!
# Classica struttura if:
# usa 'man test' per maggiori informazioni sulle condizionali
if [ $NOME -ne $USER ]
then
echo "Il tuo nome non è lo username"
else
echo "Il tuo nome è lo username"
fi
# C'è anche l'esecuzione condizionale
echo "Sempre eseguito" || echo "Eseguito solo se la prima condizione fallisce"
echo "Sempre eseguito" && echo "Eseguito solo se la prima condizione NON fallisce"
# Per usare && e || con l'if, c'è bisogno di piu' paia di parentesi quadre:
if [ $NOME == "Steve" ] && [ $ETA -eq 15 ]
then
echo "Questo verrà eseguito se $NOME è Steve E $ETA è 15."
fi
if [ $NOME == "Daniya" ] || [ $NOME == "Zach" ]
then
echo "Questo verrà eseguito se $NAME è Daniya O Zach."
fi
# Le espressioni sono nel seguente formato:
echo $(( 10 + 5 ))
# A differenza di altri linguaggi di programmazione, bash è una shell - quindi lavora nel contesto
# della cartella corrente. Puoi elencare i file e le cartelle nella cartella
# corrente con il comando ls:
ls
# Questi comandi hanno opzioni che controllano la loro esecuzione:
ls -l # Elenca tutti i file e le cartelle su una riga separata
# I risultati del comando precedente possono essere passati al comando successivo come input.
# Il comando grep filtra l'input con il pattern passato. Ecco come possiamo elencare i
# file .txt nella cartella corrente:
ls -l | grep "\.txt"
# Puoi redirezionare l'input e l'output del comando (stdin, stdout, e stderr).
# Leggi da stdin finchè ^EOF$ e sovrascrivi hello.py con le righe
# comprese tra "EOF":
cat > hello.py << EOF
#!/usr/bin/env python
from __future__ import print_function
import sys
print("#stdout", file=sys.stdout)
print("#stderr", file=sys.stderr)
for line in sys.stdin:
print(line, file=sys.stdout)
EOF
# Esegui hello.py con diverse redirezioni stdin, stdout, e stderr:
python hello.py < "input.in"
python hello.py > "output.out"
python hello.py 2> "error.err"
python hello.py > "output-and-error.log" 2>&1
python hello.py > /dev/null 2>&1
# Lo output error sovrascriverà il file se esiste,
# se invece vuoi appendere usa ">>":
python hello.py >> "output.out" 2>> "error.err"
# Sovrascrivi output.txt, appendi a error.err, e conta le righe:
info bash 'Basic Shell Features' 'Redirections' > output.out 2>> error.err
wc -l output.out error.err
# Esegui un comando e stampa il suo file descriptor (esempio: /dev/fd/123)
# vedi: man fd
echo <(echo "#ciaomondo")
# Sovrascrivi output.txt con "#helloworld":
cat > output.out <(echo "#helloworld")
echo "#helloworld" > output.out
echo "#helloworld" | cat > output.out
echo "#helloworld" | tee output.out >/dev/null
# Pulisci i file temporanei verbosamente (aggiungi '-i' per la modalità interattiva)
rm -v output.out error.err output-and-error.log
# I comandi possono essere sostituiti con altri comandi usando $( ):
# Il comando seguente mostra il numero di file e cartelle nella
# cartella corrente.
echo "Ci sono $(ls | wc -l) oggetti qui."
# Lo stesso puo' essere usato usando backticks `` ma non possono essere innestati - il modo migliore
# è usando $( ).
echo "Ci sono `ls | wc -l` oggetti qui."
# Bash utilizza uno statemente case che funziona in maniera simile allo switch in Java e C++:
case "$VARIABILE" in
#Lista di pattern per le condizioni che vuoi soddisfare
0) echo "C'è uno zero.";;
1) echo "C'è un uno.";;
*) echo "Non è null.";;
esac
# I cicli for iterano per ogni argomento fornito:
# I contenuti di $VARIABILE sono stampati tre volte.
for VARIABILE in {1..3}
do
echo "$VARIABILE"
done
# O scrivilo con il "ciclo for tradizionale":
for ((a=1; a <= 3; a++))
do
echo $a
done
# Possono essere usati anche per agire su file..
# Questo eseguirà il comando 'cat' su file1 e file2
for VARIABILE in file1 file2
do
cat "$VARIABILE"
done
# ..o dall'output di un comando
# Questo eseguirà cat sull'output di ls.
for OUTPUT in $(ls)
do
cat "$OUTPUT"
done
# while loop:
while [ true ]
do
echo "corpo del loop..."
break
done
# Puoi anche definire funzioni
# Definizione:
function foo ()
{
echo "Gli argomenti funzionano come gli argomenti dello script: $@"
echo "E: $1 $2..."
echo "Questa è una funzione"
return 0
}
# o semplicemente
bar ()
{
echo "Un altro modo per dichiarare funzioni!"
return 0
}
# Per chiamare la funzione
foo "Il mio nome è" $NOME
# Ci sono un sacco di comandi utili che dovresti imparare:
# stampa le ultime 10 righe di file.txt
tail -n 10 file.txt
# stampa le prime 10 righe di file.txt
head -n 10 file.txt
# ordina le righe di file.txt
sort file.txt
# riporta o ometti le righe ripetute, con -d le riporta
uniq -d file.txt
# stampa solamente la prima colonna prima del carattere ','
cut -d ',' -f 1 file.txt
# sostituisce ogni occorrenza di 'okay' con 'great' in file.txt (compatible con le regex)
sed -i 's/okay/great/g' file.txt
# stampa su stdout tutte le righe di file.txt che soddisfano una certa regex
# L'esempio stampa le righe che iniziano con "foo" e che finiscono con "bar"
grep "^foo.*bar$" file.txt
# passa l'opzione "-c" per stampare invece il numero delle righe che soddisfano la regex
grep -c "^foo.*bar$" file.txt
# se vuoi letteralmente cercare la stringa,
# e non la regex, usa fgrep (o grep -F)
fgrep "^foo.*bar$" file.txt
# Leggi la documentazione dei builtin di bash con il builtin 'help' di bash:
help
help help
help for
help return
help source
help .
# Leggi la manpage di bash con man
apropos bash
man 1 bash
man bash
# Leggi la documentazione con info (? per help)
apropos info | grep '^info.*('
man info
info info
info 5 info
# Leggi la documentazione di bash:
info bash
info bash 'Bash Features'
info bash 6
info --apropos bash
```

720
it-it/c++-it.html.markdown Normal file
View File

@ -0,0 +1,720 @@
---
language: c++
filename: learncpp.cpp
contributors:
- ["Steven Basart", "http://github.com/xksteven"]
- ["Matt Kline", "https://github.com/mrkline"]
translators:
- ["Robert Margelli", "http://github.com/sinkswim/"]
lang: it-it
---
Il C++ è un linguaggio di programmazione il quale,
[secondo il suo inventore Bjarne Stroustrup](http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2014/Keynote),
è stato progettato per
- essere un "miglior C"
- supportare l'astrazione dei dati
- supportare la programmazione orientata agli oggetti
- supportare la programmazione generica
Nonostante la sintassi possa risultare più difficile o complessa di linguaggi più recenti,
è usato in maniera vasta poichè viene compilato in istruzioni macchina che possono
essere eseguite direttamente dal processore ed offre un controllo stretto sull'hardware (come il linguaggio C)
ed allo stesso tempo offre caratteristiche ad alto livello come i generici, le eccezioni, e le classi.
Questa combinazione di velocità e funzionalità rende il C++
uno dei più utilizzati linguaggi di programmazione.
```c++
//////////////////
// Confronto con il C
//////////////////
// Il C++ è _quasi_ un superset del C e con esso condivide la sintassi di base per
// la dichiarazione di variabili, tipi primitivi, e funzioni.
// Proprio come nel C, l'inizio del programma è una funzione chiamata
// main con un intero come tipo di ritorno,
// Questo valore serve come stato d'uscita del programma.
// Vedi http://it.wikipedia.org/wiki/Valore_di_uscita per maggiori informazioni.
int main(int argc, char** argv)
{
// Gli argomenti a linea di comando sono passati tramite argc e argv così come
// avviene in C.
// argc indica il numero di argomenti,
// e argv è un array di stringhe in stile-C (char*)
// che rappresenta gli argomenti.
// Il primo argomento è il nome che è stato assegnato al programma.
// argc e argv possono essere omessi se non hai bisogno di argomenti,
// in questa maniera la funzione avrà int main() come firma.
// Lo stato di uscita 0 indica successo.
return 0;
}
// Tuttavia, il C++ varia nei seguenti modi:
// In C++, i caratteri come letterali sono da un byte.
sizeof('c') == 1
// In C, i caratteri come letterali sono della stessa dimensione degli interi.
sizeof('c') == sizeof(10)
// C++ ha prototipizzazione rigida
void func(); // funziona che non accetta argomenti
// In C
void func(); // funzione che può accettare un qualsiasi numero di argomenti
// Usa nullptr invece di NULL in C++
int* ip = nullptr;
// Gli header C standard sono disponibili in C++,
// ma sono prefissati con "c" e non hanno il suffisso ".h".
#include <cstdio>
int main()
{
printf("Ciao, mondo!\n");
return 0;
}
///////////////////////////////
// Overloading per le funzioni
//////////////////////////////
// Il C++ supporta l'overloading per le funzioni
// sia dato che ogni funzione accetta parametri diversi.
void print(char const* myString)
{
printf("Stringa %s\n", myString);
}
void print(int myInt)
{
printf("Il mio int è %d", myInt);
}
int main()
{
print("Ciao"); // Viene chiamata void print(const char*)
print(15); // Viene chiamata void print(int)
}
////////////////////////
// Argomenti di default
///////////////////////
// Puoi fornire argomenti di default per una funzione
// se non sono forniti dal chiamante.
void faiQualcosaConInteri(int a = 1, int b = 4)
{
// fai qualcosa con gli interi qui
}
int main()
{
faiQualcosaConInteri(); // a = 1, b = 4
faiQualcosaConInteri(20); // a = 20, b = 4
faiQualcosaConInteri(20, 5); // a = 20, b = 5
}
// Gli argomenti di default devono essere alla fine della lista degli argomenti.
void dichiarazioneInvalida(int a = 1, int b) // Errore!
{
}
/////////////
// Namespaces
/////////////
// I namespaces forniscono visibilità separata per dichiarazioni di variabili, funzioni,
// ed altro.
// I namespaces possono essere annidati.
namespace Primo {
namespace Annidato {
void foo()
{
printf("Questa è Primo::Annidato::foo\n");
}
} // fine di namespace Annidato
} // fine di namespace Primo
namespace Secondo {
void foo()
{
printf("Questa è Secondo::foo\n")
}
}
void foo()
{
printf("Questa è foo globale\n");
}
int main()
{
// Assume che tutto venga dal namespace "Secondo"
// a meno che non venga dichiarato altrimenti.
using namespace Secondo;
foo(); // stampa "Questa è Secondo::foo"
Primo::Annidato::foo(); // stampa "Questa è Primo::Annidato::foo"
::foo(); // stampa "Questa è foo globale"
}
///////////////
// Input/Output
///////////////
// L'input e l'output in C++ utilizza gli streams
// cin, cout, e cerr i quali rappresentano stdin, stdout, e stderr.
// << è l'operatore di inserzione >> è l'operatore di estrazione.
#include <iostream> // Include gli streams di I/O
using namespace std; // Gli streams sono nel namespace std (libreria standard)
int main()
{
int myInt;
// Stampa su stdout (o terminalee/schermo)
cout << "Inserisci il tuo numero preferito:\n";
// Prende l'input
cin >> myInt;
// cout può anche essere formattato
cout << "Il tuo numero preferito è " << myInt << "\n";
// stampa "Il tuo numero preferito è <myInt>"
cerr << "Usato per messaggi di errore";
}
////////////
// Stringhe
///////////
// Le stringhe in C++ sono oggetti ed hanno molte funzioni membro
#include <string>
using namespace std; // Anche le stringhe sono contenute nel namespace std (libreria standard)
string myString = "Ciao";
string myOtherString = " Mondo";
// + è usato per la concatenazione.
cout << myString + myOtherString; // "Ciao Mondo"
cout << myString + " Bella"; // "Ciao Bella"
// le stringhe in C++ possono essere modificate.
myString.append(" Mario");
cout << myString; // "Ciao Mario"
///////////////
// Riferimenti
//////////////
// Oltre ai puntatori come quelli in C,
// il C++ ha i _riferimenti_.
// Questi non sono tipi puntatori che non possono essere riassegnati una volta settati
// e non possono essere null.
// Inoltre, essi hanno la stessa sintassi della variabile stessa:
// * non è necessario per la dereferenziazione e
// & ("indirizzo di") non è usato per l'assegnamento.
using namespace std;
string foo = "Io sono foo";
string bar = "Io sono bar";
string& fooRef = foo; // Questo crea un riferimento a foo.
fooRef += ". Ciao!"; // Modifica foo attraverso il riferimento
cout << fooRef; // Stampa "Io sono foo. Ciao!"
// Non riassegna "fooRef". Questo è come scrivere "foo = bar", e
// foo == "Io sono bar"
// dopo questa riga.
fooRef = bar;
const string& barRef = bar; // Crea un riferimento const a bar.
// Come in C, i valori const (i puntatori e i riferimenti) non possono essere modificati.
barRef += ". Ciao!"; // Errore, i riferimenti const non possono essere modificati.
//////////////////////////////////////////////////
// Classi e programmazione orientata agli oggetti
/////////////////////////////////////////////////
// Primo esempio delle classi
#include <iostream>
// Dichiara una classe.
// Le classi sono in genere dichiara in un header file (.h o .hpp).
class Cane {
// Variabili e funzioni membro sono private di default.
std::string nome;
int peso;
// Tutti i membri dopo questo sono pubblici (public)
// finchè "private:" o "protected:" non compaiono.
public:
// Costruttore di default
Cane();
// Dichiarazioni di funzioni membro (le implentazioni sono a seguito)
// Nota che stiamo usando std::string invece di porre
// using namespace std;
// sopra.
// Mai usare uno statement "using namespace" in uno header.
void impostaNome(const std::string& nomeCane);
void impostaPeso(int pesoCane);
// Le funzioni che non modificano lo stato dell'oggetto
// dovrebbero essere marcate come const.
// Questo permette di chiamarle con un riferimento const all'oggetto.
// Inoltre, nota che le funzioni devono essere dichiarate espliciamente come _virtual_
// per essere sovrascritte in classi derivate.
// Le funzioni non sono virtual di default per motivi di performance.
virtual void print() const;
// Le funzioni possono essere definite anche all'interno del corpo della classe.
// Le funzioni definite in questo modo sono automaticamente inline.
void abbaia() const { std::cout << nome << " abbaia!\n"; }
// Assieme con i costruttori, il C++ fornisce i distruttori.
// Questi sono chiamati quando un oggetto è rimosso o esce dalla visibilità.
// Questo permette paradigmi potenti come il RAII
// (vedi sotto)
// I distruttori devono essere virtual per permettere a classi di essere derivate da questa.
virtual ~Dog();
}; // Un punto e virgola deve seguire la definizione della funzione
// Le funzioni membro di una classe sono generalmente implementate in files .cpp .
void Cane::Cane()
{
std::cout << "Un cane è stato costruito\n";
}
// Gli oggetti (ad esempio le stringhe) devono essere passati per riferimento
// se li stai modificando o come riferimento const altrimenti.
void Cane::impostaNome(const std::string& nomeCane)
{
nome = nomeCane;
}
void Cane::impostaPeso(int pesoCane)
{
peso = pesoCane;
}
// Notare che "virtual" è solamente necessario nelle dichiarazioni, non nelle definizioni.
void Cane::print() const
{
std::cout << "Il cane è " << nome << " e pesa " << peso << "kg\n";
}
void Cane::~Cane()
{
cout << "Ciao ciao " << nome << "\n";
}
int main() {
Cane myDog; // stampa "Un cane è stato costruito"
myDog.impostaNome("Barkley");
myDog.impostaPeso(10);
myDog.print(); // stampa "Il cane è Barkley e pesa 10 kg"
return 0;
} // stampa "Ciao ciao Barkley"
// Ereditarietà:
// Questa classe eredita tutto ciò che è public e protected dalla classe Cane
class MioCane : public Cane {
void impostaProprietario(const std::string& proprietarioCane)
// Sovrascrivi il comportamento della funzione print per tutti i MioCane. Vedi
// http://it.wikipedia.org/wiki/Polimorfismo_%28informatica%29
// per una introduzione più generale se non sei familiare con
// il polimorfismo.
// La parola chiave override è opzionale ma fa sì che tu stia effettivamente
// sovrascrivendo il metodo nella classe base.
void print() const override;
private:
std::string proprietario;
};
// Nel frattempo, nel file .cpp corrispondente:
void MioCane::impostaProprietario(const std::string& proprietarioCane)
{
proprietario = proprietarioCane;
}
void MioCane::print() const
{
Cane::print(); // Chiama la funzione print nella classe base Cane
std::cout << "Il cane è di " << proprietario << "\n";
// stampa "Il cane è <nome> e pesa <peso>"
// "Il cane è di <proprietario>"
}
///////////////////////////////////////////////////
// Inizializzazione ed Overloading degli Operatori
//////////////////////////////////////////////////
// In C++ puoi sovrascrivere il comportamento di operatori come +, -, *, /, ecc...
// Questo è possibile definendo una funzione che viene chiamata
// ogniqualvolta l'operatore è usato.
#include <iostream>
using namespace std;
class Punto {
public:
// Così si assegna alle variabili membro un valore di default.
double x = 0;
double y = 0;
// Definisce un costruttore di default che non fa nulla
// ma inizializza il Punto ai valori di default (0, 0)
Punto() { };
// La sintassi seguente è nota come lista di inizializzazione
// ed è il modo appropriato di inizializzare i valori membro della classe
Punto (double a, double b) :
x(a),
y(b)
{ /* Non fa nulla eccetto inizializzare i valori */ }
// Sovrascrivi l'operatore +.
Punto operator+(const Punto& rhs) const;
// Sovrascrivi l'operatore +=
Punto& operator+=(const Punto& rhs);
// Avrebbe senso aggiungere gli operatori - e -=,
// ma li saltiamo per rendere la guida più breve.
};
Punto Punto::operator+(const Punto& rhs) const
{
// Crea un nuovo punto come somma di questo e di rhs.
return Punto(x + rhs.x, y + rhs.y);
}
Punto& Punto::operator+=(const Punto& rhs)
{
x += rhs.x;
y += rhs.y;
return *this;
}
int main () {
Punto su (0,1);
Punto destro (1,0);
// Questo chiama l'operatore + di Punto
// Il Punto su chiama la funzione + con destro come argomento
Punto risultato = su + destro;
// Stampa "Risultato è spostato in (1,1)"
cout << "Risultato è spostato (" << risultato.x << ',' << risultato.y << ")\n";
return 0;
}
/////////////////
// Templates
////////////////
// Generalmente i templates in C++ sono utilizzati per programmazione generica, anche se
// sono molto più potenti dei costrutti generici in altri linguaggi. Inoltre,
// supportano specializzazione esplicita e parziale, classi in stile funzionale,
// e sono anche complete per Turing.
// Iniziamo con il tipo di programmazione generica con cui forse sei familiare. Per
// definire una classe o una funzione che prende un parametro di un dato tipo:
template<class T>
class Box {
// In questa classe, T può essere usato come qualsiasi tipo.
void inserisci(const T&) { ... }
};
// Durante la compilazione, il compilatore in effetti genera copie di ogni template
// con i parametri sostituiti, e così la definizione completa della classe deve essere
// presente ad ogni invocazione. Questo è il motivo per cui vedrai le classi template definite
// interamente in header files.
// Per instanziare una classe template sullo stack:
Box<int> intBox;
// e puoi usarla come aspettato:
intBox.inserisci(123);
//Puoi, ovviamente, innestare i templates:
Box<Box<int> > boxOfBox;
boxOfBox.inserisci(intBox);
// Fino al C++11, devi porre uno spazio tra le due '>', altrimenti '>>'
// viene visto come l'operatore di shift destro.
// Qualche volta vedrai
// template<typename T>
// invece. La parole chiavi 'class' e 'typename' sono _generalmente_
// intercambiabili in questo caso. Per una spiegazione completa, vedi
// http://en.wikipedia.org/wiki/Typename
// (si, quella parola chiave ha una sua pagina di Wikipedia propria).
// Similmente, una funzione template:
template<class T>
void abbaiaTreVolte(const T& input)
{
input.abbaia();
input.abbaia();
input.abbaia();
}
// Nota che niente è specificato relativamente al tipo di parametri. Il compilatore
// genererà e poi verificherà il tipo di ogni invocazione del template, così che
// la funzione di cui sopra funzione con ogni tipo 'T' che ha const 'abbaia' come metodo!
Cane fluffy;
fluffy.impostaNome("Fluffy")
abbaiaTreVolte(fluffy); // Stampa "Fluffy abbaia" tre volte.
// I parametri template non devono essere classi:
template<int Y>
void stampaMessaggio() {
cout << "Impara il C++ in " << Y << " minuti!" << endl;
}
// E poi esplicitamente specializzare i template per avere codice più efficiente. Ovviamente,
// la maggior parte delle casistiche reali non sono così triviali.
// Notare che avrai comunque bisogna di dichiarare la funzione (o classe) come un template
// anche se hai esplicitamente specificato tutti i parametri.
template<>
void stampaMessaggio<10>() {
cout << "Impara il C++ più velocemente in soli 10 minuti!" << endl;
}
printMessage<20>(); // Stampa "impara il C++ in 20 minuti!"
printMessage<10>(); // Stampa "Impara il C++ più velocemente in soli 10 minuti!"
////////////////////////////
// Gestione delle eccezioni
///////////////////////////
// La libreria standard fornisce un paio di tipi d'eccezioni
// (vedi http://en.cppreference.com/w/cpp/error/exception)
// ma ogni tipo può essere lanciato come eccezione
#include <exception>
// Tutte le eccezioni lanciate all'interno del blocco _try_ possono essere catturate dai successivi
// handlers _catch_.
try {
// Non allocare eccezioni nello heap usando _new_.
throw std::exception("È avvenuto un problema");
}
// Cattura le eccezioni come riferimenti const se sono oggetti
catch (const std::exception& ex)
{
std::cout << ex.what();
// Cattura ogni eccezioni non catturata dal blocco _catch_ precedente
} catch (...)
{
std::cout << "Catturata un'eccezione sconosciuta";
throw; // Rilancia l'eccezione
}
///////
// RAII
///////
// RAII sta per Resource Allocation Is Initialization.
// Spesso viene considerato come il più potente paradigma in C++.
// È un concetto semplice: un costruttore di un oggetto
// acquisisce le risorse di tale oggetto ed il distruttore le rilascia.
// Per comprendere come questo sia vantaggioso,
// consideriamo una funzione che usa un gestore di file in C:
void faiQualcosaConUnFile(const char* nomefile)
{
// Per cominciare, assumiamo che niente possa fallire.
FILE* fh = fopen(nomefile, "r"); // Apri il file in modalità lettura.
faiQualcosaConIlFile(fh);
faiQualcosAltroConEsso(fh);
fclose(fh); // Chiudi il gestore di file.
}
// Sfortunatamente, le cose vengono complicate dalla gestione degli errori.
// Supponiamo che fopen fallisca, e che faiQualcosaConUnFile e
// faiQualcosAltroConEsso ritornano codici d'errore se falliscono.
// (Le eccezioni sono la maniera preferita per gestire i fallimenti,
// ma alcuni programmatori, specialmente quelli con un passato in C,
// non sono d'accordo con l'utilità delle eccezioni).
// Adesso dobbiamo verificare che ogni chiamata per eventuali fallimenti e chiudere il gestore di file
// se un problema è avvenuto.
bool faiQualcosaConUnFile(const char* nomefile)
{
FILE* fh = fopen(nomefile, "r"); // Apre il file in modalità lettura
if (fh == nullptr) // Il puntatore restituito è null in caso di fallimento.
return false; // Riporta il fallimento al chiamante.
// Assumiamo che ogni funzione ritorni false se ha fallito
if (!faiQualcosaConIlFile(fh)) {
fclose(fh); // Chiude il gestore di file così che non sprechi memoria.
return false; // Propaga l'errore.
}
if (!faiQualcosAltroConEsso(fh)) {
fclose(fh); // Chiude il gestore di file così che non sprechi memoria.
return false; // Propaga l'errore.
}
fclose(fh); // Chiudi il gestore di file così che non sprechi memoria.
return true; // Indica successo
}
// I programmatori C in genere puliscono questa procedura usando goto:
bool faiQualcosaConUnFile(const char* nomefile)
{
FILE* fh = fopen(nomefile, "r");
if (fh == nullptr)
return false;
if (!faiQualcosaConIlFile(fh))
goto fallimento;
if (!faiQualcosAltroConEsso(fh))
goto fallimento;
fclose(fh); // Chiude il file
return true; // Indica successo
fallimento:
fclose(fh);
return false; // Propaga l'errore
}
// Se le funzioni indicano errori usando le eccezioni,
// le cose sono un pò più pulite, ma sono sempre sub-ottimali.
void faiQualcosaConUnFile(const char* nomefile)
{
FILE* fh = fopen(nomefile, "r"); // Apre il file in modalità lettura
if (fh == nullptr)
throw std::exception("Non è stato possibile aprire il file.").
try {
faiQualcosaConIlFile(fh);
faiQualcosAltroConEsso(fh);
}
catch (...) {
fclose(fh); // Fai sì che il file venga chiuso se si ha un errore.
throw; // Poi rilancia l'eccezione.
}
fclose(fh); // Chiudi il file
// Tutto è andato bene
}
// Confronta questo con l'utilizzo della classe C++ file stream (fstream)
// fstream usa i distruttori per chiudere il file.
// Come detto sopra, i distruttori sono automaticamente chiamati
// ogniqualvolta un oggetto esce dalla visibilità.
void faiQualcosaConUnFile(const std::string& nomefile)
{
// ifstream è l'abbreviazione di input file stream
std::ifstream fh(nomefile); // Apre il file
// Fai qualcosa con il file
faiQualcosaConIlFile(fh);
faiQualcosAltroConEsso(fh);
} // Il file viene chiuso automaticamente chiuso qui dal distruttore
// Questo ha vantaggi _enormi_:
// 1. Può succedere di tutto ma
// la risorsa (in questo caso il file handler) verrà ripulito.
// Una volta che scrivi il distruttore correttamente,
// È _impossibile_ scordarsi di chiudere l'handler e sprecare memoria.
// 2. Nota che il codice è molto più pulito.
// Il distruttore gestisce la chiusura del file dietro le scene
// senza che tu debba preoccupartene.
// 3. Il codice è sicuro da eccezioni.
// Una eccezione può essere lanciata in qualunque punto nella funzione e la ripulitura
// avverrà lo stesso.
// Tutto il codice C++ idiomatico usa RAII in maniera vasta su tutte le risorse.
// Esempi aggiuntivi includono
// - Utilizzo della memoria con unique_ptr e shared_ptr
// - I contenitori - la lista della libreria standard,
// vettori (i.e. array auto-aggiustati), mappe hash, e così via
// sono tutti automaticamente distrutti con i loro contenuti quando escono dalla visibilità.
// - I mutex usano lock_guard e unique_lock
///////////////////////
// Roba divertente
//////////////////////
// Aspetti del C++ che potrebbero sbalordire i nuovi arrivati (e anche qualche veterano).
// Questa sezione è, sfortunatamente, selvaggiamente incompleta; il C++ è uno dei linguaggi
// più facili con cui puoi spararti da solo nel piede.
// Puoi sovrascrivere metodi privati!
class Foo {
virtual void bar();
};
class FooSub : public Foo {
virtual void bar(); // sovrascrive Foo::bar!
};
// 0 == false == NULL (la maggior parte delle volte)!
bool* pt = new bool;
*pt = 0; // Setta il valore puntato da 'pt' come falso.
pt = 0; // Setta 'pt' al puntatore null. Entrambe le righe vengono compilate senza warnings.
// nullptr dovrebbe risolvere alcune di quei problemi:
int* pt2 = new int;
*pt2 = nullptr; // Non compila
pt2 = nullptr; // Setta pt2 a null.
// Ma in qualche modo il tipo 'bool' è una eccezione (questo è per rendere compilabile `if (ptr)`.
*pt = nullptr; // Questo compila, anche se '*pt' è un bool!
// '=' != '=' != '='!
// Chiama Foo::Foo(const Foo&) o qualche variante del costruttore di copia.
Foo f2;
Foo f1 = f2;
// Chiama Foo::Foo(const Foo&) o qualche variante, ma solo copie di 'Foo' che fanno parte di
// 'fooSub'. Ogni altro membro di 'fooSub' viene scartato. Questo comportamento
// orribile viene chiamato "object slicing."
FooSub fooSub;
Foo f1 = fooSub;
// Chiama Foo::operator=(Foo&) o una sua variante.
Foo f1;
f1 = f2;
```
Letture consigliate:
Un riferimento aggiornato del linguaggio può essere trovato qui
<http://cppreference.com/w/cpp>
Risorse addizionali possono essere trovate qui <http://cplusplus.com>

View File

@ -0,0 +1,62 @@
---
language: json
contributors:
- ["Anna Harren", "https://github.com/iirelu"]
- ["Marco Scannadinari", "https://github.com/marcoms"]
translators:
- ["Robert Margelli", "http://github.com/sinkswim/"]
lang: it-it
---
Dato che JSON è un formato per lo scambio di dati estremamente semplice, questo sarà con molta probabilità
il più semplice Learn X in Y Minutes.
Nella sua forma più pura JSON non ha commenti, ma molti parser accettano
commenti in stile C (//, /\* \*/). Per lo scopo prefissato, tuttavia, tutto sarà
100% JSON valido. Fortunatamente, si spiega da sè.
```json
{
"chiave": "valore",
"chiavi": "devono sempre essere racchiuse tra doppi apici",
"numeri": 0,
"stringhe": "Ciaø, møndø. Tutti gli unicode sono permessi, assieme con l \"escaping\".",
"ha booleani?": true,
"il nulla": null,
"numero grande": 1.2e+100,
"oggetti": {
"commento": "La maggior parte della tua struttura viene dagli oggetti.",
"array": [0, 1, 2, 3, "Gli array possono contenere qualsiasi cosa.", 5],
"un altro oggetto": {
"commento": "Queste cose possono essere annidate, molto utile."
}
},
"sciocchezze": [
{
"sorgenti di potassio": ["banane"]
},
[
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, "neo"],
[0, 0, 0, 1]
]
],
"stile alternativo": {
"commento": "Guarda quà!"
, "posizione della virgola": "non conta - fintantochè è prima del valore, allora è valida"
, "un altro commento": "che bello"
},
"è stato molto breve": "Ed hai finito. Adesso sai tutto cio che JSON ha da offrire."
}
```

View File

@ -0,0 +1,762 @@
---
language: Julia
contributors:
- ["Leah Hanson", "http://leahhanson.us"]
translators:
- ["Yuichi Motoyama", "https://github.com/yomichi"]
filename: learnjulia-jp.jl
lang: ja-jp
---
Julia は科学技術計算向けに作られた、同図像性を持った(homoiconic) プログラミング言語です。
マクロによる同図像性や第一級関数などの抽象化機能の恩恵を受けつつ、低階層をも扱えますが、
それでいてPython 並に学習しやすく、使いやすい言語となっています。
この文章は、Julia の2013年10月18日現在の開発バージョンを元にしています。
```ruby
# ハッシュ(シャープ)記号から改行までは単一行コメントとなります。
#= 複数行コメントは、
'#=' と '=#' とで囲むことで行えます。
#=
入れ子構造にすることもできます。
=#
=#
####################################################
## 1. 基本的な型と演算子
####################################################
# Julia ではすべて式となります。
# 基本となる数値型がいくつかあります。
3 # => 3 (Int64)
3.2 # => 3.2 (Float64)
2 + 1im # => 2 + 1im (Complex{Int64})
2//3 # => 2//3 (Rational{Int64})
# 一般的な中置演算子が使用可能です。
1 + 1 # => 2
8 - 1 # => 7
10 * 2 # => 20
35 / 5 # => 7.0
5 / 2 # => 2.5 # 整数型同士の割り算の結果は、浮動小数点数型になります
div(5, 2) # => 2 # 整数のまま割り算するには、 div を使います
5 \ 35 # => 7.0
2 ^ 2 # => 4 # べき乗です。排他的論理和ではありません
12 % 10 # => 2
# 丸括弧で演算の優先順位をコントロールできます
(1 + 3) * 2 # => 8
# ビット演算
~2 # => -3 # ビット反転
3 & 5 # => 1 # ビット積
2 | 4 # => 6 # ビット和
2 $ 4 # => 6 # ビット排他的論理和
2 >>> 1 # => 1 # 右論理シフト
2 >> 1 # => 1 # 右算術シフト
2 << 1 # => 4 # 左シフト
# bits 関数を使うことで、数の二進表現を得られます。
bits(12345)
# => "0000000000000000000000000000000000000000000000000011000000111001"
bits(12345.0)
# => "0100000011001000000111001000000000000000000000000000000000000000"
# ブール値が用意されています
true
false
# ブール代数
!true # => false
!false # => true
1 == 1 # => true
2 == 1 # => false
1 != 1 # => false
2 != 1 # => true
1 < 10 # => true
1 > 10 # => false
2 <= 2 # => true
2 >= 2 # => true
# 比較演算子をつなげることもできます
1 < 2 < 3 # => true
2 < 3 < 2 # => false
# 文字列は " で作れます
"This is a string."
# 文字リテラルは ' で作れます
'a'
# 文字列は文字の配列のように添字アクセスできます
"This is a string"[1] # => 'T' # Julia では添字は 1 から始まります
# ただし、UTF8 文字列の場合は添字アクセスではうまくいかないので、
# イテレーションを行ってください(map 関数や for ループなど)
# $ を使うことで、文字列に変数や、任意の式を埋め込めます。
"2 + 2 = $(2 + 2)" # => "2 + 2 = 4"
# 他にも、printf マクロを使うことでも変数を埋め込めます。
@printf "%d is less than %f" 4.5 5.3 # 5 is less than 5.300000
# 出力も簡単です
println("I'm Julia. Nice to meet you!")
####################################################
## 2. 変数と配列、タプル、集合、辞書
####################################################
# 変数の宣言は不要で、いきなり変数に値を代入・束縛できます。
some_var = 5 # => 5
some_var # => 5
# 値に束縛されていない変数を使おうとするとエラーになります。
try
some_other_var # => ERROR: some_other_var not defined
catch e
println(e)
end
# 変数名は数字や記号以外の文字から始めます。
# その後は、数字やアンダースコア(_), 感嘆符(!)も使えます。
SomeOtherVar123! = 6 # => 6
# Unicode 文字も使えます。
☃ = 8 # => 8
# ギリシャ文字などを使うことで数学的な記法が簡単にかけます。
2 * π # => 6.283185307179586
# Julia における命名習慣について:
#
# * 変数名における単語の区切りにはアンダースコアを使っても良いですが、
# 使わないと読みにくくなる、というわけではない限り、
# 推奨はされません。
#
# * 型名は大文字で始め、単語の区切りにはキャメルケースを使います。
#
# * 関数やマクロの名前は小文字で書きます。
# 単語の分かち書きにはアンダースコアをつかわず、直接つなげます。
#
# * 内部で引数を変更する関数は、名前の最後に ! をつけます。
# この手の関数は、しばしば「破壊的な関数」とか「in-place な関数」とか呼ばれます。
# 配列は、1 から始まる整数によって添字付けられる、値の列です。
a = Int64[] # => 0-element Int64 Array
# 一次元配列(列ベクトル)は、角括弧 [] のなかにカンマ , 区切りで値を並べることで作ります。
b = [4, 5, 6] # => 3-element Int64 Array: [4, 5, 6]
b[1] # => 4
b[end] # => 6
# 二次元配列は、空白区切りで作った行を、セミコロンで区切ることで作ります。
matrix = [1 2; 3 4] # => 2x2 Int64 Array: [1 2; 3 4]
# 配列の末尾に値を追加するには push! を、
# 他の配列を結合するには append! を使います。
push!(a,1) # => [1]
push!(a,2) # => [1,2]
push!(a,4) # => [1,2,4]
push!(a,3) # => [1,2,4,3]
append!(a,b) # => [1,2,4,3,4,5,6]
# 配列の末尾から値を削除するには pop! を使います。
pop!(b) # => 6 and b is now [4,5]
# 一旦元に戻しておきましょう。
push!(b,6) # b is now [4,5,6] again.
a[1] # => 1 # Julia では添字は0 ではなく1 から始まること、お忘れなく!
# end は最後の添字を表す速記法です。
# 添字を書く場所ならどこにでも使えます。
a[end] # => 6
# 先頭に対する削除・追加は shift!, unshift! です。
shift!(a) # => 1 and a is now [2,4,3,4,5,6]
unshift!(a,7) # => [7,2,4,3,4,5,6]
# ! で終わる関数名は、その引数を変更するということを示します。
arr = [5,4,6] # => 3-element Int64 Array: [5,4,6]
sort(arr) # => [4,5,6]; arr is still [5,4,6]
sort!(arr) # => [4,5,6]; arr is now [4,5,6]
# 配列の範囲外アクセスをすると BoundsError が発生します。
try
a[0] # => ERROR: BoundsError() in getindex at array.jl:270
a[end+1] # => ERROR: BoundsError() in getindex at array.jl:270
catch e
println(e)
end
# エラーが発生すると、どのファイルのどの行で発生したかが表示されます。
# 標準ライブラリで発生したものでもファイル名と行数が出ます。
# ソースからビルドした場合など、標準ライブラリのソースが手元にある場合は
# base/ ディレクトリから探し出して見てください。
# 配列は範囲オブジェクトから作ることもできます。
a = [1:5] # => 5-element Int64 Array: [1,2,3,4,5]
# 添字として範囲オブジェクトを渡すことで、
# 配列の部分列を得ることもできます。
a[1:3] # => [1, 2, 3]
a[2:end] # => [2, 3, 4, 5]
# 添字を用いて配列から値の削除をしたい場合は、splice! を使います。
arr = [3,4,5]
splice!(arr,2) # => 4 ; arr is now [3,5]
# 配列の結合は append! です。
b = [1,2,3]
append!(a,b) # Now a is [1, 2, 3, 4, 5, 1, 2, 3]
# 配列内に指定した値があるかどうかを調べるのには in を使います。
in(1, a) # => true
# length で配列の長さを取得できます。
length(a) # => 8
# 変更不可能 (immutable) な値の組として、タプルが使えます。
tup = (1, 2, 3) # => (1,2,3) # an (Int64,Int64,Int64) tuple.
tup[1] # => 1
try:
tup[1] = 3 # => ERROR: no method setindex!((Int64,Int64,Int64),Int64,Int64)
catch e
println(e)
end
# 配列に関する関数の多くが、タプルでも使えます。
length(tup) # => 3
tup[1:2] # => (1,2)
in(2, tup) # => true
# タプルから値をばらして(unpack して) 複数の変数に代入できます。
a, b, c = (1, 2, 3) # => (1,2,3) # a is now 1, b is now 2 and c is now 3
# 丸括弧なしでもタプルになります。
d, e, f = 4, 5, 6 # => (4,5,6)
# ひとつの値だけからなるタプルは、その値自体とは区別されます。
(1,) == 1 # => false
(1) == 1 # => true
# 値の交換もタプルを使えば簡単です。
e, d = d, e # => (5,4) # d is now 5 and e is now 4
# 辞書 (Dict) は、値から値への変換の集合です。
empty_dict = Dict() # => Dict{Any,Any}()
# 辞書型リテラルは次のとおりです。
filled_dict = ["one"=> 1, "two"=> 2, "three"=> 3]
# => Dict{ASCIIString,Int64}
# [] を使ったアクセスができます。
filled_dict["one"] # => 1
# すべての鍵(添字)は keys で得られます。
keys(filled_dict)
# => KeyIterator{Dict{ASCIIString,Int64}}(["three"=>3,"one"=>1,"two"=>2])
# 必ずしも辞書に追加した順番には並んでいないことに注意してください。
# 同様に、values はすべての値を返します。
values(filled_dict)
# => ValueIterator{Dict{ASCIIString,Int64}}(["three"=>3,"one"=>1,"two"=>2])
# 鍵と同様に、必ずしも辞書に追加した順番には並んでいないことに注意してください。
# in や haskey を使うことで、要素や鍵が辞書の中にあるかを調べられます。
in(("one", 1), filled_dict) # => true
in(("two", 3), filled_dict) # => false
haskey(filled_dict, "one") # => true
haskey(filled_dict, 1) # => false
# 存在しない鍵を問い合わせると、エラーが発生します。
try
filled_dict["four"] # => ERROR: key not found: four in getindex at dict.jl:489
catch e
println(e)
end
# get 関数を使い、鍵がなかった場合のデフォルト値を与えておくことで、
# このエラーを回避できます。
get(filled_dict,"one",4) # => 1
get(filled_dict,"four",4) # => 4
# 集合 (Set) は一意な値の、順序付けられていない集まりです。
empty_set = Set() # => Set{Any}()
# 集合の初期化
filled_set = Set(1,2,2,3,4) # => Set{Int64}(1,2,3,4)
# 集合への追加
push!(filled_set,5) # => Set{Int64}(5,4,2,3,1)
# in で、値が既に存在するかを調べられます。
in(2, filled_set) # => true
in(10, filled_set) # => false
# 積集合や和集合、差集合を得る関数も用意されています。
other_set = Set(3, 4, 5, 6) # => Set{Int64}(6,4,5,3)
intersect(filled_set, other_set) # => Set{Int64}(3,4,5)
union(filled_set, other_set) # => Set{Int64}(1,2,3,4,5,6)
setdiff(Set(1,2,3,4),Set(2,3,5)) # => Set{Int64}(1,4)
####################################################
## 3. 制御構文
####################################################
# まずは変数を作ります。
some_var = 5
# if 構文です。Julia ではインデントに意味はありません。
if some_var > 10
println("some_var is totally bigger than 10.")
elseif some_var < 10 # elseif 節は省略可能です
println("some_var is smaller than 10.")
else # else 節も省略可能です。
println("some_var is indeed 10.")
end
# => "some var is smaller than 10" と出力されます。
# for ループによって、反復可能なオブジェクトを走査できます。
# 反復可能なオブジェクトの型として、
# Range, Array, Set, Dict, String などがあります。
for animal=["dog", "cat", "mouse"]
println("$animal is a mammal")
# $ を使うことで文字列に変数の値を埋め込めます。
# You can use $ to interpolate variables or expression into strings
end
# prints:
# dog is a mammal
# cat is a mammal
# mouse is a mammal
# for = の代わりに for in を使うこともできます
for animal in ["dog", "cat", "mouse"]
println("$animal is a mammal")
end
# prints:
# dog is a mammal
# cat is a mammal
# mouse is a mammal
# 辞書ではタプルが返ってきます。
for a in ["dog"=>"mammal","cat"=>"mammal","mouse"=>"mammal"]
println("$(a[1]) is a $(a[2])")
end
# prints:
# dog is a mammal
# cat is a mammal
# mouse is a mammal
# タプルのアンパック代入もできます。
for (k,v) in ["dog"=>"mammal","cat"=>"mammal","mouse"=>"mammal"]
println("$k is a $v")
end
# prints:
# dog is a mammal
# cat is a mammal
# mouse is a mammal
# while ループは、条件式がtrue となる限り実行され続けます。
x = 0
while x < 4
println(x)
x += 1 # Shorthand for x = x + 1
end
# prints:
# 0
# 1
# 2
# 3
# 例外は try/catch で捕捉できます。
try
error("help")
catch e
println("caught it $e")
end
# => caught it ErrorException("help")
####################################################
## 4. 関数
####################################################
# function キーワードを次のように使うことで、新しい関数を定義できます。
#function name(arglist)
# body...
#end
function add(x, y)
println("x is $x and y is $y")
# 最後に評価された式の値が、関数全体の返り値となります。
x + y
end
add(5, 6) # => 11 after printing out "x is 5 and y is 6"
# 可変長引数関数も定義できます。
function varargs(args...)
return args
# return キーワードを使うことで、好きな位置で関数から抜けられます。
end
# => varargs (generic function with 1 method)
varargs(1,2,3) # => (1,2,3)
# ... はsplat と呼ばれます
# (訳注:「ピシャッという音(名詞)」「衝撃で平らにする(動詞)」)
# 今回は関数定義で使いましたが、関数呼び出しに使うこともできます。
# その場合、配列やタプルの要素を開いて、複数の引数へと割り当てることとなります。
Set([1,2,3]) # => Set{Array{Int64,1}}([1,2,3]) # 「整数の配列」の集合
Set([1,2,3]...) # => Set{Int64}(1,2,3) # 整数の集合
x = (1,2,3) # => (1,2,3)
Set(x) # => Set{(Int64,Int64,Int64)}((1,2,3)) # タプルの集合
Set(x...) # => Set{Int64}(2,3,1)
# 引数に初期値を与えることで、オプション引数をもった関数を定義できます。
function defaults(a,b,x=5,y=6)
return "$a $b and $x $y"
end
defaults('h','g') # => "h g and 5 6"
defaults('h','g','j') # => "h g and j 6"
defaults('h','g','j','k') # => "h g and j k"
try
defaults('h') # => ERROR: no method defaults(Char,)
defaults() # => ERROR: no methods defaults()
catch e
println(e)
end
# キーワード引数を持った関数も作れます。
function keyword_args(;k1=4,name2="hello") # ; が必要なことに注意
return ["k1"=>k1,"name2"=>name2]
end
keyword_args(name2="ness") # => ["name2"=>"ness","k1"=>4]
keyword_args(k1="mine") # => ["k1"=>"mine","name2"=>"hello"]
keyword_args() # => ["name2"=>"hello","k1"=>4]
# もちろん、これらを組み合わせることもできます。
function all_the_args(normal_arg, optional_positional_arg=2; keyword_arg="foo")
println("normal arg: $normal_arg")
println("optional arg: $optional_positional_arg")
println("keyword arg: $keyword_arg")
end
all_the_args(1, 3, keyword_arg=4)
# prints:
# normal arg: 1
# optional arg: 3
# keyword arg: 4
# Julia では関数は第一級関数として、値として扱われます。
function create_adder(x)
adder = function (y)
return x + y
end
return adder
end
# ラムダ式によって無名関数をつくれます。
(x -> x > 2)(3) # => true
# 先ほどの create_adder と同じもの
function create_adder(x)
y -> x + y
end
# 中の関数に名前をつけても構いません。
function create_adder(x)
function adder(y)
x + y
end
adder
end
add_10 = create_adder(10)
add_10(3) # => 13
# いくつかの高階関数が定義されています。
map(add_10, [1,2,3]) # => [11, 12, 13]
filter(x -> x > 5, [3, 4, 5, 6, 7]) # => [6, 7]
# map の代わりとしてリスト内包表記も使えます。
[add_10(i) for i=[1, 2, 3]] # => [11, 12, 13]
[add_10(i) for i in [1, 2, 3]] # => [11, 12, 13]
####################################################
## 5. 型
####################################################
# Julia ではすべての値にひとつの型がついています。
# 変数に、ではなくて値に、です。
# typeof 関数を使うことで、値が持つ型を取得できます。
typeof(5) # => Int64
# 型自身もまた、第一級の値であり、型を持っています。
typeof(Int64) # => DataType
typeof(DataType) # => DataType
# DataType は型を表現する型であり、DataType 自身もDataType 型の値です。
# 型はドキュメント化や最適化、関数ディスパッチのために使われます。
# 静的な型チェックは行われません。
# 自分で新しい型を定義することもできます。
# 他の言語で言う、構造体やレコードに近いものになっています。
# 型定義には type キーワードを使います。
# type Name
# field::OptionalType
# ...
# end
type Tiger
taillength::Float64
coatcolor # 型注釈を省略した場合、自動的に :: Any として扱われます。
end
# 型を定義すると、その型のプロパティすべてを、定義した順番に
# 引数として持つデフォルトコンストラクタが自動的に作られます。
tigger = Tiger(3.5,"orange") # => Tiger(3.5,"orange")
# 型名がそのままコンストラクタ名(関数名)となります。
sherekhan = typeof(tigger)(5.6,"fire") # => Tiger(5.6,"fire")
# このような、構造体スタイルの型は、具体型(concrete type)と呼ばれます。
# 具体型はインスタンス化可能ですが、派生型(subtype)を持つことができません。
# 具体型の他には抽象型(abstract type)があります。
# abstract Name
abstract Cat # 型の階層図の途中の一点を指し示す名前となります。
# 抽象型はインスタンス化できませんが、派生型を持つことができます。
# 例えば、 Number は以下の派生型を持つ抽象型です。
subtypes(Number) # => 6-element Array{Any,1}:
# Complex{Float16}
# Complex{Float32}
# Complex{Float64}
# Complex{T<:Real}
# ImaginaryUnit
# Real
subtypes(Cat) # => 0-element Array{Any,1}
# すべての型は、直接的にはただひとつの基本型(supertype) を持ちます。
# super 関数でこれを取得可能です。
typeof(5) # => Int64
super(Int64) # => Signed
super(Signed) # => Real
super(Real) # => Number
super(Number) # => Any
super(super(Signed)) # => Number
super(Any) # => Any
# Int64 を除き、これらはすべて抽象型です。
# <: は派生形を表す演算子です
# これを使うことで派生型を定義できます。
type Lion <: Cat # Lion 抽象型 Cat の派生型
mane_color
roar::String
end
# 型名と同じ名前の関数を定義し、既に存在するコンストラクタを呼び出して、
# 必要とする型の値を返すことによって、
# デフォルトコンストラクタ以外のコンストラクタを作ることができます。
Lion(roar::String) = Lion("green",roar)
# 型定義の外側で定義されたコンストラクタなので、外部コンストラクタと呼ばれます。
type Panther <: Cat # Panther Cat の派生型
eye_color
Panther() = new("green")
# Panther は内部コンストラクタとしてこれのみを持ち、
# デフォルトコンストラクタを持たない
end
# 内部コンストラクタを使うことで、どのような値が作られるのかをコントロールすることができます。
# 出来る限り、外部コンストラクタを使うべきです。
####################################################
## 6. 多重ディスパッチ
####################################################
# Julia では、すべての名前付きの関数は総称的関数(generic function) です。
# これは、関数はいくつかの細かいメソッドの集合である、という意味です。
# 例えば先の Lion 型のコンストラクタ Lion は、Lion という関数の1つのメソッドです。
# コンストラクタ以外の例をみるために、新たに meow 関数を作りましょう。
# Lion, Panther, Tiger 型それぞれに対する meow 関数のメソッド定義
function meow(animal::Lion)
animal.roar # 型のプロパティには . でアクセスできます。
end
function meow(animal::Panther)
"grrr"
end
function meow(animal::Tiger)
"rawwwr"
end
# meow 関数の実行
meow(tigger) # => "rawwr"
meow(Lion("brown","ROAAR")) # => "ROAAR"
meow(Panther()) # => "grrr"
# 型の階層関係を見てみましょう
issubtype(Tiger,Cat) # => false
issubtype(Lion,Cat) # => true
issubtype(Panther,Cat) # => true
# 抽象型 Cat の派生型を引数にとる関数
function pet_cat(cat::Cat)
println("The cat says $(meow(cat))")
end
pet_cat(Lion("42")) # => prints "The cat says 42"
try
pet_cat(tigger) # => ERROR: no method pet_cat(Tiger,)
catch e
println(e)
end
# オブジェクト指向言語では、一般的にシングルディスパッチが用いられます。
# つまり、関数に複数あるメソッドのうちにどれが呼ばれるかは、
# その第一引数(もしくは、 . や -> の前にある値の型)によってのみ決定されます。
# 一方でJulia では、すべての引数の型が、このメソッド決定に寄与します。
# 多変数関数を定義して、この辺りを見て行きましょう。
function fight(t::Tiger,c::Cat)
println("The $(t.coatcolor) tiger wins!")
end
# => fight (generic function with 1 method)
fight(tigger,Panther()) # => prints The orange tiger wins!
fight(tigger,Lion("ROAR")) # => prints The orange tiger wins!
# 第二引数の Cat が実際は Lion だった時に、挙動が変わるようにします。
fight(t::Tiger,l::Lion) = println("The $(l.mane_color)-maned lion wins!")
# => fight (generic function with 2 methods)
fight(tigger,Panther()) # => prints The orange tiger wins!
fight(tigger,Lion("ROAR")) # => prints The green-maned lion wins!
# 別に Tiger だけが戦う必要もないですね。
fight(l::Lion,c::Cat) = println("The victorious cat says $(meow(c))")
# => fight (generic function with 3 methods)
fight(Lion("balooga!"),Panther()) # => prints The victorious cat says grrr
try
fight(Panther(),Lion("RAWR")) # => ERROR: no method fight(Panther,Lion)
catch
end
# 第一引数にも Cat を許しましょう。
fight(c::Cat,l::Lion) = println("The cat beats the Lion")
# => Warning: New definition
# fight(Cat,Lion) at none:1
# is ambiguous with
# fight(Lion,Cat) at none:2.
# Make sure
# fight(Lion,Lion)
# is defined first.
#fight (generic function with 4 methods)
# 警告が出ましたが、これは次の対戦で何が起きるのかが不明瞭だからです。
fight(Lion("RAR"),Lion("brown","rarrr")) # => prints The victorious cat says rarrr
# Julia のバージョンによっては、結果が違うかもしれません。
fight(l::Lion,l2::Lion) = println("The lions come to a tie")
fight(Lion("RAR"),Lion("brown","rarrr")) # => prints The lions come to a tie
# Julia が生成する LLVM 内部表現や、アセンブリを調べることもできます。
square_area(l) = l * l # square_area (generic function with 1 method)
square_area(5) #25
# square_area に整数を渡すと何が起きる?
code_native(square_area, (Int32,))
# .section __TEXT,__text,regular,pure_instructions
# Filename: none
# Source line: 1 # Prologue
# push RBP
# mov RBP, RSP
# Source line: 1
# movsxd RAX, EDI # l を取得
# imul RAX, RAX # l*l を計算して RAX に入れる
# pop RBP # Base Pointer を元に戻す
# ret # 終了。RAX の中身が結果
code_native(square_area, (Float32,))
# .section __TEXT,__text,regular,pure_instructions
# Filename: none
# Source line: 1
# push RBP
# mov RBP, RSP
# Source line: 1
# vmulss XMM0, XMM0, XMM0 # 単精度浮動小数点数演算 (AVX)
# pop RBP
# ret
code_native(square_area, (Float64,))
# .section __TEXT,__text,regular,pure_instructions
# Filename: none
# Source line: 1
# push RBP
# mov RBP, RSP
# Source line: 1
# vmulsd XMM0, XMM0, XMM0 # 倍精度浮動小数点数演算 (AVX)
# pop RBP
# ret
#
# Julia では、浮動小数点数と整数との演算では
# 自動的に浮動小数点数用の命令が生成されることに注意してください。
# 円の面積を計算してみましょう。
circle_area(r) = pi * r * r # circle_area (generic function with 1 method)
circle_area(5) # 78.53981633974483
code_native(circle_area, (Int32,))
# .section __TEXT,__text,regular,pure_instructions
# Filename: none
# Source line: 1
# push RBP
# mov RBP, RSP
# Source line: 1
# vcvtsi2sd XMM0, XMM0, EDI # Load integer (r) from memory
# movabs RAX, 4593140240 # Load pi
# vmulsd XMM1, XMM0, QWORD PTR [RAX] # pi * r
# vmulsd XMM0, XMM0, XMM1 # (pi * r) * r
# pop RBP
# ret
#
code_native(circle_area, (Float64,))
# .section __TEXT,__text,regular,pure_instructions
# Filename: none
# Source line: 1
# push RBP
# mov RBP, RSP
# movabs RAX, 4593140496
# Source line: 1
# vmulsd XMM1, XMM0, QWORD PTR [RAX]
# vmulsd XMM0, XMM1, XMM0
# pop RBP
# ret
#
```
## より勉強するために
[公式ドキュメント](http://docs.julialang.org/en/latest/manual/) (英語)にはより詳細な解説が記されています。
Julia に関して助けが必要ならば、[メーリングリスト](https://groups.google.com/forum/#!forum/julia-users) が役に立ちます。
みんな非常に親密に教えてくれます。

View File

@ -1,15 +1,16 @@
---
language: java
contributors:
- ["Jake Prather", "http://github.com/JakeHP"]
- ["Jakukyo Friel", "http://weakish.github.io"]
- ["Madison Dickson", "http://github.com/mix3d"]
- ["Simon Morgan", "http://sjm.io/"]
filename: LearnJava.java
---
Java is a general-purpose, concurrent, class-based, object-oriented computer programming language.
[Read more here.](http://docs.oracle.com/javase/tutorial/java/index.html)
Java is a general-purpose, concurrent, class-based, object-oriented computer
programming language.
[Read more here.](http://docs.oracle.com/javase/tutorial/java/)
```java
// Single-line comments start with //
@ -30,17 +31,17 @@ import java.security.*;
// the file.
public class LearnJava {
// A program must have a main method as an entry point
// A program must have a main method as an entry point.
public static void main (String[] args) {
// Use System.out.println to print lines
// Use System.out.println() to print lines.
System.out.println("Hello World!");
System.out.println(
"Integer: " + 10 +
" Double: " + 3.14 +
" Boolean: " + true);
// To print without a newline, use System.out.print
// To print without a newline, use System.out.print().
System.out.print("Hello ");
System.out.print("World");
@ -49,7 +50,7 @@ public class LearnJava {
// Types & Variables
///////////////////////////////////////
// Declare a variable using <type> <name> [
// Declare a variable using <type> <name>
// Byte - 8-bit signed two's complement integer
// (-128 <= byte <= 127)
byte fooByte = 100;
@ -68,7 +69,7 @@ public class LearnJava {
// L is used to denote that this variable value is of type Long;
// anything without is treated as integer by default.
// Note: Java has no unsigned types
// Note: Java has no unsigned types.
// Float - Single-precision 32-bit IEEE 754 Floating Point
float fooFloat = 234.5f;
@ -85,7 +86,7 @@ public class LearnJava {
// Char - A single 16-bit Unicode character
char fooChar = 'A';
// final variables can't be reassigned to another object
// final variables can't be reassigned to another object.
final int HOURS_I_WORK_PER_WEEK = 9001;
// Strings
@ -100,17 +101,17 @@ public class LearnJava {
System.out.println(bazString);
// 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>];
int [] intArray = new int[10];
String [] stringArray = new String[1];
boolean boolArray [] = new boolean[100];
// 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>];
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
@ -121,17 +122,17 @@ public class LearnJava {
System.out.println("intArray @ 1: " + intArray[1]); // => 1
// Others to check out
// ArrayLists - Like arrays except more functionality is offered,
// and the size is mutable
// ArrayLists - Like arrays except more functionality is offered, and
// the size is mutable.
// LinkedLists - Implementation of doubly-linked list. All of the
// operations perform as could be expected for
// a doubly-linked list.
// Maps - A set of objects that maps keys to values. A map cannot contain
// duplicate keys; each key can map to at most one value.
// HashMaps - This class uses a hashtable to implement the Map interface.
// This allows the execution time of basic operations,
// such as get and insert element, to remain constant even
// for large sets.
// operations perform as could be expected for a
// doubly-linked list.
// Maps - A set of objects that maps keys to values. A map cannot
// contain duplicate keys; each key can map to at most one value.
// HashMaps - This class uses a hashtable to implement the Map
// interface. This allows the execution time of basic
// operations, such as get and insert element, to remain
// constant even for large sets.
///////////////////////////////////////
// Operators
@ -159,13 +160,13 @@ public class LearnJava {
// Bitwise operators!
/*
~ Unary bitwise complement
<< Signed left shift
>> Signed right shift
>>> Unsigned right shift
& Bitwise AND
^ Bitwise exclusive OR
| Bitwise inclusive OR
~ Unary bitwise complement
<< Signed left shift
>> Signed right shift
>>> Unsigned right shift
& Bitwise AND
^ Bitwise exclusive OR
| Bitwise inclusive OR
*/
// Incrementations
@ -174,10 +175,10 @@ public class LearnJava {
// The ++ and -- operators increment and decrement by 1 respectively.
// If they are placed before the variable, they increment then return;
// after the variable they return then increment.
System.out.println(i++); //i = 1, prints 0 (post-increment)
System.out.println(++i); //i = 2, prints 2 (pre-increment)
System.out.println(i--); //i = 1, prints 2 (post-decrement)
System.out.println(--i); //i = 0, prints 0 (pre-decrement)
System.out.println(i++); // i = 1, prints 0 (post-increment)
System.out.println(++i); // i = 2, prints 2 (pre-increment)
System.out.println(i--); // i = 1, prints 2 (post-decrement)
System.out.println(--i); // i = 0, prints 0 (pre-decrement)
///////////////////////////////////////
// Control Structures
@ -196,81 +197,77 @@ public class LearnJava {
// While loop
int fooWhile = 0;
while(fooWhile < 100)
{
//System.out.println(fooWhile);
//Increment the counter
//Iterated 100 times, fooWhile 0,1,2...99
while(fooWhile < 100) {
System.out.println(fooWhile);
// Increment the counter
// Iterated 100 times, fooWhile 0,1,2...99
fooWhile++;
}
System.out.println("fooWhile Value: " + fooWhile);
// Do While Loop
int fooDoWhile = 0;
do
{
//System.out.println(fooDoWhile);
//Increment the counter
//Iterated 99 times, fooDoWhile 0->99
do {
System.out.println(fooDoWhile);
// Increment the counter
// Iterated 99 times, fooDoWhile 0->99
fooDoWhile++;
}while(fooDoWhile < 100);
} while(fooDoWhile < 100);
System.out.println("fooDoWhile Value: " + fooDoWhile);
// For Loop
int fooFor;
//for loop structure => for(<start_statement>; <conditional>; <step>)
for(fooFor=0; fooFor<10; fooFor++){
//System.out.println(fooFor);
//Iterated 10 times, fooFor 0->9
// for loop structure => for(<start_statement>; <conditional>; <step>)
for (fooFor = 0; fooFor < 10; fooFor++) {
System.out.println(fooFor);
// Iterated 10 times, fooFor 0->9
}
System.out.println("fooFor Value: " + fooFor);
// For Each Loop
// An automatic iteration through an array or list of objects.
int[] fooList = {1,2,3,4,5,6,7,8,9};
//for each loop structure => for(<object> : <array_object>)
//reads as: for each object in the array
//note: the object type must match the array.
// The for loop is also able to iterate over arrays as well as objects
// that implement the Iterable interface.
int[] fooList = {1, 2, 3, 4, 5, 6, 7, 8, 9};
// for each loop structure => for (<object> : <iterable>)
// reads as: for each element in the iterable
// note: the object type must match the element type of the iterable.
for( int bar : fooList ){
//System.out.println(bar);
for (int bar : fooList) {
System.out.println(bar);
//Iterates 9 times and prints 1-9 on new lines
}
// Switch Case
// A switch works with the byte, short, char, and int data types.
// It also works with enumerated types (discussed in Enum Types),
// the String class, and a few special classes that wrap
// primitive types: Character, Byte, Short, and Integer.
// It also works with enumerated types (discussed in Enum Types), the
// String class, and a few special classes that wrap primitive types:
// Character, Byte, Short, and Integer.
int month = 3;
String monthString;
switch (month){
case 1:
monthString = "January";
switch (month) {
case 1: monthString = "January";
break;
case 2:
monthString = "February";
case 2: monthString = "February";
break;
case 3:
monthString = "March";
break;
default:
monthString = "Some other month";
case 3: monthString = "March";
break;
default: monthString = "Some other month";
break;
}
System.out.println("Switch Case Result: " + monthString);
// Conditional Shorthand
// You can use the '?' operator for quick assignments or logic forks.
// Reads as "If (statement) is true, use <first value>, otherwise, use <second value>"
// Reads as "If (statement) is true, use <first value>, otherwise, use
// <second value>"
int foo = 5;
String bar = (foo < 10) ? "A" : "B";
System.out.println(bar); // Prints A, because the statement is true
///////////////////////////////////////
// Converting Data Types And Typcasting
///////////////////////////////////////
////////////////////////////////////////
// Converting Data Types And Typecasting
////////////////////////////////////////
// Converting data
@ -286,9 +283,8 @@ public class LearnJava {
// String
// Typecasting
// You can also cast java objects, there's a lot of details and
// deals with some more intermediate concepts.
// Feel free to check it out here:
// You can also cast Java objects, there's a lot of details and deals
// with some more intermediate concepts. Feel free to check it out here:
// http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html
@ -318,9 +314,9 @@ public class LearnJava {
// Class Declaration Syntax:
// <public/private/protected> class <class name>{
// //data fields, constructors, functions all inside.
// //functions are called as methods in Java.
// <public/private/protected> class <class name> {
// // data fields, constructors, functions all inside.
// // functions are called as methods in Java.
// }
class Bicycle {
@ -341,7 +337,8 @@ class Bicycle {
}
// This is a constructor that takes arguments
public Bicycle(int startCadence, int startSpeed, int startGear, String name) {
public Bicycle(int startCadence, int startSpeed, int startGear,
String name) {
this.gear = startGear;
this.cadence = startCadence;
this.speed = startSpeed;
@ -387,10 +384,8 @@ class Bicycle {
//Method to display the attribute values of this Object.
@Override
public String toString() {
return "gear: " + gear +
" cadence: " + cadence +
" speed: " + speed +
" name: " + name;
return "gear: " + gear + " cadence: " + cadence + " speed: " + speed +
" name: " + name;
}
} // end class Bicycle
@ -404,26 +399,26 @@ class PennyFarthing extends Bicycle {
super(startCadence, startSpeed, 0, "PennyFarthing");
}
// You should mark a method you're overriding with an @annotation
// To learn more about what annotations are and their purpose
// check this out: http://docs.oracle.com/javase/tutorial/java/annotations/
// You should mark a method you're overriding with an @annotation.
// To learn more about what annotations are and their purpose check this
// out: http://docs.oracle.com/javase/tutorial/java/annotations/
@Override
public void setGear(int gear) {
gear = 0;
}
}
//Interfaces
//Interface declaration syntax
//<access-level> interface <interface-name> extends <super-interfaces> {
// //Constants
// //Method declarations
//}
// Interfaces
// Interface declaration syntax
// <access-level> interface <interface-name> extends <super-interfaces> {
// // Constants
// // Method declarations
// }
//Example - Food:
// Example - Food:
public interface Edible {
public void eat(); //Any class that implements this interface, must implement this method
public void eat(); // Any class that implements this interface, must
// implement this method.
}
public interface Digestible {
@ -431,29 +426,31 @@ public interface Digestible {
}
//We can now create a class that implements both of these interfaces
// We can now create a class that implements both of these interfaces.
public class Fruit implements Edible, Digestible {
@Override
public void eat() {
//...
// ...
}
@Override
public void digest() {
//...
// ...
}
}
//In java, you can extend only one class, but you can implement many interfaces.
//For example:
public class ExampleClass extends ExampleClassParent implements InterfaceOne, InterfaceTwo {
// In Java, you can extend only one class, but you can implement many
// interfaces. For example:
public class ExampleClass extends ExampleClassParent implements InterfaceOne,
InterfaceTwo {
@Override
public void InterfaceOneMethod() {
}
@Override
public void InterfaceTwoMethod() {
}
}
```
## Further Reading
@ -490,8 +487,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)

View File

@ -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.

View File

@ -10,7 +10,7 @@ As JSON is an extremely simple data-interchange format, this is most likely goin
to be the simplest Learn X in Y Minutes ever.
JSON in its purest form has no actual comments, but most parsers will accept
C-style (//, /\* \*/) comments. For the purposes of this, however, everything is
C-style (`//`, `/* */`) comments. For the purposes of this, however, everything is
going to be 100% valid JSON. Luckily, it kind of speaks for itself.
```json

View File

@ -8,7 +8,7 @@ filename: learnjulia.jl
Julia is a new homoiconic functional language focused on technical computing.
While having the full power of homoiconic macros, first-class functions, and low-level control, Julia is as easy to learn and use as Python.
This is based on the current development version of Julia, as of October 18th, 2013.
This is based on Julia 0.3.
```ruby
@ -91,7 +91,7 @@ false
# $ can be used for string interpolation:
"2 + 2 = $(2 + 2)" # => "2 + 2 = 4"
# You can put any Julia expression inside the parenthesis.
# You can put any Julia expression inside the parentheses.
# Another way to format strings is the printf macro.
@printf "%d is less than %f" 4.5 5.3 # 5 is less than 5.300000
@ -190,7 +190,7 @@ end
# inside the julia folder to find these files.
# You can initialize arrays from ranges
a = [1:5] # => 5-element Int64 Array: [1,2,3,4,5]
a = [1:5;] # => 5-element Int64 Array: [1,2,3,4,5]
# You can look at ranges with slice syntax.
a[1:3] # => [1, 2, 3]
@ -264,7 +264,7 @@ in(("two", 3), filled_dict) # => false
haskey(filled_dict, "one") # => true
haskey(filled_dict, 1) # => false
# Trying to look up a non-existant key will raise an error
# Trying to look up a non-existent key will raise an error
try
filled_dict["four"] # => ERROR: key not found: four in getindex at dict.jl:489
catch e

View File

@ -219,8 +219,8 @@ identity 1 # => 1
# Operators are not functions in LiveScript, but you can easily turn
# them into one! Enter the operator sectioning:
divide-by-2 = (/ 2)
[2, 4, 8, 16].map(divide-by-2) .reduce (+)
divide-by-two = (/ 2)
[2, 4, 8, 16].map(divide-by-two) .reduce (+)
# Not only of function application lives LiveScript, as in any good
@ -248,8 +248,8 @@ reduce = (f, xs, initial) --> xs.reduce f, initial
# The underscore is also used in regular partial application, which you
# can use for any function:
div = (left, right) -> left / right
div-by-2 = div _, 2
div-by-2 4 # => 2
div-by-two = div _, 2
div-by-two 4 # => 2
# Last, but not least, LiveScript has back-calls, which might help

View File

@ -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
#
@ -147,7 +155,7 @@ var anotherArray = ["Default index", "starts at", "0"]
# More data structures are available, including tables, sets, lists, queues,
# and crit bit trees.
# http://nimrod-lang.org/lib.html#collections-and-algorithms
# http://nim-lang.org/docs/lib.html#collections-and-algorithms
#
# IO and Control Flow
@ -166,7 +174,7 @@ else:
# `while`, `if`, `continue`, `break`
import strutils as str # http://nimrod-lang.org/strutils.html
import strutils as str # http://nim-lang.org/docs/strutils.html
echo "I'm thinking of a number between 41 and 43. Guess which!"
let number: int = 42
var
@ -255,11 +263,11 @@ performance, and compile-time features.
## Further Reading
* [Home Page](http://nimrod-lang.org)
* [Download](http://nimrod-lang.org/download.html)
* [Community](http://nimrod-lang.org/community.html)
* [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)
* [Rosetta Code](http://rosettacode.org/wiki/Category:Nimrod)
* [Home Page](http://nim-lang.org)
* [Download](http://nim-lang.org/download.html)
* [Community](http://nim-lang.org/community.html)
* [FAQ](http://nim-lang.org/question.html)
* [Documentation](http://nim-lang.org/documentation.html)
* [Manual](http://nim-lang.org/docs/manual.html)
* [Standard Library](http://nim-lang.org/docs/lib.html)
* [Rosetta Code](http://rosettacode.org/wiki/Category:Nim)

View File

@ -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."

View File

@ -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 ***)

View File

@ -47,9 +47,9 @@ my %fruit_color = ("apple", "red", "banana", "yellow");
# You can use whitespace and the "=>" operator to lay them out more nicely:
my %fruit_color = (
apple => "red",
banana => "yellow",
);
apple => "red",
banana => "yellow",
);
# Scalars, arrays and hashes are documented more fully in perldata.
# (perldoc perldata).
@ -60,17 +60,17 @@ my %fruit_color = (
# Perl has most of the usual conditional and looping constructs.
if ( $var ) {
...
} elsif ( $var eq 'bar' ) {
...
if ($var) {
...
} elsif ($var eq 'bar') {
...
} else {
...
...
}
unless ( condition ) {
...
}
unless (condition) {
...
}
# This is provided as a more readable version of "if (!condition)"
# the Perlish post-condition way
@ -78,19 +78,29 @@ print "Yow!" if $zippy;
print "We have no bananas" unless $bananas;
# while
while ( condition ) {
...
}
while (condition) {
...
}
# for and foreach
for ($i = 0; $i <= $max; $i++) {
...
}
# for loops and iteration
for (my $i = 0; $i < $max; $i++) {
print "index is $i";
}
foreach (@array) {
print "This element is $_\n";
}
for (my $i = 0; $i < @elements; $i++) {
print "Current element is " . $elements[$i];
}
for my $element (@elements) {
print $element;
}
# implicitly
for (@elements) {
print;
}
#### Regular expressions
@ -129,9 +139,11 @@ my @lines = <$in>;
# Writing subroutines is easy:
sub logger {
my $logmessage = shift;
open my $logfile, ">>", "my.log" or die "Could not open my.log: $!";
print $logfile $logmessage;
my $logmessage = shift;
open my $logfile, ">>", "my.log" or die "Could not open my.log: $!";
print $logfile $logmessage;
}
# Now we can use the subroutine just as any other built-in function:

View File

@ -10,8 +10,7 @@ contributors:
Perl 6 is a highly capable, feature-rich programming language made for the
upcoming hundred years.
Perl 6 runs on [the Parrot VM](http://parrot.org/), the JVM
and [the MoarVM](http://moarvm.com).
Perl 6 runs on [the MoarVM](http://moarvm.com) and the JVM.
Meta-note : the triple pound signs are here to denote headlines,
double paragraphs, and single notes.
@ -35,7 +34,8 @@ my $variable;
## * Scalars. They represent a single value. They start with a `$`
my $str = 'String';
my $str2 = "String"; # double quotes allow for interpolation
# double quotes allow for interpolation (which we'll see later):
my $str2 = "String";
# variable names can contain but not end with simple quotes and dashes,
# and can contain (and end with) underscores :
@ -66,23 +66,13 @@ my @keys = 0, 2;
@array[@keys] = @letters; # Assign using an array
say @array; #=> a 6 b
# There are two more kinds of lists: Parcel and Arrays.
# Parcels are immutable lists (you can't modify a list that's not assigned).
# This is a parcel:
(1, 2, 3); # Not assigned to anything. Changing an element would provoke an error
# This is a list:
my @a = (1, 2, 3); # Assigned to `@a`. Changing elements is okay!
# Lists flatten (in list context). You'll see below how to apply item context
# or use arrays to have real nested lists.
## * Hashes. Key-Value Pairs.
# Hashes are actually arrays of Pairs (`Key => Value`),
# except they get "flattened", removing duplicated keys.
## * Hashes, or key-value Pairs.
# Hashes are actually arrays of Pairs
# (you can construct a Pair object using the syntax `Key => Value`),
# except they get "flattened" (hash context), removing duplicated keys.
my %hash = 1 => 2,
3 => 4;
my %hash = autoquoted => "key", # keys *can* get auto-quoted
my %hash = autoquoted => "key", # keys get auto-quoted
"some other" => "value", # trailing commas are okay
;
my %hash = <key1 value1 key2 value2>; # you can also create a hash
@ -112,6 +102,62 @@ sub say-hello-to(Str $name) { # You can provide the type of an argument
say "Hello, $name !";
}
## It can also have optional arguments:
sub with-optional($arg?) { # the "?" marks the argument optional
say "I might return `(Any)` if I don't have an argument passed,
or I'll return my argument";
$arg;
}
with-optional; # returns Any
with-optional(); # returns Any
with-optional(1); # returns 1
## You can also give them a default value when they're not passed:
sub hello-to($name = "World") {
say "Hello, $name !";
}
hello-to; #=> Hello, World !
hello-to(); #=> Hello, World !
hello-to('You'); #=> Hello, You !
## You can also, by using a syntax akin to the one of hashes (yay unified syntax !),
## pass *named* arguments to a `sub`.
# They're optional, and will default to "Any" (Perl's "null"-like value).
sub with-named($normal-arg, :$named) {
say $normal-arg + $named;
}
with-named(1, named => 6); #=> 7
# There's one gotcha to be aware of, here:
# If you quote your key, Perl 6 won't be able to see it at compile time,
# and you'll have a single Pair object as a positional paramater,
# which means this fails:
with-named(1, 'named' => 6);
with-named(2, :named(5)); #=> 7
# To make a named argument mandatory, you can use `?`'s inverse, `!`
sub with-mandatory-named(:$str!) {
say "$str !";
}
with-mandatory-named(str => "My String"); #=> My String !
with-mandatory-named; # run time error: "Required named parameter not passed"
with-mandatory-named(3); # run time error: "Too many positional parameters passed"
## If a sub takes a named boolean argument ...
sub takes-a-bool($name, :$bool) {
say "$name takes $bool";
}
# ... you can use the same "short boolean" hash syntax:
takes-a-bool('config', :bool); # config takes True
takes-a-bool('config', :!bool); # config takes False
## You can also provide your named arguments with defaults:
sub named-def(:$def = 5) {
say $def;
}
named-def; #=> 5
named-def(def => 15); #=> 15
# Since you can omit parenthesis to call a function with no arguments,
# you need "&" in the name to capture `say-hello`.
my &s = &say-hello;
@ -136,74 +182,6 @@ sub concat3($a, $b, $c) {
concat3(|@array); #=> a, b, c
# `@array` got "flattened" as a part of the argument list
## It can also have optional arguments:
sub with-optional($arg?) { # the "?" marks the argument optional
say "I might return `(Any)` if I don't have an argument passed,
or I'll return my argument";
$arg;
}
with-optional; # returns Any
with-optional(); # returns Any
with-optional(1); # returns 1
## You can also give them a default value when they're not passed:
sub hello-to($name = "World") {
say "Hello, $name !";
}
hello-to; #=> Hello, World !
hello-to(); #=> Hello, World !
hello-to('You'); #=> Hello, You !
## You can also, by using a syntax akin to the one of hashes (yay unification !),
## pass *named* arguments to a `sub`.
sub with-named($normal-arg, :$named) {
say $normal-arg + $named;
}
with-named(1, named => 6); #=> 7
# There's one gotcha to be aware of, here:
# If you quote your key, Perl 6 won't be able to see it at compile time,
# and you'll have a single Pair object as a positional paramater.
with-named(2, :named(5)); #=> 7
with-named(3, :4named); #=> 7
# (special colon pair syntax for numbers,
# to be used with s// and such, see later)
with-named(3); # warns, because we tried to use the undefined $named in a `+`:
# by default, named arguments are *optional*
# To make a named argument mandatory, you can use `?`'s inverse, `!`
sub with-mandatory-named(:$str!) {
say "$str !";
}
with-mandatory-named(str => "My String"); #=> My String !
with-mandatory-named; # run time error: "Required named parameter not passed"
with-mandatory-named(3); # run time error: "Too many positional parameters passed"
## If a sub takes a named boolean argument ...
sub takes-a-bool($name, :$bool) {
say "$name takes $bool";
}
# ... you can use the same "short boolean" hash syntax:
takes-a-bool('config', :bool); # config takes True
takes-a-bool('config', :!bool); # config takes False
# or you can use the "adverb" form:
takes-a-bool('config'):bool; #=> config takes True
takes-a-bool('config'):!bool; #=> config takes False
# You'll learn to love (or maybe hate, eh) that syntax later.
## You can also provide your named arguments with defaults:
sub named-def(:$def = 5) {
say $def;
}
named-def; #=> 5
named-def(:10def); #=> 10
named-def(def => 15); #=> 15
# -- Note: we're going to learn *more* on subs really soon,
# but we need to grasp a few more things to understand their real power. Ready?
### Containers
# In Perl 6, values are actually stored in "containers".
# The assignment operator asks the container on the left to store the value on
@ -220,23 +198,19 @@ sub mutate($n is rw) {
# A sub itself returns a container, which means it can be marked as rw:
my $x = 42;
sub mod() is rw { $x }
mod() = 52; # in this case, the parentheses are mandatory
# (else Perl 6 thinks `mod` is a "term")
sub x-store() is rw { $x }
x-store() = 52; # in this case, the parentheses are mandatory
# (else Perl 6 thinks `x-store` is an identifier)
say $x; #=> 52
### Control Flow Structures
# You don't need to put parenthesis around the condition,
# but that also means you always have to use brackets (`{ }`) for their body:
## Conditionals
# - `if`
# Before talking about `if`, we need to know which values are "Truthy"
# (represent True), and which are "Falsey" (or "Falsy") -- represent False.
# Only these values are Falsey: (), 0, "0", Nil, A type (like `Str` or `Int`),
# Only these values are Falsey: (), 0, "", Nil, A type (like `Str` or `Int`),
# and of course False itself.
# Every other value is Truthy.
if True {
@ -247,30 +221,40 @@ unless False {
say "It's not false !";
}
# As you can see, you don't need parentheses around conditions.
# However, you do need the brackets around the "body" block:
# if (true) say; # This doesn't work !
# You can also use their postfix versions, with the keyword after:
say "Quite truthy" if True;
# if (true) say; # This doesn't work !
# - Ternary conditional, "?? !!" (like `x ? y : z` in some other languages)
my $a = $condition ?? $value-if-true !! $value-if-false;
# - `given`-`when` looks like other languages `switch`, but much more
# powerful thanks to smart matching and thanks to Perl 6's "topic variable", $_.
#
# This variable contains the default argument of a block,
# a loop's current iteration (unless explicitly named), etc.
#
# `given` simply puts its argument into `$_` (like a block would do),
# and `when` compares it using the "smart matching" (`~~`) operator.
#
# Since other Perl 6 constructs use this variable (as said before, like `for`,
# blocks, etc), this means the powerful `when` is not only applicable along with
# a `given`, but instead anywhere a `$_` exists.
given "foo bar" {
when /foo/ { # Don't worry about smart matching -- just know `when` uses it.
say $_; #=> foo bar
when /foo/ { # Don't worry about smart matching yet just know `when` uses it.
# This is equivalent to `if $_ ~~ /foo/`.
say "Yay !";
}
when $_.chars > 50 { # smart matching anything with True (`$a ~~ True`) is True,
# so you can also put "normal" conditionals.
# This when is equivalent to this `if`:
# if $_ ~~ ($_.chars > 50) {...}
# Which means:
# if $_.chars > 50 {...}
say "Quite a long string !";
}
default { # same as `when *` (using the Whatever Star)
@ -281,7 +265,7 @@ given "foo bar" {
## Looping constructs
# - `loop` is an infinite loop if you don't pass it arguments,
# but can also be a c-style `for`:
# but can also be a C-style `for` loop:
loop {
say "This is an infinite loop !";
last; # last breaks out of the loop, like the `break` keyword in other languages
@ -296,11 +280,11 @@ loop (my $i = 0; $i < 5; $i++) {
# - `for` - Passes through an array
for @array -> $variable {
say "I've found $variable !";
say "I've got $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 $_";
@ -316,45 +300,15 @@ for @array {
last if $_ == 5; # Or break out of a loop (like `break` in C-like languages).
}
# Note - the "lambda" `->` syntax isn't reserved to `for`:
# The "pointy block" syntax isn't specific to for.
# It's just a way to express a block in Perl6.
if long-computation() -> $result {
say "The result is $result";
}
## Loops can also have a label, and be jumped to through these.
OUTER: while 1 {
say "hey";
while 1 {
OUTER.last; # All the control keywords must be called on the label itself
}
}
# Now that you've seen how to traverse a list, you need to be aware of something:
# List context (@) flattens. If you traverse nested lists, you'll actually be traversing a
# shallow list (except if some sub-list were put in item context ($)).
for 1, 2, (3, (4, ((5)))) {
say "Got $_.";
} #=> Got 1. Got 2. Got 3. Got 4. Got 5.
# ... However: (forcing item context with `$`)
for 1, 2, $(3, 4) {
say "Got $_.";
} #=> Got 1. Got 2. Got 3 4.
# Note that the last one actually joined 3 and 4.
# While `$(...)` will apply item to context to just about anything, you can also create
# an array using `[]`:
for [1, 2, 3, 4] {
say "Got $_.";
} #=> Got 1 2 3 4.
# The other difference between `$()` and `[]` is that `[]` always returns a mutable Array
# whereas `$()` will return a Parcel when given a Parcel.
### Operators
## Since Perl languages are very much operator-based languages
## Since Perl languages are very much operator-based languages,
## Perl 6 operators are actually just funny-looking subroutines, in syntactic
## categories, like infix:<+> (addition) or prefix:<!> (bool not).
@ -394,9 +348,6 @@ $arg ~~ &bool-returning-function; # `True` if the function, passed `$arg`
1 ~~ True; # smart-matching against a boolean always returns that boolean
# (and will warn).
# - `===` is value identity and uses `.WHICH` on the objects to compare them
# - `=:=` is container identity and uses `VAR()` on the objects to compare them
# You also, of course, have `<`, `<=`, `>`, `>=`.
# Their string equivalent are also avaiable : `lt`, `le`, `gt`, `ge`.
3 > 4;
@ -416,17 +367,21 @@ say @array[^10]; # you can pass arrays as subscripts and it'll return
# "1 2 3 4 5 6 7 8 9 10" (and not run out of memory !)
# Note : when reading an infinite list, Perl 6 will "reify" the elements
# it needs, then keep them in memory. They won't be calculated more than once.
# Warning, though: if you try this example in the REPL and just put `1..*`,
# Perl 6 will be forced to try and evaluate the whole array (to print it),
# so you'll end with an infinite loop.
# It also will never calculate more elements that are needed.
# You can use that in most places you'd expect, even assigning to an array
my @numbers = ^20;
@numbers[5..*] = 3, 9 ... * > 90; # The right hand side could be infinite as well.
# (but not both, as this would be an infinite loop)
say @numbers; #=> 3 9 15 21 27 [...] 81 87
# An array subscript can also be a closure.
# It'll be called with the length as the argument
say join(' ', @array[15..*]); #=> 15 16 17 18 19
# which is equivalent to:
say join(' ', @array[-> $n { 15..$n }]);
# You can use that in most places you'd expect, even assigning to an array
my @numbers = ^20;
my @seq = 3, 9 ... * > 95; # 3 9 15 21 27 [...] 81 87 93 99
@numbers[5..*] = 3, 9 ... *; # even though the sequence is infinite,
# only the 15 needed values will be calculated.
say @numbers; #=> 0 1 2 3 4 3 9 15 21 [...] 81 87
# (only 20 values)
## * And, Or
3 && 4; # 4, which is Truthy. Calls `.Bool` on `4` and gets `True`.
@ -438,7 +393,7 @@ $a && $b && $c; # Returns the first argument that evaluates to False,
$a || $b;
# And because you're going to want them,
# you also have composed assignment operators:
# you also have compound assignment operators:
$a *= 2; # multiply and assignment
$b %%= 5; # divisible by and assignment
@array .= sort; # calls the `sort` method and assigns the result back
@ -448,7 +403,7 @@ $b %%= 5; # divisible by and assignment
# a few more key concepts that make them better than in any other language :-).
## Unpacking !
# It's the ability to "extract" arrays and keys.
# It's the ability to "extract" arrays and keys (AKA "destructuring").
# It'll work in `my`s and in parameter lists.
my ($a, $b) = 1, 2;
say $a; #=> 1
@ -559,6 +514,21 @@ map(sub ($a, $b) { $a + $b + 3 }, @array); # (here with `sub`)
# Note : those are sorted lexicographically.
# `{ $^b / $^a }` is like `-> $a, $b { $b / $a }`
## About types...
# Perl6 is gradually typed. This means you can specify the type
# of your variables/arguments/return types, or you can omit them
# and they'll default to "Any".
# You obviously get access to a few base types, like Int and Str.
# The constructs for declaring types are "class", "role",
# which you'll see later.
# For now, let us examinate "subset":
# a "subset" is a "sub-type" with additional checks.
# For example: "a very big integer is an Int that's greater than 500"
# You can specify the type you're subtyping (by default, Any),
# and add additional checks with the "where" keyword:
subset VeryBigInteger of Int where * > 500;
## Multiple Dispatch
# Perl 6 can decide which variant of a `sub` to call based on the type of the
# arguments, or on arbitrary preconditions, like with a type or a `where`:
@ -567,20 +537,19 @@ map(sub ($a, $b) { $a + $b + 3 }, @array); # (here with `sub`)
multi sub sayit(Int $n) { # note the `multi` keyword here
say "Number: $n";
}
multi sayit(Str $s) } # the `sub` is the default
multi sayit(Str $s) { # a multi is a `sub` by default
say "String: $s";
}
sayit("foo"); # prints "String: foo"
sayit(True); # fails at *compile time* with
# "calling 'sayit' will never work with arguments of types ..."
# with arbitrary precondition:
# with arbitrary precondition (remember subsets?):
multi is-big(Int $n where * > 50) { "Yes !" } # using a closure
multi is-big(Int $ where 10..50) { "Quite." } # Using smart-matching
# (could use a regexp, etc)
multi is-big(Int $) { "No" }
# You can also name these checks, by creating "subsets":
subset Even of Int where * %% 2;
multi odd-or-even(Even) { "Even" } # The main case using the type.
@ -660,7 +629,7 @@ class A {
has Int $!private-field = 10;
method get-value {
$.field + $!private-field + $n;
$.field + $!private-field;
}
method set-value($n) {
@ -678,7 +647,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`).
@ -724,7 +693,7 @@ role PrintableVal {
}
}
# you "use" a mixin with "does" :
# you "import" a mixin (a "role") with "does":
class Item does PrintableVal {
has $.val;
@ -971,7 +940,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 !!
@ -1083,9 +1052,7 @@ postcircumfix:<{ }>(%h, $key, :delete); # (you can call operators like that)
# It's a prefix meta-operator that takes a binary functions and
# one or many lists. If it doesn't get passed any argument,
# it either return a "default value" for this operator
# (a value that wouldn't change the result if passed as one
# of the element of the list to be passed to the operator),
# or `Any` if there's none (examples below).
# (a meaningless value) or `Any` if there's none (examples below).
#
# Otherwise, it pops an element from the list(s) one at a time, and applies
# the binary function to the last result (or the list's first element)
@ -1107,9 +1074,7 @@ say [//] Nil, Any, False, 1, 5; #=> False
# Default value examples:
say [*] (); #=> 1
say [+] (); #=> 0
# In both cases, they're results that, were they in the lists,
# wouldn't have any impact on the final value
# (since N*1=N and N+0=N).
# meaningless values, since N*1=N and N+0=N.
say [//]; #=> (Any)
# There's no "default value" for `//`.
@ -1163,90 +1128,6 @@ say @fib[^10]; #=> 1 1 2 3 5 8 13 21 34 55
# That's why `@primes[^100]` will take a long time the first time you print
# it, then be instant.
## * Sort comparison
# They return one value of the `Order` enum : `Less`, `Same` and `More`
# (which numerify to -1, 0 or +1).
1 <=> 4; # sort comparison for numerics
'a' leg 'b'; # sort comparison for string
$obj eqv $obj2; # sort comparison using eqv semantics
## * Generic ordering
3 before 4; # True
'b' after 'a'; # True
## * Short-circuit default operator
# Like `or` and `||`, but instead returns the first *defined* value :
say Any // Nil // 0 // 5; #=> 0
## * Short-circuit exclusive or (XOR)
# Returns `True` if one (and only one) of its arguments is true
say True ^^ False; #=> True
## * Flip Flop
# The flip flop operators (`ff` and `fff`, equivalent to P5's `..`/`...`).
# are operators that take two predicates to test:
# They are `False` until their left side returns `True`, then are `True` until
# their right side returns `True`.
# Like for ranges, you can exclude the iteration when it became `True`/`False`
# by using `^` on either side.
# Let's start with an example :
for <well met young hero we shall meet later> {
# by default, `ff`/`fff` smart-match (`~~`) against `$_`:
if 'met' ^ff 'meet' { # Won't enter the if for "met"
# (explained in details below).
.say
}
if rand == 0 ff rand == 1 { # compare variables other than `$_`
say "This ... probably will never run ...";
}
}
# This will print "young hero we shall meet" (excluding "met"):
# the flip-flop will start returning `True` when it first encounters "met"
# (but will still return `False` for "met" itself, due to the leading `^`
# on `ff`), until it sees "meet", which is when it'll start returning `False`.
# The difference between `ff` (awk-style) and `fff` (sed-style) is that
# `ff` will test its right side right when its left side changes to `True`,
# and can get back to `False` right away
# (*except* it'll be `True` for the iteration that matched) -
# While `fff` will wait for the next iteration to
# try its right side, once its left side changed:
.say if 'B' ff 'B' for <A B C B A>; #=> B B
# because the right-hand-side was tested
# directly (and returned `True`).
# "B"s are printed since it matched that time
# (it just went back to `False` right away).
.say if 'B' fff 'B' for <A B C B A>; #=> B C B
# The right-hand-side wasn't tested until
# `$_` became "C"
# (and thus did not match instantly).
# A flip-flop can change state as many times as needed:
for <test start print it stop not printing start print again stop not anymore> {
.say if $_ eq 'start' ^ff^ $_ eq 'stop'; # exclude both "start" and "stop",
#=> "print this printing again"
}
# you might also use a Whatever Star,
# which is equivalent to `True` for the left side or `False` for the right:
for (1, 3, 60, 3, 40, 60) { # Note: the parenthesis are superfluous here
# (sometimes called "superstitious parentheses")
.say if $_ > 50 ff *; # Once the flip-flop reaches a number greater than 50,
# it'll never go back to `False`
#=> 60 3 40 60
}
# You can also use this property to create an `If`
# that'll not go through the first time :
for <a b c> {
.say if * ^ff *; # the flip-flop is `True` and never goes back to `False`,
# but the `^` makes it *not run* on the first iteration
#=> b c
}
### Regular Expressions
# I'm sure a lot of you have been waiting for this one.
# Well, now that you know a good deal of Perl 6 already, we can get started.
@ -1470,6 +1351,105 @@ multi MAIN('import', File, Str :$as) { ... } # omitting parameter name
# As you can see, this is *very* powerful.
# It even went as far as to show inline the constants.
# (the type is only displayed if the argument is `$`/is named)
###
### APPENDIX A:
###
### List of things
###
# It's considered by now you know the Perl6 basics.
# This section is just here to list some common operations,
# but which are not in the "main part" of the tutorial to bloat it up
## Operators
## * Sort comparison
# They return one value of the `Order` enum : `Less`, `Same` and `More`
# (which numerify to -1, 0 or +1).
1 <=> 4; # sort comparison for numerics
'a' leg 'b'; # sort comparison for string
$obj eqv $obj2; # sort comparison using eqv semantics
## * Generic ordering
3 before 4; # True
'b' after 'a'; # True
## * Short-circuit default operator
# Like `or` and `||`, but instead returns the first *defined* value :
say Any // Nil // 0 // 5; #=> 0
## * Short-circuit exclusive or (XOR)
# Returns `True` if one (and only one) of its arguments is true
say True ^^ False; #=> True
## * Flip Flop
# The flip flop operators (`ff` and `fff`, equivalent to P5's `..`/`...`).
# are operators that take two predicates to test:
# They are `False` until their left side returns `True`, then are `True` until
# their right side returns `True`.
# Like for ranges, you can exclude the iteration when it became `True`/`False`
# by using `^` on either side.
# Let's start with an example :
for <well met young hero we shall meet later> {
# by default, `ff`/`fff` smart-match (`~~`) against `$_`:
if 'met' ^ff 'meet' { # Won't enter the if for "met"
# (explained in details below).
.say
}
if rand == 0 ff rand == 1 { # compare variables other than `$_`
say "This ... probably will never run ...";
}
}
# This will print "young hero we shall meet" (excluding "met"):
# the flip-flop will start returning `True` when it first encounters "met"
# (but will still return `False` for "met" itself, due to the leading `^`
# on `ff`), until it sees "meet", which is when it'll start returning `False`.
# The difference between `ff` (awk-style) and `fff` (sed-style) is that
# `ff` will test its right side right when its left side changes to `True`,
# and can get back to `False` right away
# (*except* it'll be `True` for the iteration that matched) -
# While `fff` will wait for the next iteration to
# try its right side, once its left side changed:
.say if 'B' ff 'B' for <A B C B A>; #=> B B
# because the right-hand-side was tested
# directly (and returned `True`).
# "B"s are printed since it matched that time
# (it just went back to `False` right away).
.say if 'B' fff 'B' for <A B C B A>; #=> B C B
# The right-hand-side wasn't tested until
# `$_` became "C"
# (and thus did not match instantly).
# A flip-flop can change state as many times as needed:
for <test start print it stop not printing start print again stop not anymore> {
.say if $_ eq 'start' ^ff^ $_ eq 'stop'; # exclude both "start" and "stop",
#=> "print this printing again"
}
# you might also use a Whatever Star,
# which is equivalent to `True` for the left side or `False` for the right:
for (1, 3, 60, 3, 40, 60) { # Note: the parenthesis are superfluous here
# (sometimes called "superstitious parentheses")
.say if $_ > 50 ff *; # Once the flip-flop reaches a number greater than 50,
# it'll never go back to `False`
#=> 60 3 40 60
}
# You can also use this property to create an `If`
# that'll not go through the first time :
for <a b c> {
.say if * ^ff *; # the flip-flop is `True` and never goes back to `False`,
# but the `^` makes it *not run* on the first iteration
#=> b c
}
# - `===` is value identity and uses `.WHICH` on the objects to compare them
# - `=:=` is container identity and uses `VAR()` on the objects to compare them
```
If you want to go further, you can:
@ -1477,5 +1457,5 @@ If you want to go further, you can:
- Read the [Perl 6 Advent Calendar](http://perl6advent.wordpress.com/). This is probably the greatest source of Perl 6 information, snippets and such.
- Come along on `#perl6` at `irc.freenode.net`. The folks here are always helpful.
- Check the [source of Perl 6's functions and classes](https://github.com/rakudo/rakudo/tree/nom/src/core). Rakudo is mainly written in Perl 6 (with a lot of NQP, "Not Quite Perl", a Perl 6 subset easier to implement and optimize).
- Read the [Synopses](perlcabal.org/syn). They explain it from an implementor point-of-view, but it's still very interesting.
- Read [the language design documents](http://design.perl6.org). They explain P6 from an implementor point-of-view, but it's still very interesting.

View File

@ -60,7 +60,7 @@ $float = 1.2e3;
$float = 7E-10;
// Delete variable
unset($int1)
unset($int1);
// Arithmetic
$sum = 1 + 1; // 2

View File

@ -0,0 +1,637 @@
---
name: python
category: language
language: python
filename: learnpython-pl.py
contributors:
- ["Louie Dinh", "http://ldinh.ca"]
- ["Amin Bandali", "http://aminbandali.com"]
- ["Andre Polykanine", "https://github.com/Oire"]
translators:
- ["Dominik Krzemiński", "https://github.com/dokato"]
lang: pl-pl
---
Python został opracowany przez Guido Van Rossuma na początku lat 90-tych.
Obecnie jest jednym z najbardziej popularnych języków programowania.
Zakochałem się w Pythonie dzięki porządkowi, jaki utrzymywany jest w kodzie.
To po prostu wykonywalny pseudokod.
Zapraszam do kontaktu. Złapiecie nas na:
- kontakt polski: raymon92 [at] [google's email service]
- kontakt angielski: [@louiedinh](http://twitter.com/louiedinh) lub louiedinh [at] [google's email service]
Uwaga: Ten artykuł odnosi się do wersji Pythona 2.7, ale powinien
działać w wersjach 2.x. Dla wersji 3.x znajdziesz odpowiedni artykuł na stronie głównej.
```python
# -*- coding: utf-8 -*-
# Pojedyncze komentarze oznaczamy takim symbolem.
""" Wielolinijkowe napisy zapisywane są przy użyciu
trzech znaków cudzysłowiu i często
wykorzystywane są jako komentarze.
"""
####################################################
## 1. Podstawowe typy danych i operatory
####################################################
# Liczby to liczby
3 # => 3
# Matematyka jest intuicyjna
1 + 1 # => 2
8 - 1 # => 7
10 * 2 # => 20
35 / 5 # => 7
# Dzielenie może być kłopotliwe. Poniższe to dzielenie
# całkowitoliczbowe(int) i wynik jest automatycznie zaokrąglany.
5 / 2 # => 2
# Aby to naprawić musimy powiedzieć nieco o liczbach zmiennoprzecinkowych.
2.0 # To liczba zmiennoprzecinkowa, tzw. float
11.0 / 4.0 # => 2.75 ahhh...znacznie lepiej
# Wynik dzielenia całkowitoliczbowego jest obcinany dla liczb
# dodatnich i ujemnych.
5 // 3 # => 1
5.0 // 3.0 # => 1.0 # działa też na floatach
-5 // 3 # => -2
-5.0 // 3.0 # => -2.0
# Operator modulo - wyznaczanie reszty z dzielenia
7 % 3 # => 1
# Potęgowanie (x do potęgi ytej)
2**4 # => 16
# Wymuszanie pierwszeństwa w nawiasach
(1 + 3) * 2 # => 8
# Operacje logiczne
# Zauważ, że przy "and" i "or" trzeba zwracać uwagę na rozmiar liter
True and False #=> False # Fałsz
False or True #=> True # Prawda
# Zauważ, że operatorów logicznych można używać z intami
0 and 2 #=> 0
-5 or 0 #=> -5
0 == False #=> True
2 == True #=> False
k1 == True #=> True
# aby zanegować użyj "not"
not True # => False
not False # => True
# Równość ==
1 == 1 # => True
2 == 1 # => False
# Nierówność !=
1 != 1 # => False
2 != 1 # => True
# Więcej porównań
1 < 10 # => True
1 > 10 # => False
2 <= 2 # => True
2 >= 2 # => True
# Porównania można układać w łańcuch!
1 < 2 < 3 # => True
2 < 3 < 2 # => False
# Napisy (typ string) tworzone są przy użyciu cudzysłowów " lub '
"Jestem napisem."
'Ja też jestem napisem.'
# Napisy można dodawać!
"Witaj " + "świecie!" # => "Witaj świecie!"
# ... a nawet mnożone
"Hej" * 3 # => "HejHejHej"
# Napis może być traktowany jako lista znaków
"To napis"[0] # => 'T'
# % może być używane do formatowania napisów:
"%s są %s" % ("napisy", "fajne")
# Jednak nowszym sposobem formatowania jest metoda "format".
# Ta metoda jest obecnie polecana:
"{0} są {1}".format("napisy", "fajne")
# Jeśli nie chce ci się liczyć użyj słów kluczowych.
"{imie} chce zjeść {jadlo}".format(imie="Bob", jasno="lasagne")
# None jest obiektem
None # => None
# Nie używaj "==" w celu porównania obiektów z None
# Zamiast tego użyj "is"
"etc" is None # => False
None is None # => True
# Operator 'is' testuje identyczność obiektów. To nie jest zbyt
# pożyteczne, gdy działamy tylko na prostych wartościach,
# ale przydaje się, gdy mamy do czynienia z obiektami.
# None, 0, i pusty napis "" są odpowiednikami logicznego False.
# Wszystkie inne wartości są True
bool(0) # => False
bool("") # => False
####################################################
## 2. Zmienne i zbiory danych
####################################################
# Python ma wyrażenie wypisujące "print" we wszystkich wersjach 2.x, ale
# zostało usunięte z wersji 3.
print "Jestem Python. Miło poznać!"
# Python ma też funkcję "print" dostępną w wersjach 2.7 and 3...
# ale w 2.7 musisz dodać import (odkomentuj):
# from __future__ import print_function
print("Ja też jestem Python! ")
# Nie trzeba deklarować zmiennych przed przypisaniem.
jakas_zmienna = 5 # Konwencja mówi: używaj małych znaków i podłogi _
jakas_zmienna # => 5
# Próba dostępu do niezadeklarowanej zmiennej da błąd.
# Przejdź do sekcji Obsługa wyjątków po więcej...
inna_zmienna # Wyrzuca nazwę błędu
# "if" może być użyte jako wyrażenie
"huraaa!" if 3 > 2 else 2 # => "huraaa!"
# Listy:
li = []
# Możesz zacząć od wypełnionej listy
inna_li = [4, 5, 6]
# Dodaj na koniec używając "append"
li.append(1) # li to teraz [1]
li.append(2) # li to teraz [1, 2]
li.append(4) # li to teraz [1, 2, 4]
li.append(3) # li to teraz [1, 2, 4, 3]
# Usuwanie z konca da "pop"
li.pop() # => 3 a li stanie się [1, 2, 4]
# Dodajmy ponownie
li.append(3) # li to znowu [1, 2, 4, 3].
# Dostęp do list jak do każdej tablicy
li[0] # => 1
# Użyj = aby nadpisać wcześniej wypełnione miejsca w liście
li[0] = 42
li[0] # => 42
li[0] = 1 # Uwaga: ustawiamy starą wartość
# Tak podglądamy ostatni element
li[-1] # => 3
# Jeżeli wyjdziesz poza zakres...
li[4] # ... zobaczysz IndexError
# Możesz tworzyć wyniki.
li[1:3] # => [2, 4]
# Bez początku
li[2:] # => [4, 3]
# Omijamy koniec
li[:3] # => [1, 2, 4]
# Wybierz co drugi
li[::2] # =>[1, 4]
# Odwróć listę
li[::-1] # => [3, 4, 2, 1]
# Użyj kombinacji powyższych aby tworzyć bardziej skomplikowane wycinki
# li[poczatek:koniec:krok]
# Usuń element używając "del"
del li[2] # li to teraz [1, 2, 3]
# Listy można dodawać
li + inna_li # => [1, 2, 3, 4, 5, 6]
# Uwaga: wartości poszczególnych list się nie zmieniają.
# Do łączenia list użyj "extend()"
li.extend(other_li) # li to teraz [1, 2, 3, 4, 5, 6]
# Sprawdź czy jest w liście używając "in"
1 in li # => True
# "len()" pokazuje długość listy
len(li) # => 6
# Krotki (tuple) są jak listy, ale nie można ich modyfikować.
tup = (1, 2, 3)
tup[0] # => 1
tup[0] = 3 # wyrzuci TypeError
# Ale wielu akcji dla list możesz używać przy krotkach
len(tup) # => 3
tup + (4, 5, 6) # => (1, 2, 3, 4, 5, 6)
tup[:2] # => (1, 2)
2 in tup # => True
# Można rozpakować krotki i listy do poszczególych zmiennych
a, b, c = (1, 2, 3) # a to teraz 1, b jest 2, a c to 3
# Jeżeli zapomnisz nawiasów automatycznie tworzone są krotki
d, e, f = 4, 5, 6
# Popatrz jak prosto zamienić wartości
e, d = d, e # d to teraz 5 a e to 4
# Słowniki są również pożyteczne
pusty_slownik = {}
# Tu tworzymy wypełniony:
pelen_slownik = {"raz": 1, "dwa": 2, "trzy": 3}
# Podglądany wartość
pelen_slownik["one"] # => 1
# Wypisz wszystkie klucze używając "keys()"
pelen_slownik.keys() # => ["trzy", "dwa", "raz"]
# Uwaga: słowniki nie gwarantują kolejności występowania kluczy.
# A teraz wszystkie wartości "values()"
pelen_slownik.values() # => [3, 2, 1]
# Uwaga: to samo dotyczy wartości.
# Sprawdzanie czy występuje to "in"
"raz" in pelen_slownik # => True
1 in pelen_slownik # => False
# Próba dobrania się do nieistniejącego klucza da KeyError
pelen_slownik["cztery"] # KeyError
# Użyj "get()" method aby uniknąć KeyError
pelen_slownik.get("raz") # => 1
pelen_slownik.get("cztery") # => None
# Metoda get zwraca domyślną wartość gdy brakuje klucza
pelen_slownik.get("one", 4) # => 1
pelen_slownik.get("cztery", 4) # => 4
# zauważ, że pelen_slownik.get("cztery") jest wciąż => None
# (get nie ustawia wartości słownika)
# przypisz wartość do klucza podobnie jak w listach
pelen_slownik["cztery"] = 4 # teraz: pelen_slownik["cztery"] => 4
# "setdefault()" wstawia do słownika tylko jeśli nie było klucza
pelen_slownik.setdefault("piec", 5) # pelen_slownik["piec"] daje 5
pelen_slownik.setdefault("piec", 6) # pelen_slownik["piec"] to wciąż 5
# Teraz zbiory (set) ... cóż zbiory (to po prostu listy ale bez potórzeń)
pusty_zbior = set()
# Inicjalizujemy "set()" pewnymi wartościami
jakis_zbior = set([1, 2, 2, 3, 4]) # jakis_zbior to teraz set([1, 2, 3, 4])
# kolejność nie jest gwarantowana, nawet gdy wydaje się posortowane
inny_zbior = set([4, 3, 2, 2, 1]) # inny_zbior to set([1, 2, 3, 4])
# Od Pythona 2.7 nawiasy klamrowe {} mogą być użyte do deklarowania zbioru
pelen_zbior = {1, 2, 2, 3, 4} # => {1, 2, 3, 4}
# Dodaj więcej elementów przez "add()"
pelen_zbior.add(5) # pelen_zbior is now {1, 2, 3, 4, 5}
# Znajdź przecięcie zbiorów używając &
inny_zbior = {3, 4, 5, 6}
pelen_zbior & other_set # => {3, 4, 5}
# Suma zbiorów |
pelen_zbior | other_set # => {1, 2, 3, 4, 5, 6}
# Różnicę zbiorów da znak -
{1, 2, 3, 4} - {2, 3, 5} # => {1, 4}
# Sprawdzanie obecności w zbiorze: "in".
2 in pelen_zbior # => True
10 in pelen_zbior # => False
####################################################
## 3. Kontrola przepływu
####################################################
# Tworzymy zmienną some_var
some_var = 5
# Tutaj widzisz wyrażenie warunkowe "if". Wcięcia są ważne Pythonie!
# wypisze "some_var jest mniejsza niż 10"
if some_var > 10:
print("some_var jest wieksza niż 10")
elif some_var < 10: # This elif clause is optional.
print("some_var jest mniejsza niż 10")
else: # This is optional too.
print("some_var jest równa 10")
"""
Pętla for iteruje po elementach listy wypisując:
pies to ssak
kot to ssak
mysz to ssak
"""
for zwierze in ["pies", "kot", "mysz"]:
# Możesz użyć % aby stworzyć sformatowane napisy
print("%s to ssak" % zwierze)
"""
"range(liczba)" zwraca listę liczb
od zera do danej liczby:
0
1
2
3
"""
for i in range(4):
print(i)
"""
While to pętla która jest wykonywana dopóki spełniony jest warunek:
0
1
2
3
"""
x = 0
while x < 4:
print(x)
x += 1 # Skrót od x = x + 1
# Wyjątki wyłapujemy używając try, except
# Działa w Pythonie 2.6 i wyższych:
try:
# Użyj "raise" aby wyrzucić wyjąte
raise IndexError("To błąd indeksu")
except IndexError as e:
pass # Pass to brak reakcji na błąd. Zazwyczaj nanosisz tu poprawki.
except (TypeError, NameError):
pass # kilka wyjątków może być przechwyce razem.
else: # Opcjonalna część bloku try/except. Musi wystąpić na końcu
print "Wszystko ok!" # Zadziała tylko, gdy program nie napotka wyjatku.
####################################################
## 4. Funkcjie
####################################################
# Użyj "def" aby stworzyć nową funkcję
def dodaj(x, y):
print("x to %s a y to %s" % (x, y))
return x + y # słówko kluczowe return zwraca wynik działania
# Tak wywołuje się funkcję z parametrami (args):
dodaj(5, 6) # => wypisze "x to 5 a y to 6" i zwróci 11
# Innym sposobem jest wywołanie z parametrami nazwanymi.
dodaj(y=6, x=5) # tutaj kolejność podania nie ma znaczenia.
# Można też stworzyć funkcję, które przyjmują różną ilość parametrów
# nienazwanych args, co będzie interpretowane jako krotka jeśli nie użyjesz *
def varargs(*args):
return args
varargs(1, 2, 3) # => (1, 2, 3)
# Można też stworzyć funkcję, które przyjmują różną ilość parametrów
# nazwanych kwargs, które będa interpretowane jako słownik jeśli nie dasz **
def keyword_args(**kwargs):
return kwargs
# Wywołajmy to i sprawdźmy co się dzieje
keyword_args(wielka="stopa", loch="ness") # => {"wielka": "stopa", "loch": "ness"}
# Możesz też to pomieszać
def all_the_args(*args, **kwargs):
print(args)
print(kwargs)
"""
all_the_args(1, 2, a=3, b=4) wyrzuci:
(1, 2)
{"a": 3, "b": 4}
"""
# Użyj * aby rozwinąć parametry z krotki args
# i użyj ** aby rozwinąć parametry nazwane ze słownika kwargs.
args = (1, 2, 3, 4)
kwargs = {"a": 3, "b": 4}
all_the_args(*args) # odpowiednik foo(1, 2, 3, 4)
all_the_args(**kwargs) # odpowiednik foo(a=3, b=4)
all_the_args(*args, **kwargs) # odpowiednik foo(1, 2, 3, 4, a=3, b=4)
# Możesz podać parametry args i kwargs do funkcji równocześnie
# przez rozwinięcie odpowiednio * i **
def pass_all_the_args(*args, **kwargs):
all_the_args(*args, **kwargs)
print varargs(*args)
print keyword_args(**kwargs)
# Zakres widoczności
x = 5
def setX(num):
# Lokalna zmienna x nie jest tym samym co zmienna x
x = num # => 43
print x # => 43
def setGlobalX(num):
global x
print x # => 5
x = num # globalna zmienna to teraz 6
print x # => 6
setX(43)
setGlobalX(6)
# Można tworzyć funkcje wewnętrzne i zwrócić je jako wynik
def rob_dodawacz(x):
def dodawacz(y):
return x + y
return dodawacz
dodaj_10 = rob_dodawacz(10)
dodaj_10(3) # => 13
# Są również funkcje nienazwane "lambda"
(lambda x: x > 2)(3) # => True
# Są także wbudowane funkcje wysokiego poziomu
map(add_10, [1, 2, 3]) # => [11, 12, 13]
filter(lambda x: x > 5, [3, 4, 5, 6, 7]) # => [6, 7]
# Można używać wyrażeń listowych do mapowania (map) i filtrowania (filter)
[add_10(i) for i in [1, 2, 3]] # => [11, 12, 13]
[x for x in [3, 4, 5, 6, 7] if x > 5] # => [6, 7]
####################################################
## 5. Klasy
####################################################
# Wszystkie klasy są podklasą object
class Czlowiek(object):
# Atrybut klasy. Występuje we wszystkich instancjach klasy.
gatunek = "H. sapiens"
# Podstawowa inicjalizacja - wywoływana podczas tworzenia instacji.
# Zauważ, że podwójne podkreślenia przed i za nazwą oznaczają
# obietky lub atrybuty, który żyją tylko w kontrolowanej przez
# użytkownika przestrzeni nazw. Nie używaj ich we własnych metodach.
def __init__(self, nazwa):
# przypisz parametr "nazwa" do atrybutu instancji
self.nazwa = nazwa
# Metoda instancji. Wszystkie metody biorą "self" jako pierwszy argument
def mow(self, wiadomosc):
return "%s: %s" % (self.nazwa, wiadomosc)
# Metoda klasowa współdzielona przez instancje.
# Ma wywołującą klasę jako pierwszy argument.
@classmethod
def daj_gatunek(cls):
return cls.gatunek
# Metoda statyczna jest wywoływana bez argumentów klasy czy instancji.
@staticmethod
def grunt():
return "*grunt*"
# Instancja klasy
i = Czlowiek(name="Ian")
print(i.mow("cześć")) # wypisze "Ian: cześć"
j = Czlowiek("Joel")
print(j.mow("cześć")) # wypisze "Joel: cześć"
# Wywołujemy naszą metodę klasową
i.daj_gatunek() # => "H. sapiens"
# Zmieniamy wspólny parametr
Czlowiek.gatunek = "H. neanderthalensis"
i.daj_gatunek() # => "H. neanderthalensis"
j.daj_gatunek() # => "H. neanderthalensis"
# Wywołanie metody statycznej
Czlowiek.grunt() # => "*grunt*"
####################################################
## 6. Moduły
####################################################
# Tak importuje się moduły:
import math
print(math.sqrt(16)) # => 4
# Można podać konkretne funkcje, np. ceil, floor z modułu math
from math import ceil, floor
print(ceil(3.7)) # => 4.0
print(floor(3.7)) # => 3.0
# Można zaimportować wszystkie funkcje z danego modułu.
# Ostrzeżenie: nie jest to polecane.
from math import *
# Można skracać nazwy modułów.
import math as m
math.sqrt(16) == m.sqrt(16) # => True
# sprawdźmy czy funkcje są równoważne
from math import sqrt
math.sqrt == m.sqrt == sqrt # => True
# Moduły pythona to zwykłe skrypty napisane w tym języku. Możesz
# pisać własne i importować je. Nazwa modułu to nazwa pliku.
# W ten sposób sprawdzisz jakie funkcje wchodzą w skład modułu.
import math
dir(math)
####################################################
## 7. Zaawansowane
####################################################
# Generatory pomagają tworzyć tzw. "leniwy kod"
def podwojne_liczby(iterowalne):
for i in iterowalne:
yield i + i
# Generatory tworzą wartości w locie.
# W przeciwienstwie do wygenerowania wartości raz i ich zachowania,
# powstają one na bieżąco, w wyniku iteracji. To oznacza, że wartości
# większe niż 15 nie będą przetworzone w funkcji "podwojne_liczby".
# Zauważ, że xrange to generator, który wykonuje tę samą operację co range.
# Stworzenie listy od 1 do 900000000 zajęłoby sporo czasu i pamięci,
# a xrange tworzy obiekt generatora zamiast tworzyć całą listę jak range.
# Użyto podkreślinika, aby odróżnić nazwę zmiennej od słówka kluczowego
# Pythona.
xrange_ = xrange(1, 900000000)
# poniższa pętla będzie podwajać liczby aż do 30
for i in podwojne_liczby(xrange_):
print(i)
if i >= 30:
break
# Dekoratory
# w tym przykładzie "beg" jest nakładką na "say"
# Beg wywołuje say. Jeśli say_please jest prawdziwe wtedy wzracana wartość
# zostanie zmieniona
from functools import wraps
def beg(target_function):
@wraps(target_function)
def wrapper(*args, **kwargs):
msg, say_please = target_function(*args, **kwargs)
if say_please:
return "{} {}".format(msg, "Proszę! Jestem spłukany :(")
return msg
return wrapper
@beg
def say(say_please=False):
msg = "Kupisz mi piwo?"
return msg, say_please
print(say()) # Kupisz mi piwo?
print(say(say_please=True)) # Kupisz mi piwo? Proszę! Jestem spłukany :(
```
## Gotowy na więcej?
### Polskie
* [Zanurkuj w Pythonie](http://pl.wikibooks.org/wiki/Zanurkuj_w_Pythonie)
* [LearnPythonPl](http://www.learnpython.org/pl/)
### Angielskie:
#### Darmowe źródła online
* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/)
* [Dive Into Python](http://www.diveintopython.net/)
* [The Official Docs](http://docs.python.org/2.6/)
* [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/)
* [Python Module of the Week](http://pymotw.com/2/)
* [A Crash Course in Python for Scientists](http://nbviewer.ipython.org/5920182)
#### Inne
* [Programming Python](http://www.amazon.com/gp/product/0596158106/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596158106&linkCode=as2&tag=homebits04-20)
* [Dive Into Python](http://www.amazon.com/gp/product/1441413022/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1441413022&linkCode=as2&tag=homebits04-20)
* [Python Essential Reference](http://www.amazon.com/gp/product/0672329786/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0672329786&linkCode=as2&tag=homebits04-20)

View File

@ -199,4 +199,4 @@ That's it.
Download [Node.js](http://nodejs.org/) and `npm install pogo`.
There is plenty of documentation on [http://pogoscript.org/](http://pogoscript.org/), inlcuding a [cheat sheet](http://pogoscript.org/cheatsheet.html), a [guide](http://pogoscript.org/guide/), and how [Pogoscript translates to Javascript](http://featurist.github.io/pogo-examples/). Get in touch on the [google group](http://groups.google.com/group/pogoscript) if you have questions!
There is plenty of documentation on [http://pogoscript.org/](http://pogoscript.org/), including a [cheat sheet](http://pogoscript.org/cheatsheet.html), a [guide](http://pogoscript.org/guide/), and how [Pogoscript translates to Javascript](http://featurist.github.io/pogo-examples/). Get in touch on the [google group](http://groups.google.com/group/pogoscript) if you have questions!

View File

@ -0,0 +1,84 @@
---
language: brainfuck
contributors:
- ["Prajit Ramachandran", "http://prajitr.github.io/"]
- ["Mathias Bynens", "http://mathiasbynens.be/"]
translators:
- ["Suzane Sant Ana", "http://github.com/suuuzi"]
lang: pt-br
---
Brainfuck (em letras minúsculas, eceto no início de frases) é uma linguagem de
programação Turing-completa extremamente simples com apenas 8 comandos.
```
Qualquer caractere exceto "><+-.,[]" (sem contar as aspas) é ignorado.
Brainfuck é representado por um vetor com 30 000 células inicializadas em zero
e um ponteiro de dados que aponta para a célula atual.
Existem 8 comandos:
+ : Incrementa o vaor da célula atual em 1.
- : Decrementa o valor da célula atual em 1.
> : Move o ponteiro de dados para a célula seguinte (célula à direita).
< : Move o ponteiro de dados para a célula anterior (célula à esquerda).
. : Imprime o valor ASCII da célula atual. (ex. 65 = 'A').
, : Lê um único caractere para a célula atual.
[ : Se o valor da célula atual for zero, salta para o ] correspondente.
Caso contrário, passa para a instrução seguinte.
] : Se o valor da célula atual for zero, passa para a instrução seguinte.
Caso contrário, volta para a instrução relativa ao [ correspondente.
[ e ] formam um ciclo while. Obviamente, devem ser equilibrados.
Vamos ver alguns exemplos básicos em brainfuck:
++++++ [ > ++++++++++ < - ] > +++++ .
Este programa imprime a letra 'A'. Primeiro incrementa a célula #1 para 6.
A célula #1 será usada num ciclo. Depois é iniciado o ciclo ([) e move-se
o ponteiro de dados para a célula #2. O valor da célula #2 é incrementado 10
vezes, move-se o ponteiro de dados de volta para a célula #1, e decrementa-se
a célula #1. Este ciclo acontece 6 vezes (são necessários 6 decrementos para
a célula #1 chegar a 0, momento em que se salta para o ] correspondente,
continuando com a instrução seguinte).
Nesta altura estamos na célula #1, cujo valor é 0, enquanto a célula #2
tem o valor 60. Movemos o ponteiro de dados para a célula #2, incrementa-se 5
vezes para um valor final de 65, e então é impresso o valor da célula #2. O valor
65 corresponde ao caractere 'A' em ASCII, então 'A' é impresso no terminal.
, [ > + < - ] > .
Este programa lê um caractere e copia o seu valor para a célula #1. Um ciclo é
iniciado. Movemos o ponteiro de dados para a célula #2, incrementamos o valor na
célula #2, movemos o ponteiro de dados de volta para a célula #1 e finalmente
decrementamos o valor na célula #1. Isto continua até o valor na célula #1 ser
igual a 0 e a célula #2 ter o antigo valor da célula #1. Como o ponteiro de
dados está apontando para a célula #1 no fim do ciclo, movemos o ponteiro para a
célula #2 e imprimimos o valor em ASCII.
Os espaços servem apenas para tornar o programa mais legível. Podemos escrever
o mesmo programa da seguinte maneira:
,[>+<-]>.
Tente descobrir o que este programa faz:
,>,< [ > [ >+ >+ << -] >> [- << + >>] <<< -] >>
Este programa lê dois números e os multiplica.
Basicamente o programa pede dois caracteres ao usuário. Depois é iniciado um
ciclo exterior controlado pelo valor da célula #1. Movemos o ponteiro de dados
para a célula #2 e inicia-se o ciclo interior controlado pelo valor da célula
#2, incrementando o valor da célula #3. Porém existe um problema, no final do
ciclo interior: a célula #2 tem o valor 0. Para resolver este problema o valor da
célula #4 é também incrementado e copiado para a célula #2.
```
E isto é brainfuck. Simples, não? Por divertimento você pode escrever os
seus próprios programas em brainfuck, ou então escrever um interpretador de
brainfuck em outra linguagem. O interpretador é relativamente fácil de se
implementar, mas caso você seja masoquista, tente escrever um interpretador de
brainfuck… em brainfuck.

590
pt-br/c++-pt.html.markdown Normal file
View File

@ -0,0 +1,590 @@
---
language: c++
filename: learncpp.cpp
contributors:
- ["Steven Basart", "http://github.com/xksteven"]
- ["Matt Kline", "https://github.com/mrkline"]
translators:
- ["Miguel Araújo", "https://github.com/miguelarauj1o"]
lang: pt-br
---
C++ é uma linguagem de programação de sistemas que,
[de acordo com seu inventor Bjarne Stroustrup](http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2014/Keynote),
foi concebida para
- ser um "C melhor"
- suportar abstração de dados
- suportar programação orientada a objetos
- suportar programação genérica
Embora sua sintaxe pode ser mais difícil ou complexa do que as linguagens mais
recentes, C++ é amplamente utilizado porque compila para instruções nativas que
podem ser executadas diretamente pelo processador e oferece um controlo rígido sobre hardware (como C), enquanto oferece recursos de alto nível, como os
genéricos, exceções e classes. Esta combinação de velocidade e funcionalidade
faz C++ uma das linguagens de programação mais utilizadas.
```c++
//////////////////
// Comparação com C
//////////////////
// C ++ é quase um super conjunto de C e compartilha sua sintaxe básica para
// declarações de variáveis, tipos primitivos, e funções. No entanto, C++ varia
// em algumas das seguintes maneiras:
// A função main() em C++ deve retornar um int, embora void main() é aceita
// pela maioria dos compiladores (gcc, bumbum, etc.)
// Este valor serve como o status de saída do programa.
// Veja http://en.wikipedia.org/wiki/Exit_status para mais informações.
int main(int argc, char** argv)
{
// Argumentos de linha de comando são passados em pelo argc e argv da mesma
// forma que eles estão em C.
// argc indica o número de argumentos,
// e argv é um array de strings, feito C (char*) representado os argumentos
// O primeiro argumento é o nome pelo qual o programa foi chamado.
// argc e argv pode ser omitido se você não se importa com argumentos,
// dando a assinatura da função de int main()
// Uma saída de status de 0 indica sucesso.
return 0;
}
// Em C++, caracteres literais são um byte.
sizeof('c') == 1
// Em C, caracteres literais são do mesmo tamanho que ints.
sizeof('c') == sizeof(10)
// C++ tem prototipagem estrita
void func(); // função que não aceita argumentos
// Em C
void func(); // função que pode aceitar qualquer número de argumentos
// Use nullptr em vez de NULL em C++
int* ip = nullptr;
// Cabeçalhos padrão C estão disponíveis em C++,
// mas são prefixados com "c" e não têm sufixo .h
#include <cstdio>
int main()
{
printf("Hello, world!\n");
return 0;
}
///////////////////////
// Sobrecarga de função
///////////////////////
// C++ suporta sobrecarga de função
// desde que cada função tenha parâmetros diferentes.
void print(char const* myString)
{
printf("String %s\n", myString);
}
void print(int myInt)
{
printf("My int is %d", myInt);
}
int main()
{
print("Hello"); // Funciona para void print(const char*)
print(15); // Funciona para void print(int)
}
/////////////////////////////
// Parâmetros padrão de função
/////////////////////////////
// Você pode fornecer argumentos padrões para uma função se eles não são
// fornecidos pelo chamador.
void doSomethingWithInts(int a = 1, int b = 4)
{
// Faça alguma coisa com os ints aqui
}
int main()
{
doSomethingWithInts(); // a = 1, b = 4
doSomethingWithInts(20); // a = 20, b = 4
doSomethingWithInts(20, 5); // a = 20, b = 5
}
// Argumentos padrões devem estar no final da lista de argumentos.
void invalidDeclaration(int a = 1, int b) // Erro!
{
}
/////////////
// Namespaces (nome de espaços)
/////////////
// Namespaces fornecem escopos distintos para variável, função e outras
// declarações. Namespaces podem estar aninhados.
namespace First {
namespace Nested {
void foo()
{
printf("This is First::Nested::foo\n");
}
} // Fim do namespace aninhado
} // Fim do namespace First
namespace Second {
void foo()
{
printf("This is Second::foo\n")
}
}
void foo()
{
printf("This is global foo\n");
}
int main()
{
// Assuma que tudo é do namespace "Second" a menos que especificado de
// outra forma.
using namespace Second;
foo(); // imprime "This is Second::foo"
First::Nested::foo(); // imprime "This is First::Nested::foo"
::foo(); // imprime "This is global foo"
}
///////////////
// Entrada/Saída
///////////////
// C ++ usa a entrada e saída de fluxos (streams)
// cin, cout, and cerr representa stdin, stdout, and stderr.
// << É o operador de inserção e >> é o operador de extração.
#include <iostream> // Inclusão para o I/O streams
using namespace std; // Streams estão no namespace std (biblioteca padrão)
int main()
{
int myInt;
// Imprime na saída padrão (ou terminal/tela)
cout << "Enter your favorite number:\n";
// Pega a entrada
cin >> myInt;
// cout também pode ser formatado
cout << "Your favorite number is " << myInt << "\n";
// imprime "Your favorite number is <myInt>"
cerr << "Usado para mensagens de erro";
}
//////////
// Strings
//////////
// Strings em C++ são objetos e têm muitas funções de membro
#include <string>
using namespace std; // Strings também estão no namespace std (bib. padrão)
string myString = "Hello";
string myOtherString = " World";
// + é usado para concatenação.
cout << myString + myOtherString; // "Hello World"
cout << myString + " You"; // "Hello You"
// Em C++, strings são mutáveis e têm valores semânticos.
myString.append(" Dog");
cout << myString; // "Hello Dog"
/////////////
// Referência
/////////////
// Além de indicadores como os de C, C++ têm _referências_. Esses são tipos de
// ponteiro que não pode ser reatribuída uma vez definidos e não pode ser nulo.
// Eles também têm a mesma sintaxe que a própria variável: Não * é necessário
// para _dereferencing_ e & (endereço de) não é usado para atribuição.
using namespace std;
string foo = "I am foo";
string bar = "I am bar";
string& fooRef = foo; // Isso cria uma referência para foo.
fooRef += ". Hi!"; // Modifica foo através da referência
cout << fooRef; // Imprime "I am foo. Hi!"
// Não realocar "fooRef". Este é o mesmo que "foo = bar", e foo == "I am bar"
// depois desta linha.
fooRef = bar;
const string& barRef = bar; // Cria uma referência const para bar.
// Como C, valores const (e ponteiros e referências) não podem ser modificado.
barRef += ". Hi!"; // Erro, referência const não pode ser modificada.
//////////////////////////////////////////
// Classes e programação orientada a objeto
//////////////////////////////////////////
// Primeiro exemplo de classes
#include <iostream>
// Declara a classe.
// As classes são geralmente declarado no cabeçalho arquivos (.h ou .hpp).
class Dog {
// Variáveis de membro e funções são privadas por padrão.
std::string name;
int weight;
// Todos os membros a seguir este são públicos até que "private:" ou
// "protected:" é encontrado.
public:
// Construtor padrão
Dog();
// Declarações de função Membro (implementações a seguir)
// Note que usamos std :: string aqui em vez de colocar
// using namespace std;
// acima.
// Nunca coloque uma declaração "using namespace" em um cabeçalho.
void setName(const std::string& dogsName);
void setWeight(int dogsWeight);
// Funções que não modificam o estado do objecto devem ser marcadas como
// const. Isso permite que você chamá-los se for dada uma referência const
// para o objeto. Além disso, observe as funções devem ser explicitamente
// declarados como _virtual_, a fim de ser substituídas em classes
// derivadas. As funções não são virtuais por padrão por razões de
// performance.
virtual void print() const;
// As funções também podem ser definidas no interior do corpo da classe.
// Funções definidas como tal são automaticamente embutidas.
void bark() const { std::cout << name << " barks!\n" }
// Junto com os construtores, C++ fornece destruidores.
// Estes são chamados quando um objeto é excluído ou fica fora do escopo.
// Isto permite paradigmas poderosos, como RAII
// (veja abaixo)
// Destruidores devem ser virtual para permitir que as classes de ser
// derivada desta.
virtual ~Dog();
}; // Um ponto e vírgula deve seguir a definição de classe.
// Funções membro da classe geralmente são implementados em arquivos .cpp.
void Dog::Dog()
{
std::cout << "A dog has been constructed\n";
}
// Objetos (como strings) devem ser passados por referência
// se você está modificando-os ou referência const se você não é.
void Dog::setName(const std::string& dogsName)
{
name = dogsName;
}
void Dog::setWeight(int dogsWeight)
{
weight = dogsWeight;
}
// Observe que "virtual" só é necessária na declaração, não a definição.
void Dog::print() const
{
std::cout << "Dog is " << name << " and weighs " << weight << "kg\n";
}
void Dog::~Dog()
{
cout << "Goodbye " << name << "\n";
}
int main() {
Dog myDog; // imprime "A dog has been constructed"
myDog.setName("Barkley");
myDog.setWeight(10);
myDog.printDog(); // imprime "Dog is Barkley and weighs 10 kg"
return 0;
} // imprime "Goodbye Barkley"
// herança:
// Essa classe herda tudo público e protegido da classe Dog
class OwnedDog : public Dog {
void setOwner(const std::string& dogsOwner)
// Substituir o comportamento da função de impressão de todas OwnedDogs.
// Ver http://en.wikipedia.org/wiki/Polymorphism_(computer_science)#Subtyping
// Para uma introdução mais geral, se você não estiver familiarizado com o
// polimorfismo subtipo. A palavra-chave override é opcional, mas torna-se
// na verdade você está substituindo o método em uma classe base.
void print() const override;
private:
std::string owner;
};
// Enquanto isso, no arquivo .cpp correspondente:
void OwnedDog::setOwner(const std::string& dogsOwner)
{
owner = dogsOwner;
}
void OwnedDog::print() const
{
Dog::print(); // Chame a função de impressão na classe Dog base de
std::cout << "Dog is owned by " << owner << "\n";
// Prints "Dog is <name> and weights <weight>"
// "Dog is owned by <owner>"
}
//////////////////////////////////////////
// Inicialização e Sobrecarga de Operadores
//////////////////////////////////////////
// Em C ++, você pode sobrecarregar o comportamento dos operadores, tais como
// +, -, *, /, etc. Isto é feito através da definição de uma função que é
// chamado sempre que o operador é usado.
#include <iostream>
using namespace std;
class Point {
public:
// Variáveis membro pode ser dado valores padrão desta maneira.
double x = 0;
double y = 0;
// Define um construtor padrão que não faz nada
// mas inicializar o Point para o valor padrão (0, 0)
Point() { };
// A sintaxe a seguir é conhecido como uma lista de inicialização
// e é a maneira correta de inicializar os valores de membro de classe
Point (double a, double b) :
x(a),
y(b)
{ /* Não fazer nada, exceto inicializar os valores */ }
// Sobrecarrega o operador +.
Point operator+(const Point& rhs) const;
// Sobrecarregar o operador +=.
Point& operator+=(const Point& rhs);
// Ele também faria sentido para adicionar os operadores - e -=,
// mas vamos pular para sermos breves.
};
Point Point::operator+(const Point& rhs) const
{
// Criar um novo ponto que é a soma de um e rhs.
return Point(x + rhs.x, y + rhs.y);
}
Point& Point::operator+=(const Point& rhs)
{
x += rhs.x;
y += rhs.y;
return *this;
}
int main () {
Point up (0,1);
Point right (1,0);
// Isto chama que o operador ponto +
// Ressalte-se a chamadas (função)+ com direito como seu parâmetro...
Point result = up + right;
// Imprime "Result is upright (1,1)"
cout << "Result is upright (" << result.x << ',' << result.y << ")\n";
return 0;
}
/////////////////////////
// Tratamento de Exceções
/////////////////////////
// A biblioteca padrão fornece alguns tipos de exceção
// (see http://en.cppreference.com/w/cpp/error/exception)
// mas qualquer tipo pode ser jogado como uma exceção
#include <exception>
// Todas as exceções lançadas dentro do bloco try pode ser capturado por
// manipuladores de captura subseqüentes
try {
// Não aloca exceções no heap usando _new_.
throw std::exception("A problem occurred");
}
// Capturar exceções por referência const se eles são objetos
catch (const std::exception& ex)
{
std::cout << ex.what();
// Captura qualquer exceção não capturada pelos blocos _catch_ anteriores
} catch (...)
{
std::cout << "Exceção desconhecida encontrada";
throw; // Re-lança a exceção
}
///////
// RAII
///////
// RAII significa alocação de recursos é de inicialização.
// Muitas vezes, é considerado o paradigma mais poderoso em C++, e é o
// conceito simples que um construtor para um objeto adquire recursos daquele
// objeto e o destruidor liberá-los.
// Para entender como isso é útil,
// Considere uma função que usa um identificador de arquivo C:
void doSomethingWithAFile(const char* filename)
{
// Para começar, assuma que nada pode falhar.
FILE* fh = fopen(filename, "r"); // Abra o arquivo em modo de leitura.
doSomethingWithTheFile(fh);
doSomethingElseWithIt(fh);
fclose(fh); // Feche o arquivo.
}
// Infelizmente, as coisas são levemente complicadas para tratamento de erros.
// Suponha que fopen pode falhar, e que doSomethingWithTheFile e
// doSomethingElseWithIt retornam códigos de erro se eles falharem. (As
// exceções são a forma preferida de lidar com o fracasso, mas alguns
// programadores, especialmente aqueles com um conhecimento em C, discordam
// sobre a utilidade de exceções). Agora temos que verificar cada chamada para
// o fracasso e fechar o identificador de arquivo se ocorreu um problema.
bool doSomethingWithAFile(const char* filename)
{
FILE* fh = fopen(filename, "r"); // Abra o arquivo em modo de leitura
if (fh == nullptr) // O ponteiro retornado é nulo em caso de falha.
reuturn false; // Relate o fracasso para o chamador.
// Suponha cada função retorne false, se falhar
if (!doSomethingWithTheFile(fh)) {
fclose(fh); // Feche o identificador de arquivo para que ele não vaze.
return false; // Propague o erro.
}
if (!doSomethingElseWithIt(fh)) {
fclose(fh); // Feche o identificador de arquivo para que ele não vaze.
return false; // Propague o erro.
}
fclose(fh); // Feche o identificador de arquivo para que ele não vaze.
return true; // Indica sucesso
}
// Programadores C frequentemente limpam isso um pouco usando Goto:
bool doSomethingWithAFile(const char* filename)
{
FILE* fh = fopen(filename, "r");
if (fh == nullptr)
reuturn false;
if (!doSomethingWithTheFile(fh))
goto failure;
if (!doSomethingElseWithIt(fh))
goto failure;
fclose(fh); // Close the file
return true; // Indica sucesso
failure:
fclose(fh);
return false; // Propague o erro.
}
// Se as funções indicam erros usando exceções,
// as coisas são um pouco mais limpo, mas ainda abaixo do ideal.
void doSomethingWithAFile(const char* filename)
{
FILE* fh = fopen(filename, "r"); // Abra o arquivo em modo de leitura.
if (fh == nullptr)
throw std::exception("Não pode abrir o arquivo.");
try {
doSomethingWithTheFile(fh);
doSomethingElseWithIt(fh);
}
catch (...) {
fclose(fh); // Certifique-se de fechar o arquivo se ocorrer um erro.
throw; // Em seguida, re-lance a exceção.
}
fclose(fh); // Feche o arquivo
// Tudo ocorreu com sucesso!
}
// Compare isso com o uso de C++ classe fluxo de arquivo (fstream) fstream usa
// seu destruidor para fechar o arquivo. Lembre-se de cima que destruidores são
// automaticamente chamado sempre que um objeto cai fora do âmbito.
void doSomethingWithAFile(const std::string& filename)
{
// ifstream é curto para o fluxo de arquivo de entrada
std::ifstream fh(filename); // Abra o arquivo
// faça alguma coisa com o arquivo
doSomethingWithTheFile(fh);
doSomethingElseWithIt(fh);
} // O arquivo é automaticamente fechado aqui pelo destructor
// Isto tem _grandes_ vantagens:
// 1. Não importa o que aconteça,
// o recurso (neste caso, o identificador de ficheiro) irá ser limpo.
// Depois de escrever o destruidor corretamente,
// É _impossível_ esquecer de fechar e vazar o recurso
// 2. Nota-se que o código é muito mais limpo.
// As alças destructor fecham o arquivo por trás das cenas
// sem que você precise se preocupar com isso.
// 3. O código é seguro de exceção.
// Uma exceção pode ser jogado em qualquer lugar na função e a limpeza
// irá ainda ocorrer.
// Todos códigos C++ usam RAII extensivamente para todos os recursos.
// Outros exemplos incluem
// - Memória usa unique_ptr e shared_ptr
// - Contentores - a lista da biblioteca ligada padrão,
// vetor (i.e. array de autodimensionamento), mapas hash, e assim por diante
// tudo é automaticamente destruído quando eles saem de escopo
// - Mutex usa lock_guard e unique_lock
```
Leitura Adicional:
Uma referência atualizada da linguagem pode ser encontrada em
<http://cppreference.com/w/cpp>
Uma fonte adicional pode ser encontrada em <http://cplusplus.com>

View File

@ -0,0 +1,384 @@
---
language: clojure
filename: learnclojure-pt.clj
contributors:
- ["Adam Bard", "http://adambard.com/"]
translators:
- ["Mariane Siqueira Machado", "https://twitter.com/mariane_sm"]
lang: pt-br
---
Clojure é uma linguagem da família do Lisp desenvolvida para a JVM (máquina virtual Java). Possui uma ênfase muito mais forte em [programação funcional] (https://pt.wikipedia.org/wiki/Programa%C3%A7%C3%A3o_funcional) pura do que Common Lisp, mas inclui diversas utilidades [STM](https://en.wikipedia.org/wiki/Software_transactional_memory) para lidar com estado a medida que isso se torna necessário.
Essa combinação permite gerenciar processamento concorrente de maneira muito simples, e frequentemente de maneira automática.
(Sua versão de clojure precisa ser pelo menos 1.2)
```clojure
; Comentários começam por ponto e vírgula
; Clojure é escrito em "forms", os quais são simplesmente
; listas de coisas dentro de parênteses, separados por espaços em branco.
; O "reader" (leitor) de Clojure presume que o primeiro elemento de
; uma par de parênteses é uma função ou macro, e que os resto são argumentos.
: A primeira chamada de um arquivo deve ser ns, para configurar o namespace (espaço de nomes)
(ns learnclojure)
; Alguns exemplos básicos:
; str cria uma string concatenando seus argumentos
(str "Hello" " " "World") ; => "Hello World"
; Cálculos são feitos de forma direta e intuitiva
(+ 1 1) ; => 2
(- 2 1) ; => 1
(* 1 2) ; => 2
(/ 2 1) ; => 2
; Você pode comparar igualdade utilizando =
(= 1 1) ; => true
(= 2 1) ; => false
; Negação para operações lógicas
(not true) ; => false
; Aninhar "forms" funciona como esperado
(+ 1 (- 3 2)) ; = 1 + (3 - 2) => 2
; Tipos
;;;;;;;;;;;;;
; Clojure usa os tipos de objetos de Java para booleanos, strings e números.
; Use `class` para inspecioná-los
(class 1) ; Literais Integer são java.lang.Long por padrão
(class 1.); Literais Float são java.lang.Double
(class ""); Strings são sempre com aspas duplas, e são java.lang.String
(class false) ; Booleanos são java.lang.Boolean
(class nil); O valor "null" é chamado nil
; Se você quiser criar um lista de literais, use aspa simples para
; ela não ser avaliada
'(+ 1 2) ; => (+ 1 2)
; (que é uma abreviação de (quote (+ 1 2)))
; É possível avaliar uma lista com aspa simples
(eval '(+ 1 2)) ; => 3
; Coleções e sequências
;;;;;;;;;;;;;;;;;;;
; Listas são estruturas encadeadas, enquanto vetores são implementados como arrays.
; Listas e Vetores são classes Java também!
(class [1 2 3]); => clojure.lang.PersistentVector
(class '(1 2 3)); => clojure.lang.PersistentList
; Uma lista é escrita como (1 2 3), mas temos que colocar a aspa
; simples para impedir o leitor (reader) de pensar que é uma função.
; Também, (list 1 2 3) é o mesmo que '(1 2 3)
; "Coleções" são apenas grupos de dados
; Listas e vetores são ambos coleções:
(coll? '(1 2 3)) ; => true
(coll? [1 2 3]) ; => true
; "Sequências" (seqs) são descrições abstratas de listas de dados.
; Apenas listas são seqs.
(seq? '(1 2 3)) ; => true
(seq? [1 2 3]) ; => false
; Um seq precisa apenas prover uma entrada quando é acessada.
; Portanto, já que seqs podem ser avaliadas sob demanda (lazy) -- elas podem definir séries infinitas:
(range 4) ; => (0 1 2 3)
(range) ; => (0 1 2 3 4 ...) (uma série infinita)
(take 4 (range)) ; (0 1 2 3)
; Use cons para adicionar um item no início de uma lista ou vetor
(cons 4 [1 2 3]) ; => (4 1 2 3)
(cons 4 '(1 2 3)) ; => (4 1 2 3)
; Conj adiciona um item em uma coleção sempre do jeito mais eficiente.
; Para listas, elas inserem no início. Para vetores, é inserido no final.
(conj [1 2 3] 4) ; => [1 2 3 4]
(conj '(1 2 3) 4) ; => (4 1 2 3)
; Use concat para concatenar listas e vetores
(concat [1 2] '(3 4)) ; => (1 2 3 4)
; Use filter, map para interagir com coleções
(map inc [1 2 3]) ; => (2 3 4)
(filter even? [1 2 3]) ; => (2)
; Use reduce para reduzi-los
(reduce + [1 2 3 4])
; = (+ (+ (+ 1 2) 3) 4)
; => 10
; Reduce pode receber um argumento para o valor inicial
(reduce conj [] '(3 2 1))
; = (conj (conj (conj [] 3) 2) 1)
; => [3 2 1]
; Funções
;;;;;;;;;;;;;;;;;;;;;
; Use fn para criar novas funções. Uma função sempre retorna
; sua última expressão.
(fn [] "Hello World") ; => fn
; (É necessário colocar parênteses para chamá-los)
((fn [] "Hello World")) ; => "Hello World"
; Você pode atribuir valores a variáveis utilizando def
(def x 1)
x ; => 1
; Atribua uma função para uma var
(def hello-world (fn [] "Hello World"))
(hello-world) ; => "Hello World"
; Você pode abreviar esse processo usando defn
(defn hello-world [] "Hello World")
; O [] é uma lista de argumentos para um função.
(defn hello [name]
(str "Hello " name))
(hello "Steve") ; => "Hello Steve"
; Você pode ainda usar essa abreviação para criar funcões:
(def hello2 #(str "Hello " %1))
(hello2 "Fanny") ; => "Hello Fanny"
; Vocé pode ter funções multi-variadic, isto é, com um número variável de argumentos
(defn hello3
([] "Hello World")
([name] (str "Hello " name)))
(hello3 "Jake") ; => "Hello Jake"
(hello3) ; => "Hello World"
; Funções podem agrupar argumentos extras em uma seq
(defn count-args [& args]
(str "You passed " (count args) " args: " args))
(count-args 1 2 3) ; => "You passed 3 args: (1 2 3)"
; Você pode misturar argumentos regulares e argumentos em seq
(defn hello-count [name & args]
(str "Hello " name ", you passed " (count args) " extra args"))
(hello-count "Finn" 1 2 3)
; => "Hello Finn, you passed 3 extra args"
; Mapas
;;;;;;;;;;
; Hash maps e array maps compartilham uma mesma interface. Hash maps são mais
; rápidos para pesquisa mas não mantém a ordem da chave.
(class {:a 1 :b 2 :c 3}) ; => clojure.lang.PersistentArrayMap
(class (hash-map :a 1 :b 2 :c 3)) ; => clojure.lang.PersistentHashMap
; Arraymaps pode automaticamente se tornar hashmaps através da maioria das
; operações se eles ficarem grandes o suficiente, portanto não há necessida de
; se preocupar com isso.
;Mapas podem usar qualquer valor que se pode derivar um hash como chave
; Mapas podem usar qualquer valor em que se pode derivar um hash como chave,
; mas normalmente palavras-chave (keywords) são melhores.
; Keywords são como strings mas com algumas vantagens.
(class :a) ; => clojure.lang.Keyword
(def stringmap {"a" 1, "b" 2, "c" 3})
stringmap ; => {"a" 1, "b" 2, "c" 3}
(def keymap {:a 1, :b 2, :c 3})
keymap ; => {:a 1, :c 3, :b 2}
; A propósito, vírgulas são sempre tratadas como espaçoes em branco e não fazem nada.
; Recupere o valor de um mapa chamando ele como uma função
(stringmap "a") ; => 1
(keymap :a) ; => 1
; Uma palavra-chave pode ser usada pra recuperar os valores de um mapa
(:b keymap) ; => 2
; Não tente isso com strings
;("a" stringmap)
; => Exception: java.lang.String cannot be cast to clojure.lang.IFn
; Buscar uma chave não presente retorna nil
(stringmap "d") ; => nil
; Use assoc para adicionar novas chaves para hash-maps
(def newkeymap (assoc keymap :d 4))
newkeymap ; => {:a 1, :b 2, :c 3, :d 4}
; Mas lembre-se, tipos em Clojure são sempre imutáveis!
keymap ; => {:a 1, :b 2, :c 3}
; Use dissoc para remover chaves
(dissoc keymap :a :b) ; => {:c 3}
; Conjuntos
;;;;;;
(class #{1 2 3}) ; => clojure.lang.PersistentHashSet
(set [1 2 3 1 2 3 3 2 1 3 2 1]) ; => #{1 2 3}
; Adicione um membro com conj
(conj #{1 2 3} 4) ; => #{1 2 3 4}
; Remova um membro com disj
(disj #{1 2 3} 1) ; => #{2 3}
; Test por existência usando set como função:
(#{1 2 3} 1) ; => 1
(#{1 2 3} 4) ; => nil
; Existem muitas outras funções no namespace clojure.sets
; Forms úteis
;;;;;;;;;;;;;;;;;
; Construções lógicas em Clojure são como macros, e
; se parecem com as demais
(if false "a" "b") ; => "b"
(if false "a") ; => nil
; Use let para criar um novo escopo associando sîmbolos a valores (bindings)
(let [a 1 b 2]
(> a b)) ; => false
; Agrupe comandos juntos com "do"
(do
(print "Hello")
"World") ; => "World" (prints "Hello")
; Funções tem um do implícito
(defn print-and-say-hello [name]
(print "Saying hello to " name)
(str "Hello " name))
(print-and-say-hello "Jeff") ;=> "Hello Jeff" (prints "Saying hello to Jeff")
; Assim como let
(let [name "Urkel"]
(print "Saying hello to " name)
(str "Hello " name)) ; => "Hello Urkel" (prints "Saying hello to Urkel")
; Módulos
;;;;;;;;;;;;;;;
; Use "use" para poder usar todas as funções de um modulo
(use 'clojure.set)
; Agora nós podemos usar operações com conjuntos
(intersection #{1 2 3} #{2 3 4}) ; => #{2 3}
(difference #{1 2 3} #{2 3 4}) ; => #{1}
; Você pode escolher um subconjunto de funções para importar
(use '[clojure.set :only [intersection]])
; Use require para importar um módulo
(require 'clojure.string)
; Use / para chamar funções de um módulo
; Aqui, o módulo é clojure.string e a função é blank?
(clojure.string/blank? "") ; => true
; Você pode dar para um módulo um nome mais curto no import
(require '[clojure.string :as str])
(str/replace "This is a test." #"[a-o]" str/upper-case) ; => "THIs Is A tEst."
; (#"" denota uma expressão regular literal)
; Você pode usar require (e até "use", mas escolha require) de um namespace utilizando :require.
; Não é necessário usar aspa simples nos seus módulos se você usar desse jeito.
(ns test
(:require
[clojure.string :as str]
[clojure.set :as set]))
; Java
;;;;;;;;;;;;;;;;;
; Java tem uma biblioteca padrão enorme e muito útil,
; portanto é importante aprender como utiliza-la.
; Use import para carregar um modulo java
(import java.util.Date)
; Você pode importar usando ns também.
(ns test
(:import java.util.Date
java.util.Calendar))
; Use o nome da clase com um "." no final para criar uma nova instância
(Date.) ; <a date object>
; Use . para chamar métodos. Ou, use o atalho ".method"
(. (Date.) getTime) ; <a timestamp>
(.getTime (Date.)) ; exatamente a mesma coisa.
; Use / para chamar métodos estáticos
(System/currentTimeMillis) ; <a timestamp> (o módulo System está sempre presente)
; Use doto para pode lidar com classe (mutáveis) de forma mais tolerável
(import java.util.Calendar)
(doto (Calendar/getInstance)
(.set 2000 1 1 0 0 0)
.getTime) ; => A Date. set to 2000-01-01 00:00:00
; STM
;;;;;;;;;;;;;;;;;
; Software Transactional Memory é o mecanismo que Clojure usa para gerenciar
; estado persistente. Tem algumas construções em Clojure que o utilizam.
; O atom é o mais simples. Passe pra ele um valor inicial
(def my-atom (atom {}))
; Atualize o atom com um swap!.
; swap! pega uma funçnao and chama ela com o valor atual do atom
; como primeiro argumento, e qualquer argumento restante como o segundo
(swap! my-atom assoc :a 1) ; Coloca o valor do átomo my-atom como o resultado de (assoc {} :a 1)
(swap! my-atom assoc :b 2) ; Coloca o valor do átomo my-atom como o resultado de (assoc {:a 1} :b 2)
; Use '@' para desreferenciar um atom e acessar seu valor
my-atom ;=> Atom<#...> (Retorna o objeto do Atom)
@my-atom ; => {:a 1 :b 2}
; Abaixo um contador simples usando um atom
(def counter (atom 0))
(defn inc-counter []
(swap! counter inc))
(inc-counter)
(inc-counter)
(inc-counter)
(inc-counter)
(inc-counter)
@counter ; => 5
; Outras construção STM são refs e agents.
; Refs: http://clojure.org/refs
; Agents: http://clojure.org/agents
```
### Leitura adicional
Esse tutorial está longe de ser exaustivo, mas deve ser suficiente para que você possa começar.
Clojure.org tem vários artigos:
[http://clojure.org/](http://clojure.org/)
Clojuredocs.org tem documentação com exemplos para quase todas as funções principais (pertecentes ao core):
[http://clojuredocs.org/quickref/Clojure%20Core](http://clojuredocs.org/quickref/Clojure%20Core)
4Clojure é um grande jeito de aperfeiçoar suas habilidades em Clojure/Programação Funcional:
[http://www.4clojure.com/](http://www.4clojure.com/)
Clojure-doc.org tem um bom número de artigos para iniciantes:
[http://clojure-doc.org/](http://clojure-doc.org/)

View File

@ -0,0 +1,622 @@
---
language: "Common Lisp"
filename: commonlisp-pt.lisp
contributors:
- ["Paul Nathan", "https://github.com/pnathan"]
translators:
- ["Édipo Luis Féderle", "https://github.com/edipofederle"]
lang: pt-br
---
ANSI Common Lisp é uma linguagem de uso geral, multi-paradigma, designada
para uma variedade de aplicações na indústria. É frequentemente citada
como uma linguagem de programação programável.
O ponto inicial clássico é [Practical Common Lisp e livremente disponível](http://www.gigamonkeys.com/book/)
Outro livro recente e popular é o
[Land of Lisp](http://landoflisp.com/).
```common_lisp
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; 0. Sintaxe
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; "Form" Geral
;; Lisp tem dois pedaços fundamentais de sintaxe: o ATOM e S-expression.
;; Tipicamente, S-expressions agrupadas são chamadas de `forms`.
10 ; um atom; é avaliado para ele mesmo
:THING ;Outro atom; avaliado para o símbolo :thing.
t ; outro atom, denotado true.
(+ 1 2 3 4) ; uma s-expression
'(4 :foo t) ;outra s-expression
;;; Comentários
;; Comentários de uma única linha começam com ponto e vírgula; usar dois para
;; comentários normais, três para comentários de seção, e quadro para comentários
;; em nível de arquivo.
#| Bloco de comentário
pode abranger várias linhas e...
#|
eles podem ser aninhados
|#
|#
;;; Ambiente
;; Existe uma variedade de implementações; a maioria segue o padrão.
;; CLISP é um bom ponto de partida.
;; Bibliotecas são gerenciadas através do Quicklisp.org's Quicklisp sistema.
;; Common Lisp é normalmente desenvolvido com um editor de texto e um REPL
;; (Read Evaluate Print Loop) rodando ao mesmo tempo. O REPL permite exploração
;; interativa do programa como ele é "ao vivo" no sistema.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; 1. Tipos Primitivos e Operadores
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Símbolos
'foo ; => FOO Perceba que um símbolo é automáticamente convertido para maiúscula.
;; Intern manualmente cria um símbolo a partir de uma string.
(intern "AAAA") ; => AAAA
(intern "aaa") ; => |aaa|
;;; Números
9999999999999999999999 ; inteiro
#b111 ; binário => 7
#o111 ; octal => 73
#x111 ; hexadecimal => 273
3.14159s0 ; single
3.14159d0 ; double
1/2 ; ratios
#C(1 2) ; números complexos
;; Funções são escritas como (f x y z ...)
;; onde f é uma função e x, y, z, ... são operadores
;; Se você quiser criar uma lista literal de dados, use ' para evitar
;; que a lista seja avaliada - literalmente, "quote" os dados.
'(+ 1 2) ; => (+ 1 2)
;; Você também pode chamar uma função manualmente:
(funcall #'+ 1 2 3) ; => 6
;; O mesmo para operações aritiméticas
(+ 1 1) ; => 2
(- 8 1) ; => 7
(* 10 2) ; => 20
(expt 2 3) ; => 8
(mod 5 2) ; => 1
(/ 35 5) ; => 7
(/ 1 3) ; => 1/3
(+ #C(1 2) #C(6 -4)) ; => #C(7 -2)
;;; Booleans
t ; para true (qualquer valor não nil é true)
nil ; para false - e para lista vazia
(not nil) ; => t
(and 0 t) ; => t
(or 0 nil) ; => 0
;;; Caracteres
#\A ; => #\A
#\λ ; => #\GREEK_SMALL_LETTER_LAMDA
#\u03BB ; => #\GREEK_SMALL_LETTER_LAMDA
;;; String são arrays de caracteres com tamanho fixo.
"Hello, world!"
"Benjamin \"Bugsy\" Siegel" ; barra é um escape de caracter
;; String podem ser concatenadas também!
(concatenate 'string "Hello " "world!") ; => "Hello world!"
;; Uma String pode ser tratada como uma sequência de caracteres
(elt "Apple" 0) ; => #\A
;; format pode ser usado para formatar strings
(format nil "~a can be ~a" "strings" "formatted")
;; Impimir é bastante fácil; ~% indica nova linha
(format t "Common Lisp is groovy. Dude.~%")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 2. Variáveis
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Você pode criar uma global (escopo dinâmico) usando defparameter
;; um nome de variável pode conter qualquer caracter, exceto: ()",'`;#|\
;; Variáveis de escopo dinâmico devem ter asteriscos em seus nomes!
(defparameter *some-var* 5)
*some-var* ; => 5
;; Você pode usar caracteres unicode também.
(defparameter *AΛB* nil)
;; Acessando uma variável anteriormente não ligada é um
;; comportamento não definido (mas possível). Não faça isso.
;; Ligação local: `me` é vinculado com "dance with you" somente dentro
;; de (let ... ). Let permite retornar o valor do último `form` no form let.
(let ((me "dance with you"))
me)
;; => "dance with you"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 3. Estruturas e Coleções
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Estruturas
(defstruct dog name breed age)
(defparameter *rover*
(make-dog :name "rover"
:breed "collie"
:age 5))
*rover* ; => #S(DOG :NAME "rover" :BREED "collie" :AGE 5)
(dog-p *rover*) ; => t ;; ewww)
(dog-name *rover*) ; => "rover"
;; Dog-p, make-dog, e dog-name foram todas criadas por defstruct!
;;; Pares
;; `cons' constroi pares, `car' and `cdr' extrai o primeiro
;; e o segundo elemento
(cons 'SUBJECT 'VERB) ; => '(SUBJECT . VERB)
(car (cons 'SUBJECT 'VERB)) ; => SUBJECT
(cdr (cons 'SUBJECT 'VERB)) ; => VERB
;;; Listas
;; Listas são estruturas de dados do tipo listas encadeadas, criadas com `cons'
;; pares e terminam `nil' (ou '()) para marcar o final da lista
(cons 1 (cons 2 (cons 3 nil))) ; => '(1 2 3)
;; `list' é um construtor conveniente para listas
(list 1 2 3) ; => '(1 2 3)
;; e a quote (') também pode ser usado para um valor de lista literal
'(1 2 3) ; => '(1 2 3)
;; Ainda pode-se usar `cons' para adicionar um item no começo da lista.
(cons 4 '(1 2 3)) ; => '(4 1 2 3)
;; Use `append' para - surpreendentemente - juntar duas listas
(append '(1 2) '(3 4)) ; => '(1 2 3 4)
;; Ou use concatenate -
(concatenate 'list '(1 2) '(3 4))
;; Listas são um tipo muito central, então existe uma grande variedade de
;; funcionalidades para eles, alguns exemplos:
(mapcar #'1+ '(1 2 3)) ; => '(2 3 4)
(mapcar #'+ '(1 2 3) '(10 20 30)) ; => '(11 22 33)
(remove-if-not #'evenp '(1 2 3 4)) ; => '(2 4)
(every #'evenp '(1 2 3 4)) ; => nil
(some #'oddp '(1 2 3 4)) ; => T
(butlast '(subject verb object)) ; => (SUBJECT VERB)
;;; Vetores
;; Vector's literais são arrays de tamanho fixo.
#(1 2 3) ; => #(1 2 3)
;; Use concatenate para juntar dois vectors
(concatenate 'vector #(1 2 3) #(4 5 6)) ; => #(1 2 3 4 5 6)
;;; Arrays
;; Ambos vetores e strings são um caso especial de arrays.
;; 2D arrays
(make-array (list 2 2))
;; (make-array '(2 2)) também funciona.
; => #2A((0 0) (0 0))
(make-array (list 2 2 2))
; => #3A(((0 0) (0 0)) ((0 0) (0 0)))
;; Cuidado - os valores de inicialição padrões são
;; definidos pela implementção. Aqui vai como defini-lós.
(make-array '(2) :initial-element 'unset)
; => #(UNSET UNSET)
;; E, para acessar o element em 1,1,1 -
(aref (make-array (list 2 2 2)) 1 1 1)
; => 0
;;; Vetores Ajustáveis
;; Vetores ajustáveis tem a mesma representação impressa que os vectores
;; de tamanho fixo
(defparameter *adjvec* (make-array '(3) :initial-contents '(1 2 3)
:adjustable t :fill-pointer t))
*adjvec* ; => #(1 2 3)
;; Adicionando novo elemento
(vector-push-extend 4 *adjvec*) ; => 3
*adjvec* ; => #(1 2 3 4)
;;; Ingenuamente, conjuntos são apenas listas:
(set-difference '(1 2 3 4) '(4 5 6 7)) ; => (3 2 1)
(intersection '(1 2 3 4) '(4 5 6 7)) ; => 4
(union '(1 2 3 4) '(4 5 6 7)) ; => (3 2 1 4 5 6 7)
(adjoin 4 '(1 2 3 4)) ; => (1 2 3 4)
;; Mas você irá querer usar uma estrutura de dados melhor que uma lista encadeada.
;; para performance.
;;; Dicionários são implementados como hash tables
;; Cria um hash table
(defparameter *m* (make-hash-table))
;; seta um valor
(setf (gethash 'a *m*) 1)
;; Recupera um valor
(gethash 'a *m*) ; => 1, t
;; Detalhe - Common Lisp tem multiplos valores de retorno possíveis. gethash
;; retorna t no segundo valor se alguma coisa foi encontrada, e nil se não.
;; Recuperando um valor não presente retorna nil
(gethash 'd *m*) ;=> nil, nil
;; Você pode fornecer um valor padrão para uma valores não encontrados
(gethash 'd *m* :not-found) ; => :NOT-FOUND
;; Vamos tratas múltiplos valores de rotorno aqui.
(multiple-value-bind
(a b)
(gethash 'd *m*)
(list a b))
; => (NIL NIL)
(multiple-value-bind
(a b)
(gethash 'a *m*)
(list a b))
; => (1 T)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 3. Funções
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Use `lambda' para criar funções anônimas
;; Uma função sempre retorna um valor da última expressão avaliada.
;; A representação exata impressão de uma função varia de acordo ...
(lambda () "Hello World") ; => #<FUNCTION (LAMBDA ()) {1004E7818B}>
;; Use funcall para chamar uma função lambda.
(funcall (lambda () "Hello World")) ; => "Hello World"
;; Ou Apply
(apply (lambda () "Hello World") nil) ; => "Hello World"
;; "De-anonymize" a função
(defun hello-world ()
"Hello World")
(hello-world) ; => "Hello World"
;; O () acima é a lista de argumentos da função.
(defun hello (name)
(format nil "Hello, ~a " name))
(hello "Steve") ; => "Hello, Steve"
;; Funções podem ter argumentos opcionais; eles são nil por padrão
(defun hello (name &optional from)
(if from
(format t "Hello, ~a, from ~a" name from)
(format t "Hello, ~a" name)))
(hello "Jim" "Alpacas") ;; => Hello, Jim, from Alpacas
;; E os padrões podem ser configurados...
(defun hello (name &optional (from "The world"))
(format t "Hello, ~a, from ~a" name from))
(hello "Steve")
; => Hello, Steve, from The world
(hello "Steve" "the alpacas")
; => Hello, Steve, from the alpacas
;; E é claro, palavras-chaves são permitidas também... frequentemente mais
;; flexivel que &optional.
(defun generalized-greeter (name &key (from "the world") (honorific "Mx"))
(format t "Hello, ~a ~a, from ~a" honorific name from))
(generalized-greeter "Jim") ; => Hello, Mx Jim, from the world
(generalized-greeter "Jim" :from "the alpacas you met last summer" :honorific "Mr")
; => Hello, Mr Jim, from the alpacas you met last summer
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 4. Igualdade
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Common Lisp tem um sistema sofisticado de igualdade. Alguns são cobertos aqui.
;; Para número use `='
(= 3 3.0) ; => t
(= 2 1) ; => nil
;; para identidade de objeto (aproximadamente) use `eql`
(eql 3 3) ; => t
(eql 3 3.0) ; => nil
(eql (list 3) (list 3)) ; => nil
;; para listas, strings, e para pedaços de vetores use `equal'
(equal (list 'a 'b) (list 'a 'b)) ; => t
(equal (list 'a 'b) (list 'b 'a)) ; => nil
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 5. Fluxo de Controle
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Condicionais
(if t ; testa a expressão
"this is true" ; então expressão
"this is false") ; senão expressão
; => "this is true"
;; Em condicionais, todos valores não nulos são tratados como true
(member 'Groucho '(Harpo Groucho Zeppo)) ; => '(GROUCHO ZEPPO)
(if (member 'Groucho '(Harpo Groucho Zeppo))
'yep
'nope)
; => 'YEP
;; `cond' encadeia uma série de testes para selecionar um resultado
(cond ((> 2 2) (error "wrong!"))
((< 2 2) (error "wrong again!"))
(t 'ok)) ; => 'OK
;; Typecase é um condicional que escolhe uma de seus cláusulas com base do tipo
;; do seu valor
(typecase 1
(string :string)
(integer :int))
; => :int
;;; Interação
;; Claro que recursão é suportada:
(defun walker (n)
(if (zerop n)
:walked
(walker (1- n))))
(walker 5) ; => :walked
;; Na maioria das vezes, nós usamos DOTLISO ou LOOP
(dolist (i '(1 2 3 4))
(format t "~a" i))
; => 1234
(loop for i from 0 below 10
collect i)
; => (0 1 2 3 4 5 6 7 8 9)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 6. Mutação
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Use `setf' para atribuir um novo valor para uma variável existente. Isso foi
;; demonstrado anteriormente no exemplo da hash table.
(let ((variable 10))
(setf variable 2))
; => 2
;; Um bom estilo Lisp é para minimizar funções destrutivas e para evitar
;; mutação quando razoável.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 7. Classes e Objetos
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Sem clases Animal, vamos usar os veículos de transporte de tração
;; humana mecânicos.
(defclass human-powered-conveyance ()
((velocity
:accessor velocity
:initarg :velocity)
(average-efficiency
:accessor average-efficiency
:initarg :average-efficiency))
(:documentation "A human powered conveyance"))
;; defcalss, seguido do nome, seguido por uma list de superclass,
;; seguido por um uma 'slot list', seguido por qualidades opcionais como
;; :documentation
;; Quando nenhuma lista de superclasse é setada, uma lista padrão para
;; para o objeto padrão é usada. Isso *pode* ser mudado, mas não até você
;; saber o que está fazendo. Olhe em Art of the Metaobject Protocol
;; para maiores informações.
(defclass bicycle (human-powered-conveyance)
((wheel-size
:accessor wheel-size
:initarg :wheel-size
:documentation "Diameter of the wheel.")
(height
:accessor height
:initarg :height)))
(defclass recumbent (bicycle)
((chain-type
:accessor chain-type
:initarg :chain-type)))
(defclass unicycle (human-powered-conveyance) nil)
(defclass canoe (human-powered-conveyance)
((number-of-rowers
:accessor number-of-rowers
:initarg :number-of-rowers)))
;; Chamando DESCRIBE na classe human-powered-conveyance no REPL dá:
(describe 'human-powered-conveyance)
; COMMON-LISP-USER::HUMAN-POWERED-CONVEYANCE
; [symbol]
;
; HUMAN-POWERED-CONVEYANCE names the standard-class #<STANDARD-CLASS
; HUMAN-POWERED-CONVEYANCE>:
; Documentation:
; A human powered conveyance
; Direct superclasses: STANDARD-OBJECT
; Direct subclasses: UNICYCLE, BICYCLE, CANOE
; Not yet finalized.
; Direct slots:
; VELOCITY
; Readers: VELOCITY
; Writers: (SETF VELOCITY)
; AVERAGE-EFFICIENCY
; Readers: AVERAGE-EFFICIENCY
; Writers: (SETF AVERAGE-EFFICIENCY)
;; Note o comportamento reflexivo disponível para você! Common Lisp é
;; projetada para ser um sistema interativo.
;; Para definir um métpdo, vamos encontrar o que nossa cirunferência da
;; roda da bicicleta usando a equação: C = d * pi
(defmethod circumference ((object bicycle))
(* pi (wheel-size object)))
;; pi já é definido para a gente em Lisp!
;; Vamos supor que nós descobrimos que o valor da eficiência do número
;; de remadores em uma canoa é aproximadamente logarítmica. Isso provavelmente
;; deve ser definido no construtor / inicializador.
;; Veja como initializar sua instância após Common Lisp ter construído isso:
(defmethod initialize-instance :after ((object canoe) &rest args)
(setf (average-efficiency object) (log (1+ (number-of-rowers object)))))
;; Em seguida, para a construção de uma ocorrência e verificar a eficiência média ...
(average-efficiency (make-instance 'canoe :number-of-rowers 15))
; => 2.7725887
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 8. Macros
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Macros permitem que você estenda a sintaxe da lingaugem
;; Common Lisp não vem com um loop WHILE - vamos adicionar um.
;; Se obedecermos nossos instintos 'assembler', acabamos com:
(defmacro while (condition &body body)
"Enquanto `condition` é verdadeiro, `body` é executado.
`condition` é testado antes de cada execução do `body`"
(let ((block-name (gensym)))
`(tagbody
(unless ,condition
(go ,block-name))
(progn
,@body)
,block-name)))
;; Vamos dar uma olhada em uma versão alto nível disto:
(defmacro while (condition &body body)
"Enquanto `condition` for verdadeira, `body` é executado.
`condition` é testado antes de cada execução do `body`"
`(loop while ,condition
do
(progn
,@body)))
;; Entretanto, com um compilador moderno, isso não é preciso; o LOOP
;; 'form' compila igual e é bem mais fácil de ler.
;; Noteq ue ``` é usado , bem como `,` e `@`. ``` é um operador 'quote-type'
;; conhecido como 'quasiquote'; isso permite o uso de `,` . `,` permite "unquoting"
;; e variáveis. @ interpolará listas.
;; Gensym cria um símbolo único garantido que não existe em outras posições
;; o sistema. Isto é porque macros são expandidas em tempo de compilação e
;; variáveis declaradas na macro podem colidir com as variáveis usadas na
;; código regular.
;; Veja Practical Common Lisp para maiores informações sobre macros.
```
## Leitura Adicional
[Continua em frente com Practical Common Lisp book.](http://www.gigamonkeys.com/book/)
## Créditos
Muitos agradecimentos ao pessoal de Schema por fornecer um grande ponto de partida
o que facilitou muito a migração para Common Lisp.
- [Paul Khuong](https://github.com/pkhuong) pelas grandes revisões.

View File

@ -1,110 +1,119 @@
---
category: tool
tool: git
lang: pt-br
filename: LearnGit.txt
contributors:
- ["Jake Prather", "http://github.com/JakeHP"]
translators:
- ["Miguel Araújo", "https://github.com/miguelarauj1o"]
lang: pt-br
filename: learngit-pt.txt
- ["Suzane Sant Ana", "http://github.com/suuuzi"]
---
Git é um sistema de controle de versão distribuído e de gerenciamento de código-fonte.
Git é um sistema distribuido de gestão para código fonte e controle de versões.
Ele faz isso através de uma série de momentos instantâneos de seu projeto, e ele funciona
com esses momentos para lhe fornecer a funcionalidade para a versão e
gerenciar o seu código-fonte.
Funciona através de uma série de registos de estado do projeto e usa esse
registo para permitir funcionalidades de versionamento e gestão de código
fonte.
## Versionando Conceitos
## Conceitos de versionamento
### O que é controle de versão?
### O que é controle de versão
O controle de versão é um sistema que registra alterações em um arquivo ou conjunto
de arquivos, ao longo do tempo.
Controle de versão (*source control*) é um processo de registo de alterações
a um arquivo ou conjunto de arquivos ao longo do tempo.
### Versionamento Centralizado VS Versionamento Distribuído
### Controle de versão: Centralizado VS Distribuído
* Controle de versão centralizado concentra-se na sincronização, controle e backup de arquivos.
* Controle de versão distribuído concentra-se na partilha de mudanças. Toda mudança tem um ID único.
* Sistemas Distribuídos não têm estrutura definida. Você poderia facilmente ter um estilo SVN,
sistema centralizado, com git.
* Controle de versão centralizado foca na sincronização, registo e *backup*
de arquivos.
* Controle de versão distribuído foca em compartilhar alterações. Cada
alteração é associada a um *id* único.
* Sistemas distribuídos não tem estrutura definida. É possivel ter um sistema
centralizado ao estilo SVN usando git.
[Informação Adicional](http://git-scm.com/book/en/Getting-Started-About-Version-Control)
[Informação adicional (EN)](http://git-scm.com/book/en/Getting-Started-About-Version-Control)
### Porque usar o Git?
### Por que usar git?
* Possibilidade de trabalhar offline
* Colaborar com os outros é fácil!
* Ramificação é fácil
* Mesclagem é fácil
* Git é rápido
* Git é flexível.
* Permite trabalhar offline.
* Colaborar com outros é fácil!
* Criar *branches* é fácil!
* Fazer *merge* é fácil!
* Git é rápido.
* Git é flexivel.
## Git - Arquitetura
## Arquitetura Git
### Repositório
Um conjunto de arquivos, diretórios, registros históricos, cometes, e cabeças. Imagine-o
como uma estrutura de dados de código-fonte, com o atributo que cada "elemento" do
código-fonte dá-lhe acesso ao seu histórico de revisão, entre outras coisas.
Um conjunto de arquivos, diretórios, registos históricos, *commits* e
referências. Pode ser descrito como uma estrutura de dados de código fonte
com a particularidade de cada elemento do código fonte permitir acesso ao
histórico das suas alterações, entre outras coisas.
Um repositório git é composto do diretório git. e árvore de trabalho.
Um repositório git é constituido pelo diretório .git e a *working tree*
### Diretório .git (componente do repositório)
O diretório git. contém todas as configurações, registros, galhos, cabeça(HEAD) e muito mais.
[Lista Detalhada](http://gitready.com/advanced/2009/03/23/whats-inside-your-git-directory.html)
O repositório .git contém todas as configurações, *logs*, *branches*,
referências e outros.
### Árvore de trabalho (componente do repositório)
[Lista detalhada (EN)](http://gitready.com/advanced/2009/03/23/whats-inside-your-git-directory.html)
Esta é, basicamente, os diretórios e arquivos no seu repositório. Ele é muitas vezes referida
como seu diretório de trabalho.
### *Working Tree* (componente do repositório)
### Índice (componente do diretório .git)
A *Working Tree* é basicamente a listagem dos diretórios e arquivos do repositório. É chamada também de diretório do projeto.
O Índice é a área de teste no git. É basicamente uma camada que separa a sua árvore de trabalho
a partir do repositório Git. Isso dá aos desenvolvedores mais poder sobre o que é enviado para o
repositório Git.
### *Index* (componente do diretório .git)
### Comete (commit)
O *Index* é a camada da interface no git. É o elemento que separa
o diretório do projeto do repositório git. Isto permite aos programadores um
maior controle sobre o que é registado no repositório git.
A commit git é um instantâneo de um conjunto de alterações ou manipulações a sua árvore de trabalho.
Por exemplo, se você adicionou 5 imagens, e removeu outros dois, estas mudanças serão contidas
em um commit (ou instantâneo). Esta confirmação pode ser empurrado para outros repositórios, ou não!
### *Commit*
### Ramo (branch)
Um *commit** de git é um registo de um cojunto de alterações ou manipulações nos arquivos do projeto.
Por exemplo, ao adicionar cinco arquivos e remover outros 2, estas alterações
serão gravadas num *commit* (ou registo). Este *commit* pode então ser enviado
para outros repositórios ou não!
Um ramo é, essencialmente, um ponteiro que aponta para o último commit que você fez. Como
você se comprometer, este ponteiro irá atualizar automaticamente e apontar para o último commit.
### *Branch*
### Cabeça (HEAD) e cabeça (head) (componente do diretório .git)
Um *branch* é essencialmente uma referência que aponta para o último *commit*
efetuado. Na medida que são feitos novos commits, esta referência é atualizada
automaticamente e passa a apontar para o commit mais recente.
HEAD é um ponteiro que aponta para o ramo atual. Um repositório tem apenas 1 * ativo * HEAD.
head é um ponteiro que aponta para qualquer commit. Um repositório pode ter qualquer número de commits.
### *HEAD* e *head* (componentes do diretório .git)
### Recursos Conceituais
*HEAD* é a referência que aponta para o *branch* em uso. Um repositório só tem
uma *HEAD* activa.
*head* é uma referência que aponta para qualquer *commit*. Um repositório pode
ter um número indefinido de *heads*
* [Git para Cientistas da Computação](http://eagain.net/articles/git-for-computer-scientists/)
### Recursos conceituais (EN)
* [Git para Cientistas de Computação](http://eagain.net/articles/git-for-computer-scientists/)
* [Git para Designers](http://hoth.entp.com/output/git_for_designers.html)
## Comandos
### init
### *init*
Criar um repositório Git vazio. As configurações do repositório Git, informações armazenadas,
e mais são armazenados em um diretório (pasta) com o nome ". git".
Cria um repositório Git vazio. As definições, informação guardada e outros do
repositório git são guardados em uma pasta chamada ".git".
```bash
$ git init
```
### config
### *config*
Para configurar as definições. Quer seja para o repositório, o próprio sistema, ou
configurações globais.
Permite configurar as definições, sejam as definições do repositório, sistema
ou configurações globais.
```bash
# Impressão e definir algumas variáveis de configuração básica (global)
# Imprime e define algumas variáveis de configuração básicas (global)
$ git config --global user.email
$ git config --global user.name
@ -112,22 +121,21 @@ $ git config --global user.email "MyEmail@Zoho.com"
$ git config --global user.name "My Name"
```
[Saiba mais sobre o git config.](http://git-scm.com/docs/git-config)
[Aprenda mais sobre git config. (EN)](http://git-scm.com/docs/git-config)
### help
Para lhe dar um acesso rápido a um guia extremamente detalhada de cada comando. ou
apenas dar-lhe um rápido lembrete de algumas semânticas.
Para visualizar rapidamente o detalhamento de cada comando ou apenas lembrar da semântica.
```bash
# Rapidamente verificar os comandos disponíveis
# Ver rapidamente os comandos disponiveis
$ git help
# Confira todos os comandos disponíveis
# Ver todos os comandos disponiveis
$ git help -a
# Ajuda específica de comando - manual do usuário
# git help <command_here>
# Usar o *help* para um comando especifico
# git help <comando_aqui>
$ git help add
$ git help commit
$ git help init
@ -135,85 +143,89 @@ $ git help init
### status
Para mostrar as diferenças entre o arquivo de índice (basicamente o trabalho de
copiar/repo) e a HEAD commit corrente.
Apresenta as diferenças entre o arquivo *index* (a versão corrente
do repositório) e o *commit* da *HEAD* atual.
```bash
# Irá exibir o ramo, os arquivos não monitorados, as alterações e outras diferenças
# Apresenta o *branch*, arquivos não monitorados, alterações e outras
# difereças
$ git status
# Para saber outras "tid bits" sobre git status
# Para aprender mais detalhes sobre git *status*
$ git help status
```
### add
Para adicionar arquivos para a atual árvore/directory/repo trabalho. Se você não
der `git add` nos novos arquivos para o trabalhando árvore/diretório, eles não serão
incluídos em commits!
Adiciona arquivos ao repositório corrente. Se os arquivos novos não forem
adicionados através de `git add` ao repositório, então eles não serão
incluidos nos commits!
```bash
# Adicionar um arquivo no seu diretório de trabalho atual
# adiciona um arquivo no diretório do projeto atual
$ git add HelloWorld.java
# Adicionar um arquivo em um diretório aninhado
# adiciona um arquivo num sub-diretório
$ git add /path/to/file/HelloWorld.c
# Suporte a expressões regulares!
# permite usar expressões regulares!
$ git add ./*.java
```
### branch
Gerenciar seus ramos. Você pode visualizar, editar, criar, apagar ramos usando este comando.
Gerencia os *branches*. É possível ver, editar, criar e apagar branches com este
comando.
```bash
# Lista ramos e controles remotos existentes
# listar *branches* existentes e remotos
$ git branch -a
# Criar um novo ramo
# criar um novo *branch*
$ git branch myNewBranch
# Apagar um ramo
# apagar um *branch*
$ git branch -d myBranch
# Renomear um ramo
# alterar o nome de um *branch*
# git branch -m <oldname> <newname>
$ git branch -m myBranchName myNewBranchName
# Editar a descrição de um ramo
# editar a descrição de um *branch*
$ git branch myBranchName --edit-description
```
### checkout
Atualiza todos os arquivos na árvore de trabalho para corresponder à versão no
índice, ou árvore especificada.
Atualiza todos os arquivos no diretório do projeto para que fiquem iguais
à versão do index ou do *branch* especificado.
```bash
# Finalizar um repo - padrão de ramo mestre
# Checkout de um repositório - por padrão para o branch master
$ git checkout
# Checa um ramo especificado
# Checkout de um branch especifico
$ git checkout branchName
# Criar um novo ramo e mudar para ela, como: "<nome> git branch; git checkout <nome>"
# Cria um novo branch e faz checkout para ele.
# Equivalente a: "git branch <name>; git checkout <name>"
$ git checkout -b newBranch
```
### clone
Clones, ou cópias, de um repositório existente para um novo diretório. Ele também adiciona
filiais remotas de rastreamento para cada ramo no repo clonado, que permite que você empurre
a um ramo remoto.
Clona ou copia um repositório existente para um novo diretório. Também
adiciona *branches* de monitoramento remoto para cada *branch* no repositório
clonado o que permite enviar alterações para um *branch* remoto.
```bash
# Clone learnxinyminutes-docs
# Clona learnxinyminutes-docs
$ git clone https://github.com/adambard/learnxinyminutes-docs.git
```
### commit
Armazena o conteúdo atual do índice em um novo "commit". Este commit contém
as alterações feitas e uma mensagem criada pelo utilizador.
Guarda o conteudo atual do index num novo *commit*. Este *commit* contém
as alterações feitas e a mensagem criada pelo usuário.
```bash
# commit com uma mensagem
@ -222,170 +234,170 @@ $ git commit -m "Added multiplyNumbers() function to HelloWorld.c"
### diff
Mostra as diferenças entre um arquivo no diretório, o índice de trabalho e commits.
Apresenta as diferenças entre um arquivo no repositório do projeto, *index*
e *commits*
```bash
# Mostrar diferença entre o seu diretório de trabalho e o índice.
# Apresenta a diferença entre o diretório atual e o index
$ git diff
# Mostrar diferenças entre o índice e o commit mais recente.
# Apresenta a diferença entre o index e os commits mais recentes
$ git diff --cached
# Mostrar diferenças entre o seu diretório de trabalho e o commit mais recente.
# Apresenta a diferença entre o diretório atual e o commit mais recente
$ git diff HEAD
```
### grep
Permite procurar rapidamente um repositório.
Permite procurar facilmente num repositório
Configurações opcionais:
```bash
# Obrigado ao Travis Jeffery por isto
# Configure os números de linha a serem mostrados nos resultados de busca grep
# Define a apresentação de números de linha nos resultados do grep
$ git config --global grep.lineNumber true
# Fazer resultados de pesquisa mais legível, incluindo agrupamento
# Agrupa os resultados da pesquisa para facilitar a leitura
$ git config --global alias.g "grep --break --heading --line-number"
```
```bash
# Procure por "variableName" em todos os arquivos java
# Pesquisa por "variableName" em todos os arquivos java
$ git grep 'variableName' -- '*.java'
# Procure por uma linha que contém "arrayListName" e "adicionar" ou "remover"
$ git grep -e 'arrayListName' --and \( -e add -e remove \)
# Pesquisa por uma linha que contém "arrayListName" e "add" ou "remove"
$ git grep -e 'arrayListName' --and \( -e add -e remove \)
```
Google é seu amigo; para mais exemplos
[Git Grep Ninja](http://travisjeffery.com/b/2012/02/search-a-git-repo-like-a-ninja)
O Google é seu amigo; para mais exemplos:
[Git Grep Ninja (EN)](http://travisjeffery.com/b/2012/02/search-a-git-repo-like-a-ninja)
### log
Mostrar commits para o repositório.
Apresenta commits do repositório.
```bash
# Mostrar todos os commits
# Apresenta todos os commits
$ git log
# Mostrar um número X de commits
# Apresenta X commits
$ git log -n 10
# Mostrar somente commits mesclados
# Apresenta apenas commits de merge
$ git log --merges
```
### merge
"Merge" em mudanças de commits externos no branch atual.
"Merge" junta as alterações de commits externos com o *branch* atual.
```bash
# Mesclar o ramo especificado para o atual.
# Junta o branch especificado com o atual
$ git merge branchName
# Gera sempre uma mesclagem commit ao mesclar
# Para gerar sempre um commit ao juntar os branches
$ git merge --no-ff branchName
```
### mv
Renomear ou mover um arquivo
Alterar o nome ou mover um arquivo.
```bash
# Renomear um arquivo
# Alterar o nome de um arquivo
$ git mv HelloWorld.c HelloNewWorld.c
# Mover um arquivo
$ git mv HelloWorld.c ./new/path/HelloWorld.c
# Força renomear ou mover
# "ExistingFile" já existe no diretório, será substituído
# Forçar a alteração de nome ou mudança local
# "existingFile" já existe no directório, será sobrescrito.
$ git mv -f myFile existingFile
```
### pull
Puxa de um repositório e se funde com outro ramo.
Puxa alterações de um repositório e as junta com outro branch
```bash
# Atualize seu repo local, através da fusão de novas mudanças
# A partir da "origem" remoto e ramo "master (mestre)".
# Atualiza o repositório local, juntando as novas alterações
# do repositório remoto 'origin' e branch 'master'
# git pull <remote> <branch>
# git pull => implícito por padrão => git pull origin master
# git pull => aplica a predefinição => git pull origin master
$ git pull origin master
# Mesclar em mudanças de ramo remoto e rebase
# Ramo commita em seu repo local, como: "git pull <remote> <branch>, git rebase <branch>"
# Juntar alterações do branch remote e fazer rebase commits do branch
# no repositório local, como: "git pull <remote> <branch>, git rebase <branch>"
$ git pull origin master --rebase
```
### push
Empurre e mesclar as alterações de uma ramificação para uma remota e ramo.
Enviar e juntar alterações de um branch para o seu branch correspondente
num repositório remoto.
```bash
# Pressione e mesclar as alterações de um repo local para um
# Chamado remoto "origem" e ramo de "mestre".
# Envia e junta as alterações de um repositório local
# para um remoto denominado "origin" no branch "master".
# git push <remote> <branch>
# git push => implícito por padrão => git push origin master
# git push => aplica a predefinição => git push origin master
$ git push origin master
# Para ligar atual filial local com uma filial remota, bandeira add-u:
$ git push -u origin master
# Agora, a qualquer hora que você quer empurrar a partir desse mesmo ramo local, uso de atalho:
$ git push
```
### rebase (CAUTELA)
### rebase (cautela!)
Tire todas as alterações que foram commitadas em um ramo, e reproduzi-las em outro ramo.
* Não rebase commits que você tenha empurrado a um repo público *.
Pega em todas as alterações que foram registadas num branch e volta a
aplicá-las em outro branch.
*Não deve ser feito rebase de commits que foram enviados para um repositório
público*
```bash
# Rebase experimentBranch para mestre
# Faz Rebase de experimentBranch para master
# git rebase <basebranch> <topicbranch>
$ git rebase master experimentBranch
```
[Leitura Adicional.](http://git-scm.com/book/en/Git-Branching-Rebasing)
[Leitura adicional (EN).](http://git-scm.com/book/en/Git-Branching-Rebasing)
### reset (CAUTELA)
### reset (cuidado!)
Repor o atual HEAD de estado especificado. Isto permite-lhe desfazer fusões (merge),
puxa (push), commits, acrescenta (add), e muito mais. É um grande comando, mas também
perigoso se não saber o que se está fazendo.
Restabelece a HEAD atual ao estado definido. Isto permite reverter *merges*,
*pulls*, *commits*, *adds* e outros. É um comando muito poderoso mas também
perigoso quando não há certeza do que se está fazendo.
```bash
# Repor a área de teste, para coincidir com o último commit (deixa diretório inalterado)
# Restabelece a camada intermediária de registo para o último
# commit (o directório fica sem alterações)
$ git reset
# Repor a área de teste, para coincidir com o último commit, e substituir diretório trabalhado
# Restabelece a camada intermediária de registo para o último commit, e
# sobrescreve o projeto atual
$ git reset --hard
# Move a ponta ramo atual para o especificado commit (deixa diretório inalterado)
# Todas as alterações ainda existem no diretório.
# Move a head do branch atual para o commit especificado, sem alterar o projeto.
# todas as alterações ainda existem no projeto
$ git reset 31f2bb1
# Move a ponta ramo atual para trás, para o commit especificado
# E faz o jogo dir trabalho (exclui mudanças não commitadas e todos os commits
# Após o commit especificado).
# Inverte a head do branch atual para o commit especificado
# fazendo com que este esteja em sintonia com o diretório do projeto
# Remove alterações não registadas e todos os commits após o commit especificado
$ git reset --hard 31f2bb1
```
### rm
O oposto do git add, git rm remove arquivos da atual árvore de trabalho.
O oposto de git add, git rm remove arquivos do branch atual.
```bash
# remove HelloWorld.c
$ git rm HelloWorld.c
# Remove um arquivo de um diretório aninhado
# Remove um arquivo de um sub-directório
$ git rm /pather/to/the/file/HelloWorld.c
```
# # Mais informações
## Informação complementar (EN)
* [tryGit - A fun interactive way to learn Git.](http://try.github.io/levels/1/challenges/1)
@ -398,5 +410,3 @@ $ git rm /pather/to/the/file/HelloWorld.c
* [SalesForce Cheat Sheet](https://na1.salesforce.com/help/doc/en/salesforce_git_developer_cheatsheet.pdf)
* [GitGuys](http://www.gitguys.com/)
* [Git - guia prático](http://rogerdudler.github.io/git-guide/index.pt_BR.html)

176
pt-br/hy-pt.html.markdown Normal file
View File

@ -0,0 +1,176 @@
---
language: hy
filename: learnhy.hy
contributors:
- ["Abhishek L", "http://twitter.com/abhishekl"]
translators:
- ["Miguel Araújo", "https://github.com/miguelarauj1o"]
lang: pt-br
---
Hy é um dialeto de Lisp escrito sobre Python. Isto é possível convertendo
código Hy em árvore sintática abstrata python (ast). Portanto, isto permite
hy chamar código python nativo e vice-versa.
Este tutorial funciona para hy ≥ 0.9.12
```clojure
;; Isso dá uma introdução básica em hy, como uma preliminar para o link abaixo
;; http://try-hy.appspot.com
;;
; Comentários em ponto-e-vírgula, como em outros LISPS
;; s-noções básicas de expressão
; programas Lisp são feitos de expressões simbólicas ou sexps que se assemelham
(some-function args)
; agora o essencial "Olá mundo"
(print "hello world")
;; Tipos de dados simples
; Todos os tipos de dados simples são exatamente semelhantes aos seus homólogos
; em python que
42 ; => 42
3.14 ; => 3.14
True ; => True
4+10j ; => (4+10j) um número complexo
; Vamos começar com um pouco de aritmética muito simples
(+ 4 1) ;=> 5
; o operador é aplicado a todos os argumentos, como outros lisps
(+ 4 1 2 3) ;=> 10
(- 2 1) ;=> 1
(* 4 2) ;=> 8
(/ 4 1) ;=> 4
(% 4 2) ;=> 0 o operador módulo
; exponenciação é representado pelo operador ** como python
(** 3 2) ;=> 9
; formas aninhadas vão fazer a coisa esperada
(+ 2 (* 4 2)) ;=> 10
; também operadores lógicos e ou não e igual etc. faz como esperado
(= 5 4) ;=> False
(not (= 5 4)) ;=> True
;; variáveis
; variáveis são definidas usando SETV, nomes de variáveis podem usar utf-8, exceto
; for ()[]{}",'`;#|
(setv a 42)
(setv π 3.14159)
(def *foo* 42)
;; outros tipos de dados de armazenamento
; strings, lists, tuples & dicts
; estes são exatamente os mesmos tipos de armazenamento de python
"hello world" ;=> "hello world"
; operações de string funcionam semelhante em python
(+ "hello " "world") ;=> "hello world"
; Listas são criadas usando [], a indexação começa em 0
(setv mylist [1 2 3 4])
; tuplas são estruturas de dados imutáveis
(setv mytuple (, 1 2))
; dicionários são pares de valores-chave
(setv dict1 {"key1" 42 "key2" 21})
; :nome pode ser utilizado para definir palavras-chave em hy que podem ser utilizados para as chaves
(setv dict2 {:key1 41 :key2 20})
; usar 'get' para obter o elemento em um índice/key
(get mylist 1) ;=> 2
(get dict1 "key1") ;=> 42
; Alternativamente, se foram utilizadas palavras-chave que podem ser chamadas diretamente
(:key1 dict2) ;=> 41
;; funções e outras estruturas de programa
; funções são definidas usando defn, o último sexp é devolvido por padrão
(defn greet [name]
"A simple greeting" ; uma docstring opcional
(print "hello " name))
(greet "bilbo") ;=> "hello bilbo"
; funções podem ter argumentos opcionais, bem como argumentos-chave
(defn foolists [arg1 &optional [arg2 2]]
[arg1 arg2])
(foolists 3) ;=> [3 2]
(foolists 10 3) ;=> [10 3]
; funções anônimas são criados usando construtores 'fn' ou 'lambda'
; que são semelhantes para 'defn'
(map (fn [x] (* x x)) [1 2 3 4]) ;=> [1 4 9 16]
;; operações de sequência
; hy tem algumas utils embutidas para operações de sequência, etc.
; recuperar o primeiro elemento usando 'first' ou 'car'
(setv mylist [1 2 3 4])
(setv mydict {"a" 1 "b" 2})
(first mylist) ;=> 1
; corte listas usando 'slice'
(slice mylist 1 3) ;=> [2 3]
; obter elementos de uma lista ou dict usando 'get'
(get mylist 1) ;=> 2
(get mydict "b") ;=> 2
; lista de indexação começa a partir de 0, igual em python
; assoc pode definir elementos em chaves/índices
(assoc mylist 2 10) ; faz mylist [1 2 10 4]
(assoc mydict "c" 3) ; faz mydict {"a" 1 "b" 2 "c" 3}
; há toda uma série de outras funções essenciais que torna o trabalho com
; sequências uma diversão
;; Python interop
;; importação funciona exatamente como em python
(import datetime)
(import [functools [partial reduce]]) ; importa fun1 e fun2 do module1
(import [matplotlib.pyplot :as plt]) ; fazendo uma importação em foo como em bar
; todos os métodos de python embutidas etc. são acessíveis a partir hy
; a.foo(arg) is called as (.foo a arg)
(.split (.strip "hello world ")) ;=> ["hello" "world"]
;; Condicionais
; (if condition (body-if-true) (body-if-false)
(if (= passcode "moria")
(print "welcome")
(print "Speak friend, and Enter!"))
; aninhe múltiplas cláusulas 'if else if' com cond
(cond
[(= someval 42)
(print "Life, universe and everything else!")]
[(> someval 42)
(print "val too large")]
[(< someval 42)
(print "val too small")])
; declarações de grupo com 'do', essas são executadas sequencialmente
; formas como defn tem um 'do' implícito
(do
(setv someval 10)
(print "someval is set to " someval)) ;=> 10
; criar ligações lexicais com 'let', todas as variáveis definidas desta forma
; tem escopo local
(let [[nemesis {"superman" "lex luther"
"sherlock" "moriarty"
"seinfeld" "newman"}]]
(for [(, h v) (.items nemesis)]
(print (.format "{0}'s nemesis was {1}" h v))))
;; classes
; classes são definidas da seguinte maneira
(defclass Wizard [object]
[[--init-- (fn [self spell]
(setv self.spell spell) ; init a mágica attr
None)]
[get-spell (fn [self]
self.spell)]])
;; acesse hylang.org
```
### Outras Leituras
Este tutorial é apenas uma introdução básica para hy/lisp/python.
Docs Hy: [http://hy.readthedocs.org](http://hy.readthedocs.org)
Repo Hy no Github: [http://github.com/hylang/hy](http://github.com/hylang/hy)
Acesso ao freenode irc com #hy, hashtag no twitter: #hylang

View File

@ -0,0 +1,500 @@
---
language: swift
contributors:
- ["Grant Timmerman", "http://github.com/grant"]
- ["Christopher Bess", "http://github.com/cbess"]
translators:
- ["Mariane Siqueira Machado", "https://twitter.com/mariane_sm"]
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
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/RoadMapiOS/index.html), também disponível apenas em inglês.
```swift
// importa um módulo
import UIKit
//
// MARK: Noções básicas
//
// Xcode supporta anotações para seu código e lista elas na barra de atalhos
// MARK: Marca uma sessão
// TODO: Faça algo logo
// FIXME: Conserte esse código
println("Hello, world")
// Valores em variáveis (var) podem ter seu valor alterado depois de declarados.
// Valores em constantes (let) NÃO podem ser alterados depois de declarados.
var myVariable = 42
let øπΩ = "value" // nomes de variáveis em unicode
let π = 3.1415926
let convenience = "keyword" // nome de variável contextual
let weak = "keyword"; let override = "another keyword" // comandos podem ser separados por uma ponto e vírgula
let `class` = "keyword" // Crases permitem que palavras-chave seja usadas como nome de variáveis
let explicitDouble: Double = 70
let intValue = 0007 // 7
let largeIntValue = 77_000 // 77000
let label = "some text " + String(myVariable) // Coerção
let piText = "Pi = \(π), Pi 2 = \(π * 2)" // Interpolação de strings
// Constrói valores específicos
// Utiliza configuração de build -D
#if false
println("Not printed")
let buildValue = 3
#else
let buildValue = 7
#endif
println("Build value: \(buildValue)") // Build value: 7
/*
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.
Optional<T> é uma enum.
*/
var someOptionalString: String? = "optional" // Pode ser nil
// o mesmo acima, mas ? é um operador pós-fixado (açúcar sintático)
var someOptionalString2: Optional<String> = "optional"
if someOptionalString != nil {
// Eu não sou nil
if someOptionalString!.hasPrefix("opt") {
println("has the prefix")
}
let empty = someOptionalString?.isEmpty
}
someOptionalString = nil
// Optional implicitamente desempacotado (unwrapped)
var unwrappedString: String! = "Valor é esperado."
// o mesmo acima, mas ? é um operador pósfixado (açúcar sintático)
var unwrappedString2: ImplicitlyUnwrappedOptional<String> = "Valor é esperado."
if let someOptionalStringConstant = someOptionalString {
// Tem `Some` (algum) valor, não nil
if !someOptionalStringConstant.hasPrefix("ok") {
// não possui o prefixo
}
}
// Swift tem suporte para armazenar um valor de qualquer tipo.
// AnyObject == id
// Ao contrário de Objective-C `id`, AnyObject funciona com qualquer valor (Class, Int, struct, etc)
var anyObjectVar: AnyObject = 7
anyObjectVar = "Mudou o valor para string, não é uma boa prática, mas é possível."
/*
Comentário aqui
/*
Comentários aninhados também são suportados
*/
*/
//
// MARK: Coleções
//
/*
Tipos Array e Dicionário são structs. Portanto `let` e `var`
também indicam se são mutáveis (var) ou imutáveis (let) quando declarados
com esses tipos.
*/
// Array
var shoppingList = ["catfish", "water", "lemons"]
shoppingList[1] = "bottle of water"
let emptyArray = [String]() // imutável
var emptyMutableArray = [String]() // mutável
// Dicionário
var occupations = [
"Malcolm": "Captain",
"kaylee": "Mechanic"
]
occupations["Jayne"] = "Public Relations"
let emptyDictionary = [String: Float]() // imutável
var emptyMutableDictionary = [String: Float]() // mutável
//
// MARK: Controle de fluxo
//
// laço for (array)
let myArray = [1, 1, 2, 3, 5]
for value in myArray {
if value == 1 {
println("One!")
} else {
println("Not one!")
}
}
// laço for (dicionário)
var dict = ["one": 1, "two": 2]
for (key, value) in dict {
println("\(key): \(value)")
}
// laço for (alcance)
for i in -1...shoppingList.count {
println(i)
}
shoppingList[1...2] = ["steak", "peacons"]
// use ..< para excluir o último número
// laço while (enquanto)
var i = 1
while i < 1000 {
i *= 2
}
// laço do-while
do {
println("hello")
} while 1 == 2
// Switch
let vegetable = "red pepper"
switch vegetable {
case "celery":
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: // required (in order to cover all possible input)
let vegetableComment = "Everything tastes good in soup."
}
//
// MARK: Funções
//
// Funções são tipos de primeira classe, o que significa que eles podem ser aninhados
// em funções e podem ser passados como parâmetros
// Funções Swift com cabeçalhos doc (formato como reStructedText)
/**
Uma operação de saudação
- Um bullet em documentos
- Outro bullet
:param: nome A nome
:param: dia A dia
:returns: Uma string contendo o nome e o dia.
*/
func greet(name: String, day: String) -> String {
return "Hello \(name), today is \(day)."
}
greet("Bob", "Tuesday")
// Função que retorna múltiplos items em uma tupla
func getGasPrices() -> (Double, Double, Double) {
return (3.59, 3.69, 3.79)
}
let pricesTuple = getGasPrices()
let price = pricesTuple.2 // 3.79
// Ignore valores de Tuplas (ou outros valores) usando _ (underscore)
let (_, price1, _) = pricesTuple // price1 == 3.69
println(price1 == pricesTuple.1) // true
println("Gas price: \(price)")
// Número variável de argumentos
func setup(numbers: Int...) {
// its an array
let number = numbers[0]
let argCount = numbers.count
}
// Passando e retornando funções
func makeIncrementer() -> (Int -> Int) {
func addOne(number: Int) -> Int {
return 1 + number
}
return addOne
}
var increment = makeIncrementer()
increment(7)
// passagem por referência
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: Closures
//
var numbers = [1, 2, 6]
// Funções são casos especiais de closures ({})
// Exemplo de closure.
// `->` separa argumentos e tipo de retorno
// `in` separa o cabeçalho do closure do seu corpo
numbers.map({
(number: Int) -> Int in
let result = 3 * number
return result
})
// Quando o tipo é conhecido, como abaixo, nós podemos fazer o seguinte
numbers = numbers.map({ number in 3 * number })
// Ou até mesmo isso
//numbers = numbers.map({ $0 * 3 })
print(numbers) // [3, 6, 18]
// Closure restante
numbers = sorted(numbers) { $0 > $1 }
print(numbers) // [18, 6, 3]
// Super atalho, já que o operador < infere os tipos
numbers = sorted(numbers, < )
print(numbers) // [3, 6, 18]
//
// MARK: Estruturas
//
// Estruturas e classes tem funcionalidades muito similares
struct NamesTable {
let names: [String]
// Custom subscript
subscript(index: Int) -> String {
return names[index]
}
}
// Estruturas possuem um inicializador auto-gerado automático (implícito)
let namesTable = NamesTable(names: ["Me", "Them"])
//let name = namesTable[2]
//println("Name is \(name)") // Name is Them
//
// MARK: Classes
//
// Classes, Estruturas e seus membros possuem três níveis de modificadores de acesso
// Eles são: internal (default), public, private
public class Shape {
public func getArea() -> Int {
return 0;
}
}
// Todos os métodos e propriedades de uma classe são públicos.
// Se você só precisa armazenar dados em um objeto estruturado, use `struct`
internal class Rect: Shape {
var sideLength: Int = 1
// Getter e setter personalizado
private var perimeter: Int {
get {
return 4 * sideLength
}
set {
// `newValue` é uma variável implicita disponível para os setters
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
// 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
willSet(someIdentifier) {
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`
class Square: Rect {
convenience init() {
self.init(sideLength: 5)
}
}
var mySquare = Square()
print(mySquare.getArea()) // 25
mySquare.shrink()
print(mySquare.sideLength) // 4
// Compara instâncias, não é o mesmo que == o qual compara objetos
if mySquare === mySquare {
println("Yep, it's mySquare")
}
//
// MARK: Enums
//
// Enums podem opcionalmente ser de um tipo específico ou não.
// Podem conter métodos do mesmo jeito que classes.
enum Suit {
case Spades, Hearts, Diamonds, Clubs
func getIcon() -> String {
switch self {
case .Spades: return "♤"
case .Hearts: return "♡"
case .Diamonds: return "♢"
case .Clubs: return "♧"
}
}
}
//
// MARK: Protocolos
//
// `protocol` pode requerer que os tipos que se adequam tenham
// propriedades de instância, métodos, operadores e subscripts.
protocol ShapeGenerator {
var enabled: Bool { get set }
func buildShape() -> Shape
}
// Protocolos declarados com @objc permitem funções opcionais,
// que permitem verificar a confomidade
@objc protocol TransformShape {
optional func reshaped()
optional func canReshape() -> Bool
}
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
self.delegate?.reshaped?()
}
}
}
//
// MARK: Outros
//
// `extension`s: Adicionam uma funcionalidade extra para um tipo já existente.
// Square agora "segue" o protocolo `Printable`
extension Square: Printable {
var description: String {
return "Area: \(self.getArea()) - ID: \(self.identifier)"
}
}
println("Square: \(mySquare)")
// Você pode também estender tipos embutidos (built-in)
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(2)) // 42
// Generics: Similar com Java e C#. Use a palavra-chave `where` para
// especificar os requisitos do generics.
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
// Operadores:
// Operadores personalizados (custom) podem começar com os seguintes caracteres:
// / = - + * % < > ! & | ^ . ~
// ou
// Unicode math, símbolo, seta, e caracteres tipográficos ou de desenho.
prefix operator !!! {}
// Um operador de prefixo que triplica o comprimento do lado do quadrado
// quando usado
prefix func !!! (inout shape: Square) -> Square {
shape.sideLength *= 3
return shape
}
// valor atual
println(mySquare.sideLength) // 4
// Troca o comprimento do lado usando um operador personalizado !!!, aumenta o lado por 3
!!!mySquare
println(mySquare.sideLength) // 12
```

133
pt-br/xml-pt.html.markdown Normal file
View File

@ -0,0 +1,133 @@
---
language: xml
filename: learnxml.xml
contributors:
- ["João Farias", "https://github.com/JoaoGFarias"]
translators:
- ["Miguel Araújo", "https://github.com/miguelarauj1o"]
lang: pt-br
---
XML é uma linguagem de marcação projetada para armazenar e transportar dados.
Ao contrário de HTML, XML não especifica como exibir ou formatar os dados,
basta carregá-lo.
* Sintaxe XML
```xml
<!-- Comentários em XML são feitos desta forma -->
<?xml version="1.0" encoding="UTF-8"?>
<livraria>
<livro category="COZINHA">
<titulo lang="en">Everyday Italian</titulo>
<autor>Giada De Laurentiis</autor>
<year>2005</year>
<preco>30.00</preco>
</livro>
<livro category="CRIANÇAS">
<titulo lang="en">Harry Potter</titulo>
<autor>J K. Rowling</autor>
<year>2005</year>
<preco>29.99</preco>
</livro>
<livro category="WEB">
<titulo lang="en">Learning XML</titulo>
<autor>Erik T. Ray</autor>
<year>2003</year>
<preco>39.95</preco>
</livro>
</livraria>
<!-- Um típico arquivo XML é mostrado acima.
Ele começa com uma declaração, informando alguns metadados (opcional).
XML usa uma estrutura de árvore. Acima, o nó raiz é "Livraria", que tem
três nós filhos, todos os 'Livros'. Esses nós tem mais nós filhos,
e assim por diante...
Nós são criados usando tags abre/fecha, filhos são justamente os nós que
estão entre estes nós. -->
<!-- XML traz dois tipos de dados:
1 - Atributos -> Isso é metadados sobre um nó.
Normalmente, o parser XML usa esta informação para armazenar os dados
corretamente. Caracteriza-se por aparecer em parênteses dentro da tag
de abertura.
2 - Elementos -> É dados puros.
Isso é o que o analisador irá recuperar a partir do arquivo XML.
Elementos aparecem entre as tags de abertura e fechamento,
sem parênteses. -->
<!-- Abaixo, um elemento com dois atributos -->
<arquivo type="gif" id="4293">computer.gif</arquivo>
```
* Documento bem formatado x Validação
Um documento XML é bem formatado se estiver sintaticamente correto.No entanto,
é possível injetar mais restrições no documento, utilizando definições de
documentos, tais como DTD e XML Schema.
Um documento XML que segue uma definição de documento é chamado válido, sobre
esse documento.
Com esta ferramenta, você pode verificar os dados XML fora da lógica da aplicação.
```xml
<!-- Abaixo, você pode ver uma versão simplificada do documento livraria,
com a adição de definição DTD.-->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE note SYSTEM "livraria.dtd">
<livraria>
<livro category="COOKING">
<titulo >Everyday Italian</titulo>
<preco>30.00</preco>
</livro>
</livraria>
<!-- Este DTD poderia ser algo como:-->
<!DOCTYPE note
[
<!ELEMENT livraria (livro+)>
<!ELEMENT livro (titulo,preco)>
<!ATTLIST livro category CDATA "Literature">
<!ELEMENT titulo (#PCDATA)>
<!ELEMENT preco (#PCDATA)>
]>
<!-- O DTD começa com uma declaração.
Na sequência, o nó raiz é declarado, o que requer uma ou mais crianças nós
'Livro'. Cada 'Livro' deve conter exatamente um 'titulo' e um 'preco' e um
atributo chamado "categoria", com "Literatura", como o valor padrão.
Os nós "título" e "preço" contêm um conjunto de dados de caráter analisados.-->
<!-- O DTD poderia ser declarado dentro do próprio arquivo XML .-->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE note
[
<!ELEMENT livraria (livro+)>
<!ELEMENT livro (titulo,preco)>
<!ATTLIST livro category CDATA "Literature">
<!ELEMENT titulo (#PCDATA)>
<!ELEMENT preco (#PCDATA)>
]>
<livraria>
<livro category="COOKING">
<titulo >Everyday Italian</titulo>
<preco>30.00</preco>
</livro>
</livraria>
```

View File

@ -74,8 +74,7 @@ maior controlo sobre o que é registado no repositório git.
### *Commit*
Um *commit** de git é um registo de um cojunto de alterações ou manipulações
no nos ficheiros do projecto.
Um *commit** de git é um registo de um cojunto de alterações ou manipulações nos ficheiros do projecto.
Por exemplo, ao adicionar cinco ficheiros e remover outros 2, estas alterações
serão gravadas num *commit* (ou registo). Este *commit* pode então ser enviado
para outros repositórios ou não!
@ -83,7 +82,7 @@ para outros repositórios ou não!
### *Branch*
Um *branch* é essencialmente uma referência que aponta para o último *commit*
efetuado. à medida que são feitos novos commits, esta referência é atualizada
efetuado. À medida que são feitos novos commits, esta referência é atualizada
automaticamente e passa a apontar para o commit mais recente.
### *HEAD* e *head* (componentes do directório .git)
@ -115,7 +114,7 @@ Permite configurar as definições, sejam as definições do repositório, siste
ou configurações globais.
```bash
# Imprime & Define Algumas Variáveis de Configuração Básicas (Global)
# Imprime e define algumas variáveis de configuração básicas (global)
$ git config --global user.email
$ git config --global user.name
@ -123,7 +122,7 @@ $ git config --global user.email "MyEmail@Zoho.com"
$ git config --global user.name "My Name"
```
[Aprenda Mais Sobre git config. (EN)](http://git-scm.com/docs/git-config)
[Aprenda mais sobre git config. (EN)](http://git-scm.com/docs/git-config)
### help
@ -166,7 +165,7 @@ adicionados através de `git add` ao repositório, então eles não serão
incluidos nos commits!
```bash
# adiciona um ficheiro no directório do project atual
# adiciona um ficheiro no directório do projecto atual
$ git add HelloWorld.java
# adiciona um ficheiro num sub-directório
@ -371,7 +370,7 @@ Restabelece a HEAD atual ao estado definido. Isto permite reverter *merges*,
perigoso se não há certeza quanto ao que se está a fazer.
```bash
# Restabelece a camada intermediária dr registo para o último
# Restabelece a camada intermediária de registo para o último
# commit (o directório fica sem alterações)
$ git reset

View File

@ -14,7 +14,7 @@ executable pseudocode.
Feedback would be highly appreciated! You can reach me at [@louiedinh](http://twitter.com/louiedinh) or louiedinh [at] [google's email service]
Note: This article applies to Python 2.7 specifically, but should be applicable
to Python 2.x. For Python 3.x, take a look at the Python 3 tutorial.
to Python 2.x. For Python 3.x, take a look at the [Python 3 tutorial](http://learnxinyminutes.com/docs/python3/).
```python
@ -46,7 +46,7 @@ to Python 2.x. For Python 3.x, take a look at the Python 3 tutorial.
2.0 # This is a float
11.0 / 4.0 # => 2.75 ahhh...much better
# Result of integer division truncated down both for positive and negative.
# Result of integer division truncated down both for positive and negative.
5 // 3 # => 1
5.0 // 3.0 # => 1.0 # works on floats too
-5 // 3 # => -2
@ -101,6 +101,8 @@ not False # => True
# Strings can be added too!
"Hello " + "world!" # => "Hello world!"
# Strings can be added without using '+'
"Hello " "world!" # => "Hello world!"
# ... or multiplied
"Hello" * 3 # => "HelloHelloHello"
@ -139,12 +141,8 @@ bool("") # => False
## 2. Variables and Collections
####################################################
# Python has a print statement, in all 2.x versions but removed from 3.
# Python has a print statement
print "I'm Python. Nice to meet you!"
# Python also has a print function, available in versions 2.7 and 3...
# but for 2.7 you need to add the import (uncommented):
# from __future__ import print_function
print("I'm also Python! ")
# No need to declare variables before assigning to them.
some_var = 5 # Convention is to use lower_case_with_underscores
@ -193,14 +191,14 @@ li[2:] # => [4, 3]
li[:3] # => [1, 2, 4]
# Select every second entry
li[::2] # =>[1, 4]
# Revert the list
# Reverse a copy of the list
li[::-1] # => [3, 4, 2, 1]
# Use any combination of these to make advanced slices
# li[start:end:step]
# Remove arbitrary elements from a list with "del"
del li[2] # li is now [1, 2, 3]
r
# You can add lists
li + other_li # => [1, 2, 3, 4, 5, 6]
# Note: values for li and for other_li are not modified.
@ -264,7 +262,7 @@ filled_dict.get("four") # => None
# The get method supports a default argument when the value is missing
filled_dict.get("one", 4) # => 1
filled_dict.get("four", 4) # => 4
# note that filled_dict.get("four") is still => 4
# note that filled_dict.get("four") is still => None
# (get doesn't set the value in the dictionary)
# set the value of a key with a syntax similar to lists
@ -314,11 +312,11 @@ some_var = 5
# Here is an if statement. Indentation is significant in python!
# prints "some_var is smaller than 10"
if some_var > 10:
print("some_var is totally bigger than 10.")
print "some_var is totally bigger than 10."
elif some_var < 10: # This elif clause is optional.
print("some_var is smaller than 10.")
print "some_var is smaller than 10."
else: # This is optional too.
print("some_var is indeed 10.")
print "some_var is indeed 10."
"""
@ -330,7 +328,7 @@ prints:
"""
for animal in ["dog", "cat", "mouse"]:
# You can use % to interpolate formatted strings
print("%s is a mammal" % animal)
print "%s is a mammal" % animal
"""
"range(number)" returns a list of numbers
@ -342,7 +340,19 @@ prints:
3
"""
for i in range(4):
print(i)
print i
"""
"range(lower, upper)" returns a list of numbers
from the lower number to the upper number
prints:
4
5
6
7
"""
for i in range(4, 8):
print i
"""
While loops go until a condition is no longer met.
@ -354,7 +364,7 @@ prints:
"""
x = 0
while x < 4:
print(x)
print x
x += 1 # Shorthand for x = x + 1
# Handle exceptions with a try/except block
@ -377,7 +387,7 @@ else: # Optional clause to the try/except block. Must follow all except blocks
# Use "def" to create new functions
def add(x, y):
print("x is %s and y is %s" % (x, y))
print "x is %s and y is %s" % (x, y)
return x + y # Return values with a return statement
# Calling functions with parameters
@ -406,8 +416,8 @@ keyword_args(big="foot", loch="ness") # => {"big": "foot", "loch": "ness"}
# You can do both at once, if you like
def all_the_args(*args, **kwargs):
print(args)
print(kwargs)
print args
print kwargs
"""
all_the_args(1, 2, a=3, b=4) prints:
(1, 2)
@ -429,14 +439,14 @@ def pass_all_the_args(*args, **kwargs):
print varargs(*args)
print keyword_args(**kwargs)
# Function Scope
# Function Scope
x = 5
def setX(num):
# Local var x not the same as global variable x
x = num # => 43
print x # => 43
def setGlobalX(num):
global x
print x # => 5
@ -503,10 +513,10 @@ class Human(object):
# Instantiate a class
i = Human(name="Ian")
print(i.say("hi")) # prints out "Ian: hi"
print i.say("hi") # prints out "Ian: hi"
j = Human("Joel")
print(j.say("hello")) # prints out "Joel: hello"
print j.say("hello") # prints out "Joel: hello"
# Call our class method
i.get_species() # => "H. sapiens"
@ -526,12 +536,12 @@ Human.grunt() # => "*grunt*"
# You can import modules
import math
print(math.sqrt(16)) # => 4
print math.sqrt(16) # => 4
# You can get specific functions from a module
from math import ceil, floor
print(ceil(3.7)) # => 4.0
print(floor(3.7)) # => 3.0
print ceil(3.7) # => 4.0
print floor(3.7) # => 3.0
# You can import all functions from a module.
# Warning: this is not recommended
@ -577,7 +587,7 @@ xrange_ = xrange(1, 900000000)
# will double all numbers until a result >=30 found
for i in double_numbers(xrange_):
print(i)
print i
if i >= 30:
break
@ -606,8 +616,8 @@ def say(say_please=False):
return msg, say_please
print(say()) # Can you buy me a beer?
print(say(say_please=True)) # Can you buy me a beer? Please! I am poor :(
print say() # Can you buy me a beer?
print say(say_please=True) # Can you buy me a beer? Please! I am poor :(
```
## Ready For More?

View File

@ -13,7 +13,7 @@ executable pseudocode.
Feedback would be highly appreciated! You can reach me at [@louiedinh](http://twitter.com/louiedinh) or louiedinh [at] [google's email service]
Note: This article applies to Python 3 specifically. Check out the other tutorial if you want to learn the old Python 2.7
Note: This article applies to Python 3 specifically. Check out [here](http://learnxinyminutes.com/docs/python/) if you want to learn the old Python 2.7
```python
@ -39,7 +39,7 @@ Note: This article applies to Python 3 specifically. Check out the other tutoria
# Except division which returns floats by default
35 / 5 # => 7.0
# Result of integer division truncated down both for positive and negative.
# Result of integer division truncated down both for positive and negative.
5 // 3 # => 1
5.0 // 3.0 # => 1.0 # works on floats too
-5 // 3 # => -2
@ -73,8 +73,8 @@ False or True #=> True
# Note using Bool operators with ints
0 and 2 #=> 0
-5 or 0 #=> -5
0 == False #=> True
2 == True #=> False
0 == False #=> True
2 == True #=> False
1 == True #=> True
# Equality is ==
@ -101,6 +101,8 @@ False or True #=> True
# Strings can be added too! But try not to do this.
"Hello " + "world!" # => "Hello world!"
# Strings can be added without using '+'
"Hello " "world!" # => "Hello world!"
# A string can be treated like a list of characters
"This is a string"[0] # => 'T'
@ -143,7 +145,7 @@ bool({}) #=> False
# Python has a print function
print("I'm Python. Nice to meet you!")
# No need to declare variables before assigning to them.
# No need to declare variables before assigning to them.
# Convention is to use lower_case_with_underscores
some_var = 5
some_var # => 5
@ -184,7 +186,7 @@ li[2:] # => [4, 3]
li[:3] # => [1, 2, 4]
# Select every second entry
li[::2] # =>[1, 4]
# Revert the list
# Return a reversed copy of the list
li[::-1] # => [3, 4, 2, 1]
# Use any combination of these to make advanced slices
# li[start:end:step]
@ -194,7 +196,7 @@ del li[2] # li is now [1, 2, 3]
# You can add lists
# Note: values for li and for other_li are not modified.
li + other_li # => [1, 2, 3, 4, 5, 6]
li + other_li # => [1, 2, 3, 4, 5, 6]
# Concatenate lists with "extend()"
li.extend(other_li) # Now li is [1, 2, 3, 4, 5, 6]
@ -211,7 +213,7 @@ tup = (1, 2, 3)
tup[0] # => 1
tup[0] = 3 # Raises a TypeError
# You can do all those list thingies on tuples too
# You can do most of the list operations on tuples too
len(tup) # => 3
tup + (4, 5, 6) # => (1, 2, 3, 4, 5, 6)
tup[:2] # => (1, 2)
@ -233,15 +235,15 @@ filled_dict = {"one": 1, "two": 2, "three": 3}
# Look up values with []
filled_dict["one"] # => 1
# Get all keys as a list with "keys()".
# We need to wrap the call in list() because we are getting back an iterable. We'll talk about those later.
# Note - Dictionary key ordering is not guaranteed.
# Your results might not match this exactly.
# Get all keys as an iterable with "keys()". We need to wrap the call in list()
# to turn it into a list. We'll talk about those later. Note - Dictionary key
# ordering is not guaranteed. Your results might not match this exactly.
list(filled_dict.keys()) # => ["three", "two", "one"]
# Get all values as a list with "values()". Once again we need to wrap it in list() to get it out of the iterable.
# Note - Same as above regarding key ordering.
# Get all values as an iterable with "values()". Once again we need to wrap it
# in list() to get it out of the iterable. Note - Same as above regarding key
# ordering.
list(filled_dict.values()) # => [3, 2, 1]
@ -276,10 +278,10 @@ empty_set = set()
# Initialize a set with a bunch of values. Yeah, it looks a bit like a dict. Sorry.
some_set = {1, 1, 2, 2, 3, 4} # some_set is now {1, 2, 3, 4}
#Can set new variables to a set
# Can set new variables to a set
filled_set = some_set
# Add one more item to the set
# Add one more item to the set
filled_set.add(5) # filled_set is now {1, 2, 3, 4, 5}
# Do set intersection with &
@ -326,7 +328,7 @@ for animal in ["dog", "cat", "mouse"]:
print("{} is a mammal".format(animal))
"""
"range(number)" returns a list of numbers
"range(number)" returns an iterable of numbers
from zero to the given number
prints:
0
@ -337,6 +339,18 @@ prints:
for i in range(4):
print(i)
"""
"range(lower, upper)" returns an iterable of numbers
from the lower number to the upper number
prints:
4
5
6
7
"""
for i in range(4, 8):
print(i)
"""
While loops go until a condition is no longer met.
prints:
@ -394,7 +408,6 @@ our_iterator.__next__() # Raises StopIteration
list(filled_dict.keys()) #=> Returns ["one", "two", "three"]
####################################################
## 4. Functions
####################################################
@ -410,7 +423,6 @@ add(5, 6) # => prints out "x is 5 and y is 6" and returns 11
# Another way to call functions is with keyword arguments
add(y=6, x=5) # Keyword arguments can arrive in any order.
# You can define functions that take a variable number of
# positional arguments
def varargs(*args):
@ -418,7 +430,6 @@ def varargs(*args):
varargs(1, 2, 3) # => (1, 2, 3)
# You can define functions that take a variable number of
# keyword arguments, as well
def keyword_args(**kwargs):
@ -447,14 +458,14 @@ all_the_args(**kwargs) # equivalent to foo(a=3, b=4)
all_the_args(*args, **kwargs) # equivalent to foo(1, 2, 3, 4, a=3, b=4)
# Function Scope
# Function Scope
x = 5
def setX(num):
# Local var x not the same as global variable x
x = num # => 43
print (x) # => 43
def setGlobalX(num):
global x
print (x) # => 5
@ -501,7 +512,9 @@ class Human(object):
# Basic initializer, this is called when this class is instantiated.
# Note that the double leading and trailing underscores denote objects
# or attributes that are used by python but that live in user-controlled
# namespaces. You should not invent such names on your own.
# namespaces. Methods(or objects or attributes) like: __init__, __str__,
# __repr__ etc. are called magic methods (or sometimes called dunder methods)
# You should not invent such names on your own.
def __init__(self, name):
# Assign the argument to the instance's name attribute
self.name = name
@ -587,7 +600,7 @@ def double_numbers(iterable):
# double_numbers.
# Note range is a generator too. Creating a list 1-900000000 would take lot of
# time to be made
# We use a trailing underscore in variable names when we want to use a name that
# We use a trailing underscore in variable names when we want to use a name that
# would normally collide with a python keyword
range_ = range(1, 900000000)
# will double all numbers until a result >=30 found
@ -635,8 +648,8 @@ print(say(say_please=True)) # Can you buy me a beer? Please! I am poor :(
* [The Official Docs](http://docs.python.org/3/)
* [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/)
* [Python Module of the Week](http://pymotw.com/3/)
* [A Crash Course in Python for Scientists](http://nbviewer.ipython.org/5920182)
* [Python Course](http://www.python-course.eu/index.php)
### Dead Tree

View File

@ -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"

View File

@ -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!
;; for collections use `equal?'
(equal? (list 'a 'b) (list 'a 'b)) ; => #t
(equal? (list 'a 'b) (list 'b 'a)) ; => #f
(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
; Its 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
;; `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

284
ru-ru/bash-ru.html.markdown Normal file
View File

@ -0,0 +1,284 @@
---
category: tool
tool: bash
contributors:
- ["Max Yankov", "https://github.com/golergka"]
- ["Darren Lin", "https://github.com/CogBear"]
- ["Alexandre Medeiros", "http://alemedeiros.sdf.org"]
- ["Denis Arh", "https://github.com/darh"]
- ["akirahirose", "https://twitter.com/akirahirose"]
- ["Anton Strömkvist", "http://lutic.org/"]
- ["Rahil Momin", "https://github.com/iamrahil"]
- ["Gregrory Kielian", "https://github.com/gskielian"]
- ["Etan Reisner", "https://github.com/deryni"]
translators:
- ["Andrey Samsonov", "https://github.com/kryzhovnik"]
- ["Andre Polykanine", "https://github.com/Oire"]
filename: LearnBash-ru.sh
lang: ru-ru
---
Bash - это командная оболочка unix (unix shell), которая распространялась как оболочка для операционной системы GNU и используется в качестве оболочки по умолчанию для Linux и Mac OS X.
Почти все нижеприведенные примеры могут быть частью shell-скриптов или исполнены напрямую в shell.
[Подробнее.](http://www.gnu.org/software/bash/manual/bashref.html)
```bash
#!/bin/bash
# Первая строка скрипта - это shebang, который сообщает системе, как исполнять
# этот скрипт: http://en.wikipedia.org/wiki/Shebang_(Unix)
# Как вы уже поняли, комментарии начинаются с #. Shebang - тоже комментарий.
# Простой пример hello world:
echo Hello world!
# Отдельные команды начинаются с новой строки или разделяются точкой с запятой:
echo 'Это первая строка'; echo 'Это вторая строка'
# Вот так объявляется переменная:
VARIABLE="Просто строка"
# но не так:
VARIABLE = "Просто строка"
# Bash решит, что VARIABLE - это команда, которую он должен исполнить,
# и выдаст ошибку, потому что не сможет найти ее.
# и не так:
VARIABLE= 'Просто строка'
# Тут Bash решит, что 'Просто строка' - это команда, которую он должен исполнить,
# и выдаст ошибку, потому что не сможет найти такой команды
# (здесь 'VARIABLE=' выглядит как присвоение значения переменной,
# но только в контексте исполнения команды 'Просто строка').
# Использование переменой:
echo $VARIABLE
echo "$VARIABLE"
echo '$VARIABLE'
# Когда вы используете переменную - присваиваете, экспортируете и т.д. -
# пишите её имя без $. А для получения значения переменной используйте $.
# Заметьте, что ' (одинарные кавычки) не раскрывают переменные в них.
# Подстановка строк в переменные
echo ${VARIABLE/Просто/A}
# Это выражение заменит первую встреченную подстроку "Просто" на "A"
# Взять подстроку из переменной
LENGTH=7
echo ${VARIABLE:0:LENGTH}
# Это выражение вернет только первые 7 символов переменной VARIABLE
# Значение по умолчанию
echo ${FOO:-"DefaultValueIfFOOIsMissingOrEmpty"}
# Это сработает при отсутствующем значении (FOO=) и пустой строке (FOO="");
# ноль (FOO=0) вернет 0.
# Заметьте, что в любом случае значение самой переменной FOO не изменится.
# Встроенные переменные:
# В bash есть полезные встроенные переменные, например
echo "Последнее возвращенное значение: $?"
echo "PID скрипта: $$"
echo "Количество аргументов: $#"
echo "Аргументы скрипта: $@"
echo "Аргументы скрипта, распределённые по отдельным переменным: $1 $2..."
# Чтение аргументов из устройста ввода:
echo "Как Вас зовут?"
read NAME # Обратите внимание, что нам не нужно определять новую переменную
echo Привет, $NAME!
# У нас есть обычная структура if:
# наберите 'man test' для получения подробной информации о форматах условия
if [ $NAME -ne $USER ]
then
echo "Имя не совпадает с именем пользователя"
else
echo "Имя совпадает с именем пользователя"
fi
# Также есть условное исполнение
echo "Исполнится всегда" || echo "Исполнится, если первая команда завершится ошибкой"
echo "Исполнится всегда" && echo "Исполнится, если первая команда выполнится удачно"
# Можно использовать && и || в выражениях if, когда нужно несколько пар скобок:
if [ $NAME == "Steve" ] && [ $AGE -eq 15 ]
then
echo "Исполнится, если $NAME равно Steve И $AGE равно 15."
fi
if [ $NAME == "Daniya" ] || [ $NAME == "Zach" ]
then
echo "Исполнится, если $NAME равно Daniya ИЛИ Zach."
fi
# Выражения обозначаются таким форматом:
echo $(( 10 + 5 ))
# В отличие от других языков программирования, Bash - это командная оболочка,
# а значит, работает в контексте текущей директории.
# Вы можете просматривать файлы и директории в текущей директории командой ls:
ls
# У этой команды есть опции:
ls -l # Показать каждый файл и директорию на отдельной строке
# Результат предыдущей команды может быть направлен на вход следующей.
# Команда grep фильтрует ввод по шаблону.
# Так мы можем просмотреть только *.txt файлы в текущей директории:
ls -l | grep "\.txt"
# Вы можете перенаправить ввод и вывод команды (stdin, stdout и stderr).
# Следующая команда означает: читать из stdin, пока не встретится ^EOF$, и
# перезаписать hello.py следующим строками (до строки "EOF"):
cat > hello.py << EOF
#!/usr/bin/env python
from __future__ import print_function
import sys
print("#stdout", file=sys.stdout)
print("#stderr", file=sys.stderr)
for line in sys.stdin:
print(line, file=sys.stdout)
EOF
# Запуск hello.py с разными вариантами перенаправления потоков
# стандартных ввода, вывода и ошибок:
python hello.py < "input.in"
python hello.py > "output.out"
python hello.py 2> "error.err"
python hello.py > "output-and-error.log" 2>&1
python hello.py > /dev/null 2>&1
# Поток ошибок перезапишет файл, если этот файл существует,
# поэтому, если вы хотите дописывать файл, используйте ">>":
python hello.py >> "output.out" 2>> "error.err"
# Переписать output.txt, дописать error.err и сосчитать строки:
info bash 'Basic Shell Features' 'Redirections' > output.out 2>> error.err
wc -l output.out error.err
# Запустить команду и вывести ее файловый дескриптор (смотрите: man fd)
echo <(echo "#helloworld")
# Перезаписать output.txt строкой "#helloworld":
cat > output.out <(echo "#helloworld")
echo "#helloworld" > output.out
echo "#helloworld" | cat > output.out
echo "#helloworld" | tee output.out >/dev/null
# Подчистить временные файлы с подробным выводом ('-i' - интерактивый режим)
rm -v output.out error.err output-and-error.log
# Команды могут быть подставлены в строку с помощью $( ):
# следующие команды выводят число файлов и директорий в текущей директории.
echo "Здесь $(ls | wc -l) элементов."
# То же самое можно сделать с использованием обратных кавычек,
# но они не могут быть вложенными, поэтому предпочтительно использовать $( ).
echo "Здесь `ls | wc -l` элементов."
# В Bash есть структура case, которая похожа на switch в Java и C++:
case "$VARIABLE" in
# Перечислите шаблоны для условий, которые хотите отловить
0) echo "Тут ноль.";;
1) echo "Тут один.";;
*) echo "Это не пустое значение.";;
esac
# Цикл for перебирает элементы переданные в аргументе:
# Содержимое $VARIABLE будет напечатано три раза.
for VARIABLE in {1..3}
do
echo "$VARIABLE"
done
# Или с использованием "традиционного" синтаксиса цикла for:
for ((a=1; a <= 3; a++))
do
echo $a
done
# Цикл for можно использовать для действий с файлами.
# Запустим команду 'cat' для файлов file1 и file2
for VARIABLE in file1 file2
do
cat "$VARIABLE"
done
# ... или выводом из команд
# Запустим cat для вывода из ls.
for OUTPUT in $(ls)
do
cat "$OUTPUT"
done
# Цикл while:
while [ true ]
do
echo "тело цикла здесь..."
break
done
# Вы можете определять функции
# Определение:
function foo ()
{
echo "Аргументы работают также, как аргументы скрипта: $@"
echo "и: $1 $2..."
echo "Это функция"
return 0
}
# или просто
bar ()
{
echo "Другой способ определить функцию!"
return 0
}
# Вызов функции
foo "Мое имя" $NAME
# Есть много полезных команд, которые нужно знать:
# напечатать последние 10 строк файла file.txt
tail -n 10 file.txt
# напечатать первые 10 строк файла file.txt
head -n 10 file.txt
# отсортировать строки file.txt
sort file.txt
# отобрать или наоборот пропустить повторяющиеся строки (с опцией -d отбирает)
uniq -d file.txt
# напечатать только первую колонку перед символом ','
cut -d ',' -f 1 file.txt
# заменить каждое 'okay' на 'great' в файле file.txt (regex поддерживается)
sed -i 's/okay/great/g' file.txt
# вывести в stdout все строки из file.txt, совпадающие с шаблоном regex;
# этот пример выводит строки, которые начинаются на "foo" и оканчиваются "bar"
grep "^foo.*bar$" file.txt
# передайте опцию -c чтобы вывести число строк, в которых совпал шаблон
grep -c "^foo.*bar$" file.txt
# чтобы искать по строке, а не шаблону regex, используйте fgrep (или grep -F)
fgrep "^foo.*bar$" file.txt
# Читайте встроенную документацию оболочки Bash командой 'help':
help
help help
help for
help return
help source
help .
# Читайте Bash man-документацию
apropos bash
man 1 bash
man bash
# Читайте документацию info (? для помощи)
apropos info | grep '^info.*('
man info
info info
info 5 info
# Читайте bash info документацию:
info bash
info bash 'Bash Features'
info bash 6
info --apropos bash
```

View File

@ -0,0 +1,83 @@
---
language: brainfuck
contributors:
- ["Prajit Ramachandran", "http://prajitr.github.io/"]
- ["Mathias Bynens", "http://mathiasbynens.be/"]
translators:
- ["Dmitry Bessonov", "https://github.com/TheDmitry"]
lang: ru-ru
---
Brainfuck (пишется маленькими буквами, кроме начала предложения) - это очень
маленький Тьюринг-полный язык программирования лишь с 8 командами.
```
Любой символ, кроме "><+-.,[]", игнорируется, за исключением кавычек.
Brainfuck представлен массивом из 30000 ячеек, инициализированных нулями,
и указателем с позицией в текущей ячейке.
Всего восемь команд:
+ : Увеличивает значение на единицу в текущей ячейке.
- : Уменьшает значение на единицу в текущей ячейке.
> : Смещает указатель данных на следующую ячейку (ячейку справа).
< : Смещает указатель данных на предыдущую ячейку (ячейку слева).
. : Печатает ASCII символ из текущей ячейки (напр. 65 = 'A').
, : Записывает один входной символ в текущую ячейку.
[ : Если значение в текущей ячейке равно нулю, то пропустить все команды
до соответствующей ] . В противном случае, перейти к следующей инструкции.
] : Если значение в текущей ячейке равно нулю, то перейти к следующей инструкции.
В противном случае, вернуться назад к соответствующей [ .
[ и ] образуют цикл while. Естественно, они должны быть сбалансированы.
Давайте рассмотрим некоторые базовые brainfuck-программы.
++++++ [ > ++++++++++ < - ] > +++++ .
Эта программа выводит букву 'A'. Сначала программа увеличивает значение
ячейки №1 до 6. Ячейка №1 будет использоваться циклом. Затем программа входит
в цикл ([) и переходит к ячейке №2. Ячейка №2 увеличивается до 10, переходим
назад к ячейке №1 и уменьшаем ячейку №1. Этот цикл проходит 6 раз (ячейка №1
уменьшается до нуля, и с этого места пропускает инструкции до соответствующей ]
и идет дальше).
В этот момент мы находимся в ячейке №1, которая имеет значение 0, значение
ячейки №2 пока 60. Мы переходим на ячейку №2, увеличиваем 5 раз, до значения 65,
и затем выводим значение ячейки №2. Код 65 является символом 'A' в кодировке ASCII,
так что 'A' выводится на терминал.
, [ > + < - ] > .
Данная программа считывает символ из пользовательского ввода и копирует символ
в ячейку №1. Затем мы начинаем цикл. Переходим к ячейке №2, увеличиваем значение
ячейки №2, идем назад к ячейке №1 и уменьшаем значение ячейки №1. Это продолжается
до тех пор, пока ячейка №1 не равна 0, а ячейка №2 сохраняет старое значение
ячейки №1. Мы завершаем цикл на ячейке №1, поэтому переходим в ячейку №2 и
затем выводим символ ASCII.
Также имейте в виду, что пробелы здесь исключительно для читабельности. Вы можете
легко написать и так:
,[>+<-]>.
Попытайтесь разгадать, что следующая программа делает:
,>,< [ > [ >+ >+ << -] >> [- << + >>] <<< -] >>
Программа принимает два числа на вход и умножает их.
Суть в том, что программа сначала читает два ввода. Затем начинается внешний цикл,
сохраняя ячейку №1. Затем программа перемещается в ячейку №2, и начинается
внутренний цикл с сохранением ячейки №2, увеличивая ячейку №3. Однако появляется
проблема: В конце внутреннего цикла ячейка №2 равна нулю. В этом случае,
внутренний цикл не будет работать уже в следующий раз. Чтобы решить эту проблему,
мы также увеличим ячейку №4, а затем копируем ячейку №4 в ячейку №2.
Итак, ячейка №3 - результат.
```
Это и есть brainfuck. Не так уж сложно, правда? Забавы ради, вы можете написать
свою собственную brainfuck-программу или интерпретатор на другом языке.
Интерпретатор достаточно легко реализовать, но если вы мазохист, попробуйте
написать brainfuck-интерпретатор... на языке brainfuck.

View File

@ -65,7 +65,7 @@ func beyondHello() {
learnTypes() // < y minutes, learn more!
}
// Функция имеющая входные параметры и возврат нескольких значений.
// Функция, имеющая входные параметры и возвращающая несколько значений.
func learnMultiple(x, y int) (sum, prod int) {
return x + y, x * y // Возврат двух значений.
}

View File

@ -0,0 +1,516 @@
---
language: javascript
contributors:
- ["Adam Brenecki", "http://adam.brenecki.id.au"]
- ["Ariel Krakowski", "http://www.learneroo.com"]
filename: javascript-ru.js
translators:
- ["Alexey Gonchar", "http://github.com/finico"]
- ["Andre Polykanine", "https://github.com/Oire"]
lang: ru-ru
---
JavaScript был создан в 1995 году Бренданом Айком, работавшим в компании Netscape.
Изначально он был задуман как простой язык сценариев для веб-сайтов, дополняющий
Java для более сложных веб-приложений, но его тесная интеграция с веб-страницами
и встроенная поддержка браузерами привели к тому, что он стал более распространённым,
чем Java в веб-интерфейсах.
JavaScript не ограничивается только веб-браузером: например, Node.js, программная
платформа, позволяющая выполнять JavaScript, основанная на движке V8 от браузера
Google Chrome, становится все более популярной.
```js
// Си-подобные комментарии. Однострочные комментарии начинаются с двух символов слэш,
/* а многострочные комментарии начинаются с последовательности слэш-звёздочка
и заканчиваются символами звёздочка-слэш */
// Инструкции могут заканчиваться точкой с запятой ;
doStuff();
// ... но она необязательна, так как точки с запятой автоматически вставляются
// везде, где есть символ новой строки, за некоторыми исключениями.
doStuff()
// Так как эти исключения могут привести к неожиданным результатам, мы будем всегда
// использовать точку с запятой в этом руководстве.
///////////////////////////////////
// 1. Числа, Строки и Операторы
// В JavaScript только один тип числа (64-bit IEEE 754 double).
// Он имеет 52-битную мантиссу, которой достаточно для хранения целых чисел
// с точностью вплоть до 9✕10¹⁵.
3; // = 3
1.5; // = 1.5
// Некоторые простые арифметические операции работают так, как вы ожидаете.
1 + 1; // = 2
0.1 + 0.2; // = 0.30000000000000004 (а некоторые - нет)
8 - 1; // = 7
10 * 2; // = 20
35 / 5; // = 7
// Включая деление с остатком.
5 / 2; // = 2.5
// Побитовые операции также имеются; когда вы проводите такую операцию,
// ваше число с плавающей запятой переводится в целое со знаком
// длиной *до* 32 разрядов.
1 << 2; // = 4
// Приоритет в выражениях можно явно задать скобками.
(1 + 3) * 2; // = 8
// Есть три специальных значения, которые не являются реальными числами:
Infinity; // "бесконечность", например, результат деления на 0
-Infinity; // "минус бесконечность", результат деления отрицательного числа на 0
NaN; // "не число", например, результат деления 0/0
// Существует также логический тип.
true;
false;
// Строки создаются при помощи двойных или одинарных кавычек.
'абв';
"Привет, мир!";
// Для логического отрицания используется восклицательный знак.
!true; // = false
!false; // = true
// Строгое равенство ===
1 === 1; // = true
2 === 1; // = false
// Строгое неравенство !==
1 !== 1; // = false
2 !== 1; // = true
// Другие операторы сравнения
1 < 10; // = true
1 > 10; // = false
2 <= 2; // = true
2 >= 2; // = true
// Строки объединяются при помощи оператора +
"привет, " + "мир!"; // = "Привет, мир!"
// и сравниваются при помощи < и >
"a" < "b"; // = true
// Проверка равенства с приведением типов осуществляется двойным символом равно
"5" == 5; // = true
null == undefined; // = true
// ...если только не использовать ===
"5" === 5; // = false
null === undefined; // = false
// ...приведение типов может привести к странному поведению...
13 + !0; // 14
"13" + !0; // '13true'
// Вы можете получить доступ к любому символу строки, используя метод charAt
"Это строка".charAt(0); // = 'Э'
// ...или используйте метод substring, чтобы получить более крупные части
"Привет, мир".substring(0, 6); // = "Привет"
// length - это свойство, для его получения не нужно использовать ()
"Привет".length; // = 6
// Также есть null и undefined
null; // Намеренное отсутствие значения
undefined; // используется для обозначения переменных, не имеющих
// присвоенного значения (хотя непосредственно undefined
// является значением)
// false, null, undefined, NaN, 0 и "" — это ложь; всё остальное - истина.
// Следует отметить, что 0 — это ложь, а "0" — истина, несмотря на то, что
// 0 == "0".
///////////////////////////////////
// 2. Переменные, Массивы и Объекты
// Переменные объявляются при помощи ключевого слова var. JavaScript — язык с
// динамической типизацией, поэтому не нужно явно указывать тип. Для присваивания
// значения переменной используется символ =
var someVar = 5;
// если вы пропустите слово var, вы не получите сообщение об ошибке, ...
someOtherVar = 10;
// ...но ваша переменная будет создана в глобальном контексте, а не в текущем,
// где вы ее объявили.
// Переменным, объявленным без присвоения, устанавливается значение undefined.
var someThirdVar; // = undefined
// У математических операций есть сокращённые формы:
someVar += 5; // как someVar = someVar + 5; someVar теперь имеет значение 10
someVar *= 10; // теперь someVar имеет значение 100
// Ещё более краткая запись увеличения и уменьшения на единицу:
someVar++; // теперь someVar имеет значение 101
someVar--; // вернулись к 100
// Массивы — это нумерованные списки, содержащие значения любого типа.
var myArray = ["Привет", 45, true];
// Их элементы могут быть доступны при помощи синтаксиса с квадратными скобками.
// Индексы массивов начинаются с нуля.
myArray[1]; // = 45
// Массивы можно изменять, как и их длину,
myArray.push("Мир");
myArray.length; // = 4
// добавлять и редактировать определённый элемент
myArray[3] = "Привет";
// Объекты в JavaScript похожи на словари или ассоциативные массивы в других
// языках: неупорядоченный набор пар ключ-значение.
var myObj = {key1: "Привет", key2: "Мир"};
// Ключи — это строки, но кавычки необязательны, если строка удовлетворяет
// ограничениям для имён переменных. Значения могут быть любых типов.
var myObj = {myKey: "myValue", "my other key": 4};
// Атрибуты объектов можно также получить, используя квадратные скобки
myObj["my other key"]; // = 4
// или через точку, при условии, что ключ является допустимым идентификатором.
myObj.myKey; // = "myValue"
// Объекты изменяемы; можно изменять значения и добавлять новые ключи.
myObj.myThirdKey = true;
// Если вы попытаетесь получить доступ к несуществующему значению,
// вы получите undefined.
myObj.myFourthKey; // = undefined
///////////////////////////////////
// 3. Логика и управляющие конструкции.
// Синтаксис для этого раздела почти такой же, как в Java.
// Условная конструкция работает, как и следовало ожидать,
var count = 1;
if (count == 3) {
// выполняется, если count равен 3
} else if (count == 4) {
// выполняется, если count равен 4
} else {
// выполняется, если не 3 и не 4
}
// ...как и цикл while.
while (true){
// Бесконечный цикл!
}
// Цикл do-while такой же, как while, но он всегда выполняется хотя бы раз.
var input
do {
input = getInput();
} while (!isValid(input))
// цикл for такой же, как в C и Java:
// инициализация; условие; шаг.
for (var i = 0; i < 5; i++) {
// выполнится 5 раз
}
// && — это логическое И, || — это логическое ИЛИ
if (house.size == "big" && house.color == "blue") {
house.contains = "bear";
}
if (color == "red" || color == "blue") {
// цвет красный или синий
}
// && и || используют сокращённое вычисление, что полезно
// для задания значений по умолчанию.
var name = otherName || "default";
// Оператор switch выполняет проверку на равенство при помощи ===
// используйте break, чтобы прервать выполнение после каждого case,
// или выполнение пойдёт далее даже после правильного варианта.
grade = 4;
switch (grade) {
case 5:
console.log("Отлично");
break;
case 4:
console.log("Хорошо");
break;
case 3:
console.log("Можете и лучше");
break;
default:
console.log("Ой-вей!");
break;
}
///////////////////////////////////
// 4. Функции, Область видимости и Замыкания
// Функции в JavaScript объявляются при помощи ключевого слова function.
function myFunction(thing) {
return thing.toUpperCase();
}
myFunction("foo"); // = "FOO"
// Обратите внимание, что значение, которое будет возвращено, должно начинаться
// на той же строке, что и ключевое слово return, в противном случае вы будете
// всегда возвращать undefined по причине автоматической вставки точки с запятой.
// Следите за этим при использовании стиля форматирования Allman.
function myFunction()
{
return // <- здесь точка с запятой вставится автоматически
{
thisIsAn: 'object literal'
}
}
myFunction(); // = undefined
// В JavaScript функции — это объекты первого класса, поэтому они могут быть
// присвоены различным именам переменных и передаваться другим функциям
// в качестве аргументов, например, когда назначается обработчик события:
function myFunction() {
// этот код будет вызван через 5 секунд
}
setTimeout(myFunction, 5000);
// Примечание: setTimeout не является частью языка, но реализован в браузерах и Node.js
// Функции не обязательно должны иметь имя при объявлении — вы можете написать
// анонимное определение функции непосредственно в аргументе другой функции.
setTimeout(function() {
// этот код будет вызван через 5 секунд
}, 5000);
// В JavaScript есть область видимости; функции имеют свою область
// видимости, а другие блоки — нет.
if (true) {
var i = 5;
}
i; // = 5, а не undefined, как ожидалось бы в языках с блочной областью видимости
// Это привело к общепринятому шаблону "самозапускающихся анонимных функций",
// которые препятствуют проникновению переменных в глобальную область видимости
(function() {
var temporary = 5;
// Мы можем получить доступ к глобальной области для записи в «глобальный объект»,
// который в веб-браузере всегда window. Глобальный объект может иметь другое
// имя в таких платформах, как Node.js
window.permanent = 10;
})();
temporary; // вызовет сообщение об ошибке с типом ReferenceError
permanent; // = 10
// Одной из самых мощных возможностей JavaScript являются замыкания. Если функция
// определена внутри другой функции, то внутренняя функция имеет доступ к
// переменным внешней функции даже после того, как контекст выполнения выйдет из
// внешней функции.
function sayHelloInFiveSeconds(name) {
var prompt = "Привет, " + name + "!";
// Внутренние функции по умолчанию помещаются в локальную область видимости,
// как если бы они были объявлены с помощью var.
function inner() {
alert(prompt);
}
setTimeout(inner, 5000);
// setTimeout асинхронна, поэтому функция sayHelloInFiveSeconds сразу выйдет,
// после чего setTimeout вызовет функцию inner. Однако поскольку функция inner
// «замкнута» вокруг sayHelloInFiveSeconds, она по-прежнему имеет доступ к переменной prompt
// на то время, когда она наконец будет вызвана.
}
sayHelloInFiveSeconds("Адам"); // Через 5 с откроется окно «Привет, Адам!»
///////////////////////////////////
// 5. Подробнее об объектах; конструкторы и прототипы
// Объекты могут содержать в себе функции.
var myObj = {
myFunc: function() {
return "Привет, мир!";
}
};
myObj.myFunc(); // = "Привет, мир!"
// Когда вызываются функции, прикреплённые к объекту, они могут получить доступ
// к этому объекту с помощью ключевого слова this.
myObj = {
myString: "Привет, мир!",
myFunc: function() {
return this.myString;
}
};
myObj.myFunc(); // = "Привет, мир!"
// Значение this зависит от того, как функция вызывается,
// а не от того, где она определена. Таким образом, наша функция не работает,
// если она вызывается не в контексте объекта.
var myFunc = myObj.myFunc;
myFunc(); // = undefined
// И наоборот, функция может быть присвоена объекту и получать доступ к нему
// через this, даже если она не была прикреплена к нему при объявлении.
var myOtherFunc = function() {
}
myObj.myOtherFunc = myOtherFunc;
myObj.myOtherFunc(); // = "ПРИВЕТ, МИР!"
// Мы можем также указать контекст для выполнения функции при её вызове,
// используя call или apply.
var anotherFunc = function(s) {
return this.myString + s;
}
anotherFunc.call(myObj, " И привет, Луна!"); // = "Привет, мир! И привет, Луна!"
// Функция apply почти такая же, но принимает в качестве списка аргументов массив.
anotherFunc.apply(myObj, [" И привет, Солнце!"]); // = "Привет, мир! И привет, Солнце!"
// Это полезно при работе с функцией, которая принимает последовательность
// аргументов, а вы хотите передать массив.
Math.min(42, 6, 27); // = 6
Math.min([42, 6, 27]); // = NaN (Ой-ой!)
Math.min.apply(Math, [42, 6, 27]); // = 6
// Но call и apply — только временные. Когда мы хотим связать функцию с объектом,
// мы можем использовать bind.
var boundFunc = anotherFunc.bind(myObj);
boundFunc(" И привет, Сатурн!"); // = "Привет, мир! И привет, Сатурн!"
// Bind также может использоваться для частичного применения (каррирования) функции
var product = function(a, b) { return a * b; }
var doubler = product.bind(this, 2);
doubler(8); // = 16
// Когда вы вызываете функцию с помощью ключевого слова new, создается новый объект,
// доступный функции при помощи this. Такие функции называют конструкторами.
var MyConstructor = function() {
this.myNumber = 5;
}
myNewObj = new MyConstructor(); // = {myNumber: 5}
myNewObj.myNumber; // = 5
// У каждого объекта в JavaScript есть прототип. Когда вы хотите получить
// доступ к свойству объекта, которое не существует в этом объекте, интерпретатор
// будет искать это свойство в прототипе.
// Некоторые реализации языка позволяют получить доступ к прототипу объекта
// через «магическое» свойство __proto__. Несмотря на то, что это может быть полезно
// для понимания прототипов, это не часть стандарта; мы увидим стандартные способы
// использования прототипов позже.
var myObj = {
myString: "Привет, мир!"
};
var myPrototype = {
meaningOfLife: 42,
myFunc: function() {
return this.myString.toLowerCase()
}
};
myObj.__proto__ = myPrototype;
myObj.meaningOfLife; // = 42
// Для функций это тоже работает.
myObj.myFunc(); // = "Привет, мир!"
// Если интерпретатор не найдёт свойство в прототипе, то продожит поиск
// в прототипе прототипа и так далее.
myPrototype.__proto__ = {
myBoolean: true
};
myObj.myBoolean; // = true
// Здесь не участвует копирование; каждый объект хранит ссылку на свой прототип.
// Это означает, что мы можем изменить прототип, и наши изменения будут отражены везде.
myPrototype.meaningOfLife = 43;
myObj.meaningOfLife; // = 43
// Мы упомянули, что свойство __proto__ нестандартно, и нет никакого стандартного
// способа, чтобы изменить прототип существующего объекта. Однако есть два
// способа создать новый объект с заданным прототипом.
// Первый способ — это Object.create, который появился в JavaScript недавно,
// а потому доступен ещё не во всех реализациях языка.
var myObj = Object.create(myPrototype);
myObj.meaningOfLife; // = 43
// Второй способ, который работает везде, имеет дело с конструкторами.
// У конструкторов есть свойство с именем prototype. Это *не* прототип
// функции-конструктора; напротив, это прототип для новых объектов, которые
// будут созданы с помощью этого конструктора и ключевого слова new.
MyConstructor.prototype = {
myNumber: 5,
getMyNumber: function() {
return this.myNumber;
}
};
var myNewObj2 = new MyConstructor();
myNewObj2.getMyNumber(); // = 5
myNewObj2.myNumber = 6
myNewObj2.getMyNumber(); // = 6
// У встроенных типов, таких, как строки и числа, также есть конструкторы, которые
// создают эквивалентные объекты-обёртки.
var myNumber = 12;
var myNumberObj = new Number(12);
myNumber == myNumberObj; // = true
// За исключением того, что они не в точности равны.
typeof myNumber; // = 'number'
typeof myNumberObj; // = 'object'
myNumber === myNumberObj; // = false
if (0) {
// Этот код не выполнится, потому что 0 - это ложь.
}
if (Number(0)) {
// Этот код *выполнится*, потому что Number(0) истинно.
}
// Впрочем, объекты-обёртки и встроенные типы имеют общие прототипы,
// поэтому вы можете расширить функционал строк, например:
String.prototype.firstCharacter = function() {
return this.charAt(0);
}
"abc".firstCharacter(); // = "a"
// Это часто используется в т.н. полифилах, которые реализуют новые возможности
// JavaScript в старой реализации языка, так что они могут быть использованы в
// старых средах, таких, как устаревшие браузеры.
// Например, мы упомянули, что Object.create доступен не во всех реализациях, но
// мы сможем использовать его с помощью такого полифила:
if (Object.create === undefined) { // не перезаписываем метод, если он существует
Object.create = function(proto) {
// создаём временный конструктор с правильным прототипом
var Constructor = function(){};
Constructor.prototype = proto;
// затем используем его для создания нового,
// правильно прототипированного объекта
return new Constructor();
}
}
```
## Что ещё почитать
[Современный учебник JavaScript (Илья Кантор)](http://learn.javascript.ru) —
качественный учебник по JavaScript на русском языке.
[Mozilla Developer Network](https://developer.mozilla.org/ru/docs/Web/JavaScript) —
предоставляет отличную документацию для JavaScript, как он используется в браузерах.
Кроме того, это вики, поэтому, если вы знаете больше, вы можете помочь другим,
делясь своими знаниями.
[JavaScript Garden](http://bonsaiden.github.io/JavaScript-Garden/ru/) — это
подробное руководство по всем неинтуитивным особенностей языка.
[Stack Overflow](http://stackoverflow.com/questions/tagged/javascript) — можно
найти ответ почти на любой ваш вопрос, а если его нет, то задать вопрос самому.

View File

@ -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."
}
```

425
ru-ru/lua-ru.html.markdown Normal file
View File

@ -0,0 +1,425 @@
---
language: Lua
filename: learnlua-ru.lua
contributors:
- ["Tyler Neylon", "http://tylerneylon.com/"]
translators:
- ["Max Solomonov", "https://vk.com/solomonovmaksim"]
- ["Max Truhonin", "https://vk.com/maximmax42"]
- ["Konstantin Gromyko", "https://vk.com/id0x1765d79"]
- ["Stanislav Gromov", "https://vk.com/id156354391"]
lang: ru-ru
---
```lua
-- Два дефиса начинают однострочный комментарий.
--[[
Добавление двух квадратных скобок
делает комментарий многострочным.
--]]
--------------------------------------------------------------------------------
-- 1. Переменные, циклы и условия.
--------------------------------------------------------------------------------
num = 42 -- Все числа имеют тип double.
-- Не волнуйтесь, в 64-битных double 52 бита
-- отведено под хранение целой части числа;
-- точность не является проблемой для
-- целочисленных значений, занимающих меньше 52 бит.
s = 'walternate' -- Неизменные строки, как в Python.
t = "Двойные кавычки также приветствуются"
u = [[ Двойные квадратные скобки
начинают и заканчивают
многострочные значения.]]
t = nil -- Удаляет определение переменной t; в Lua есть сборка мусора.
-- Блоки обозначаются ключевыми словами, такими как do/end:
while num < 50 do
num = num + 1 -- Операторов ++ и += нет.
end
-- Ветвление "если":
if num > 40 then
print('больше 40')
elseif s ~= 'walternate' then -- ~= обозначает "не равно".
-- Проверка равенства это ==, как в Python; работает для строк.
io.write('не больше 40\n') -- По умолчанию вывод в stdout.
else
-- По умолчанию переменные являются глобальными.
thisIsGlobal = 5 -- Стиль CamelСase является общим.
-- Как сделать переменную локальной:
local line = io.read() -- Считывает введённую строку.
-- Для конкатенации строк используется оператор .. :
print('Зима пришла, ' .. line)
end
-- Неопределённые переменные возвращают nil.
-- Этот пример не является ошибочным:
foo = anUnknownVariable -- Теперь foo = nil.
aBoolValue = false
-- Только значения nil и false являются ложными; 0 и '' являются истинными!
if not aBoolValue then print('это значение ложно') end
-- Для 'or' и 'and' действует принцип "какой оператор дальше,
-- тот и применяется". Это действует аналогично оператору a?b:c в C/js:
ans = aBoolValue and 'yes' or 'no' --> 'no'
karlSum = 0
for i = 1, 100 do -- Здесь указан диапазон, ограниченный с двух сторон.
karlSum = karlSum + i
end
-- Используйте "100, 1, -1" как нисходящий диапазон:
fredSum = 0
for j = 100, 1, -1 do fredSum = fredSum + j end
-- В основном, диапазон устроен так: начало, конец[, шаг].
-- Другая конструкция цикла:
repeat
print('путь будущего')
num = num - 1
until num == 0
--------------------------------------------------------------------------------
-- 2. Функции.
--------------------------------------------------------------------------------
function fib(n)
if n < 2 then return n end
return fib(n - 2) + fib(n - 1)
end
-- Вложенные и анонимные функции являются нормой:
function adder(x)
-- Возращаемая функция создаётся, когда вызывается функция adder,
-- и запоминает значение переменной x:
return function (y) return x + y end
end
a1 = adder(9)
a2 = adder(36)
print(a1(16)) --> 25
print(a2(64)) --> 100
-- Возвраты, вызовы функций и присвоения работают со списками,
-- которые могут иметь разную длину.
-- Лишние получатели принимают значение nil, а лишние значения игнорируются.
x, y, z = 1, 2, 3, 4
-- Теперь x = 1, y = 2, z = 3, а 4 просто отбрасывается.
function bar(a, b, c)
print(a, b, c)
return 4, 8, 15, 16, 23, 42
end
x, y = bar('zaphod') --> выводит "zaphod nil nil"
-- Теперь x = 4, y = 8, а значения 15..42 отбрасываются.
-- Функции могут быть локальными и глобальными. Эти строки делают одно и то же:
function f(x) return x * x end
f = function (x) return x * x end
-- Эти тоже:
local function g(x) return math.sin(x) end
local g = function(x) return math.sin(x) end
-- Эквивалентно для local function g(x)..., однако ссылки на g
-- в теле функции не будут работать, как ожидалось.
local g; g = function (x) return math.sin(x) end
-- 'local g' будет прототипом функции.
-- Кстати, тригонометрические функции работают с радианами.
-- Вызов функции с одним строковым параметром не требует круглых скобок:
print 'hello' -- Работает без ошибок.
-- Вызов функции с одним табличным параметром также
-- не требует круглых скобок (про таблицы в след. части):
print {} -- Тоже сработает.
--------------------------------------------------------------------------------
-- 3. Таблицы.
--------------------------------------------------------------------------------
-- Таблица = единственная составная структура данных в Lua;
-- представляет собой ассоциативный массив.
-- Подобно массивам в PHP или объектам в JS, они представляют собой
-- хеш-таблицы, которые также можно использовать в качестве списков.
-- Использование словарей:
-- Литералы имеют ключ по умолчанию:
t = {key1 = 'value1', key2 = false}
-- Строковые ключи используются, как в точечной нотации в JS:
print(t.key1) -- Печатает 'value1'.
t.newKey = {} -- Добавляет новую пару ключ/значение.
t.key2 = nil -- Удаляет key2 из таблицы.
-- Литеральная нотация для любого значения ключа (кроме nil):
u = {['@!#'] = 'qbert', [{}] = 1729, [6.28] = 'tau'}
print(u[6.28]) -- пишет "tau"
-- Ключ соответствует значению для чисел и строк, но при
-- использовании таблицы в качестве ключа берётся её экземпляр.
a = u['@!#'] -- Теперь a = 'qbert'.
b = u[{}] -- Вы могли ожидать 1729, но получится nil:
-- b = nil, т.к. ключ не будет найден.
-- Это произойдёт потому, что за ключ мы использовали не тот же самый объект,
-- который был использован для сохранения оригинального значения.
-- Поэтому строки и числа удобнее использовать в качестве ключей.
-- Вызов функции с одной таблицей в качестве аргумента
-- не требует круглых скобок:
function h(x) print(x.key1) end
h{key1 = 'Sonmi~451'} -- Печатает 'Sonmi~451'.
for key, val in pairs(u) do -- Цикл по таблице.
print(key, val)
end
-- _G - это таблица со всеми глобалями.
print(_G['_G'] == _G) -- Печатает 'true'.
-- Использование таблиц, как списков / массивов:
-- Список значений с неявно заданными целочисленными ключами:
v = {'value1', 'value2', 1.21, 'gigawatts'}
for i = 1, #v do -- #v - размер списка v.
print(v[i]) -- Нумерация начинается с 1 !!
end
-- Список не является отдельным типом. v - всего лишь таблица
-- с последовательными целочисленными ключами, воспринимаемая как список.
--------------------------------------------------------------------------------
-- 3.1 Метатаблицы и метаметоды.
--------------------------------------------------------------------------------
-- Таблицу можно связать с метатаблицей, задав ей поведение, как при
-- перегрузке операторов. Позже мы увидим, что метатаблицы поддерживают
-- поведение, как в js-прототипах.
f1 = {a = 1, b = 2} -- Представляет дробь a/b.
f2 = {a = 2, b = 3}
-- Это не сработает:
-- s = f1 + f2
metafraction = {}
function metafraction.__add(f1, f2)
local sum = {}
sum.b = f1.b * f2.b
sum.a = f1.a * f2.b + f2.a * f1.b
return sum
end
setmetatable(f1, metafraction)
setmetatable(f2, metafraction)
s = f1 + f2 -- вызвать __add(f1, f2) на метатаблице от f1
-- f1, f2 не имеют ключа для своих метатаблиц в отличии от прототипов в js,
-- нужно получить его через getmetatable(f1). Метатаблица - обычная таблица
-- поэтому с ключами, известными для Lua (например, __add).
-- Но следущая строка будет ошибочной т.к в s нет метатаблицы:
-- t = s + s
-- Похожий на классы подход, приведенный ниже, поможет это исправить.
-- __index перегружает в метатаблице просмотр через точку:
defaultFavs = {animal = 'gru', food = 'donuts'}
myFavs = {food = 'pizza'}
setmetatable(myFavs, {__index = defaultFavs})
eatenBy = myFavs.animal -- работает! спасибо, мета-таблица.
--------------------------------------------------------------------------------
-- При неудаче прямой табличный поиск попытается использовать
-- значение __index в метатаблице, причём это рекурсивно.
-- Значение __index также может быть функцией
-- function(tbl, key) для настраиваемого поиска.
-- Значения типа __index, __add, ... называются метаметодами.
-- Ниже приведён полный список метаметодов.
-- __add(a, b) для a + b
-- __sub(a, b) для a - b
-- __mul(a, b) для a * b
-- __div(a, b) для a / b
-- __mod(a, b) для a % b
-- __pow(a, b) для a ^ b
-- __unm(a) для -a
-- __concat(a, b) для a .. b
-- __len(a) для #a
-- __eq(a, b) для a == b
-- __lt(a, b) для a < b
-- __le(a, b) для a <= b
-- __index(a, b) <функция или таблица> для a.b
-- __newindex(a, b, c) для a.b = c
-- __call(a, ...) для a(...)
--------------------------------------------------------------------------------
-- 3.2 Классоподобные таблицы и наследование.
--------------------------------------------------------------------------------
-- В Lua нет поддержки классов на уровне языка,
-- однако существуют разные способы их создания с помощью
-- таблиц и метатаблиц.
-- Ниже приведён один из таких способов.
Dog = {} -- 1.
function Dog:new() -- 2.
local newObj = {sound = 'woof'} -- 3.
self.__index = self -- 4.
return setmetatable(newObj, self) -- 5.
end
function Dog:makeSound() -- 6.
print('I say ' .. self.sound)
end
mrDog = Dog:new() -- 7.
mrDog:makeSound() -- 'I say woof' -- 8.
-- 1. Dog похоже на класс, но на самом деле это таблица.
-- 2. "function tablename:fn(...)" - то же самое, что и
-- "function tablename.fn(self, ...)", просто : добавляет первый аргумент
-- перед собой. См. пункты 7 и 8, чтобы понять, как self получает значение.
-- 3. newObj - это экземпляр класса Dog.
-- 4. "self" - экземпляр класса. Зачастую self = Dog, но с помощью наследования
-- это можно изменить. newObj получит свои функции, когда мы установим
-- метатаблицу для newObj и __index для self на саму себя.
-- 5. Напоминание: setmetatable возвращает первый аргумент.
-- 6. : работает, как в пункте 2, но в этот раз мы ожидаем,
-- что self будет экземпляром, а не классом.
-- 7. То же самое, что и Dog.new(Dog), поэтому self = Dog в new().
-- 8. То же самое, что mrDog.makeSound(mrDog); self = mrDog.
--------------------------------------------------------------------------------
-- Пример наследования:
LoudDog = Dog:new() -- 1.
function LoudDog:makeSound()
local s = self.sound .. ' ' -- 2.
print(s .. s .. s)
end
seymour = LoudDog:new() -- 3.
seymour:makeSound() -- 'woof woof woof' -- 4.
--------------------------------------------------------------------------------
-- 1. LoudDog получит методы и переменные класса Dog.
-- 2. В self будет ключ 'sound' из new(), см. пункт 3.
-- 3. То же самое, что и "LoudDog.new(LoudDog)", конвертированное
-- в "Dog.new(LoudDog)", поскольку в LoudDog нет ключа 'new',
-- но в его метатаблице есть "__index = Dog".
-- Результат: Метатаблицей для seymour стала LoudDog,
-- а "LoudDog.__index = Dog". Поэтому seymour.key будет равно
-- seymour.key, LoudDog.key, Dog.key, в зависимости от того,
-- какая таблица будет первой с заданным ключом.
-- 4. Ключ 'makeSound' находится в LoudDog;
-- то же самое, что и "LoudDog.makeSound(seymour)".
-- При необходимости функция new() в подклассе
-- может быть похожа на аналог в базовом классе.
function LoudDog:new()
local newObj = {}
-- установить newObj
self.__index = self
return setmetatable(newObj, self)
end
--------------------------------------------------------------------------------
-- 4. Модули.
--------------------------------------------------------------------------------
--[[ Я закомментировал этот раздел, чтобы остальная часть скрипта осталась
-- работоспособной.
```
```lua
-- Предположим, файл mod.lua будет выглядеть так:
local M = {}
local function sayMyName()
print('Hrunkner')
end
function M.sayHello()
print('Привет, ')
sayMyName()
end
return M
-- Другой файл может использовать функционал mod.lua:
local mod = require('mod') -- Запустим файл mod.lua.
-- require - стандартный способ подключения модулей.
-- require ведёт себя так: (если не кэшировано, см. ниже)
local mod = (function ()
<содержимое mod.lua>
end)()
-- Файл mod.lua воспринимается, как тело функции, поэтому
-- все локальные переменные и функции внутри него не видны за его пределами.
-- Это работает, так как здесь mod = M в mod.lua:
mod.sayHello() -- Выведет "Привет, Hrunkner".
-- Это будет ошибочным; sayMyName доступна только в mod.lua:
mod.sayMyName() -- ошибка
-- Значения, возвращаемые require, кэшируются,
-- поэтому содержимое файла выполняется только 1 раз,
-- даже если он подключается с помощью require много раз.
-- Предположим, mod2.lua содержит "print('Hi!')".
local a = require('mod2') -- Выведет "Hi!"
local b = require('mod2') -- Ничего не выведет; a=b.
-- dofile, в отличии от require, работает без кэширования:
dofile('mod2') --> Hi!
dofile('mod2') --> Hi! (запустится снова)
-- loadfile загружает файл, но не запускает его.
f = loadfile('mod2') -- Вызов f() запустит содержимое mod2.lua.
-- loadstring - это loadfile для строк.
g = loadstring('print(343)') -- Вернет функцию.
g() -- Напишет 343.
--]]
```
## Примечание (от автора)
Мне было интересно изучить Lua, чтобы делать игры при помощи <a href="http://love2d.org/">игрового движка LÖVE</a>.
Я начинал с <a href="http://nova-fusion.com/2012/08/27/lua-for-programmers-part-1/">BlackBulletIV's Lua for programmers</a>.
Затем я прочитал официальную <a href="http://www.lua.org/pil/contents.html">Документацию по Lua</a>.
Также может быть полезной <a href="http://lua-users.org/files/wiki_insecure/users/thomasl/luarefv51.pdf">Краткая справка по Lua</a> на lua-users.org.
Ещё из основных тем не охвачены стандартные библиотеки:
* <a href="http://lua-users.org/wiki/StringLibraryTutorial">библиотека string</a>
* <a href="http://lua-users.org/wiki/TableLibraryTutorial">библиотека table</a>
* <a href="http://lua-users.org/wiki/MathLibraryTutorial">библиотека math</a>
* <a href="http://lua-users.org/wiki/IoLibraryTutorial">библиотека io</a>
* <a href="http://lua-users.org/wiki/OsLibraryTutorial">библиотека os</a>
Кстати, весь файл написан на Lua; сохраните его как learn.lua и запустите при помощи "lua learn.lua" !
Изначально эта статья была написана для tylerneylon.com.
Также она доступна как <a href="https://gist.github.com/tylerneylon/5853042">github gist</a>. Удачи с Lua!

View File

@ -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
;; Макросы приводят к неясному коду, т.е. вы можете затереть существующие переменные!
;; Они являются кодопреобразующей конструкцией.
```

View File

@ -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 не устанавливает значение элемента словаря)
# Метод setdefault вставляет пару ключ-значение, только если такого ключа нет
# Присваивайте значение ключам так же, как и в списках
filled_dict["four"] = 4 # теперь filled_dict["four"] => 4
# Метод 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:

View File

@ -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
@ -575,7 +593,7 @@ def double_numbers(iterable):
range_ = range(1, 900000000)
# Будет удваивать все числа, пока результат не превысит 30
for i in double_numbers(xrange_):
for i in double_numbers(range_):
print(i)
if i >= 30:
break

View File

@ -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
```

130
ru-ru/xml-ru.html.markdown Normal file
View File

@ -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>
```

View File

@ -11,6 +11,7 @@ contributors:
- ["Ariel Krakowski", "http://www.learneroo.com"]
- ["Dzianis Dashkevich", "https://github.com/dskecse"]
- ["Levi Bostian", "https://github.com/levibostian"]
- ["Rahil Momin", "https://github.com/iamrahil"]
---
@ -60,8 +61,6 @@ false.class #=> FalseClass
# Inequality
1 != 1 #=> false
2 != 1 #=> true
!true #=> false
!false #=> true
# apart from false itself, nil is the only other 'falsey' value
@ -75,6 +74,17 @@ false.class #=> FalseClass
2 <= 2 #=> true
2 >= 2 #=> true
# Logical operators
true && false #=> false
true || false #=> true
!true #=> false
# Alternate spellings of logical operators
true and false #=> false
true or false #=> true
not true #=> false
# Strings are objects
'I am a string'.class #=> String
@ -160,6 +170,9 @@ array[1..3] #=> [2, 3, 4]
# Add to an array like this
array << 6 #=> [1, 2, 3, 4, 5, 6]
# Check if an item exists in an array
array.include?(1) #=> true
# Hashes are Ruby's primary dictionary with keys/value pairs.
# Hashes are denoted with curly braces:
hash = { 'color' => 'green', 'number' => 5 }
@ -179,6 +192,10 @@ new_hash = { defcon: 3, action: true }
new_hash.keys #=> [:defcon, :action]
# Check existence of keys and values in hash
new_hash.has_key?(:defcon) #=> true
new_hash.has_value?(3) #=> true
# Tip: Both Arrays and Hashes are Enumerable
# They share a lot of useful methods such as each, map, count, and more
@ -280,9 +297,9 @@ rescue NoMemoryError => exception_variable
puts 'NoMemoryError was raised', exception_variable
rescue RuntimeError => other_exception_variable
puts 'RuntimeError was raised now'
else
else
puts 'This runs if no exceptions were thrown at all'
ensure
ensure
puts 'This code always runs no matter what'
end

View File

@ -6,10 +6,21 @@ filename: learnrust.rs
---
Rust is an in-development programming language developed by Mozilla Research.
It is relatively unique among systems languages in that it can assert memory
safety *at compile time*. Rusts first alpha release occurred in January
2012, and development moves so quickly that at the moment the use of stable
releases is discouraged, and instead one should use nightly builds.
Rust combines low-level control over performance with high-level convenience and
safety guarantees.
It achieves these goals without requiring a garbage collector or runtime, making
it possible to use Rust libraries as a "drop-in replacement" for C.
Rusts first release, 0.1, occurred in January 2012, and for 3 years development
moved so quickly that until recently the use of stable releases was discouraged
and instead the general advise was to use nightly builds.
On May 15th 2015, Rust 1.0 was released with a complete guarantee of backward
compatibility. Improvements to compile times and other aspects of the compiler are
currently available in the nightly builds. Rust has adopted a train-based release
model with regular releases every six weeks. Rust 1.1 beta was made available at
the same time of the release of Rust 1.0.
Although Rust is a relatively low-level language, Rust has some functional
concepts that are generally found in higher-level languages. This makes
@ -24,7 +35,8 @@ Rust not only fast, but also easy and efficient to code in.
///////////////
// Functions
fn add2(x: int, y: int) -> int {
// `i32` is the type for 32-bit signed integers
fn add2(x: i32, y: i32) -> i32 {
// Implicit return (no semicolon)
x + y
}
@ -34,71 +46,90 @@ fn main() {
// Numbers //
// Immutable bindings
let x: int = 1;
let x: i32 = 1;
// Integer/float suffixes
let y: int = 13i;
let y: i32 = 13i32;
let f: f64 = 1.3f64;
// Type inference
let implicit_x = 1i;
let implicit_f = 1.3f64;
// Most of the time, the Rust compiler can infer what type a variable is, so
// you dont have to write an explicit type annotation.
// Throughout this tutorial, types are explicitly annotated in many places,
// but only for demonstrative purposes. Type inference can handle this for
// you most of the time.
let implicit_x = 1;
let implicit_f = 1.3;
// Maths
let sum = x + y + 13i;
// Arithmetic
let sum = x + y + 13;
// Mutable variable
let mut mutable = 1;
mutable = 4;
mutable += 2;
// Strings //
// String literals
let x: &'static str = "hello world!";
let x: &str = "hello world!";
// Printing
println!("{} {}", f, x); // 1.3 hello world
// A `String` - a heap-allocated string
// A `String` a heap-allocated string
let s: String = "hello world".to_string();
// A string slice - an immutable view into another string
// This is basically an immutable pointer to a string - it doesnt
// actually contain the characters of a string, just a pointer to
// A string slice an immutable view into another string
// This is basically an immutable pointer to a string it doesnt
// actually contain the contents of a string, just a pointer to
// something that does (in this case, `s`)
let s_slice: &str = s.as_slice();
let s_slice: &str = &*s;
println!("{} {}", s, s_slice); // hello world hello world
// Vectors/arrays //
// A fixed-size array
let four_ints: [int, ..4] = [1, 2, 3, 4];
let four_ints: [i32; 4] = [1, 2, 3, 4];
// A dynamically-sized vector
let mut vector: Vec<int> = vec![1, 2, 3, 4];
// A dynamic array (vector)
let mut vector: Vec<i32> = vec![1, 2, 3, 4];
vector.push(5);
// A slice - an immutable view into a vector or array
// A slice an immutable view into a vector or array
// This is much like a string slice, but for vectors
let slice: &[int] = vector.as_slice();
let slice: &[i32] = &*vector;
println!("{} {}", vector, slice); // [1, 2, 3, 4, 5] [1, 2, 3, 4, 5]
// Use `{:?}` to print something debug-style
println!("{:?} {:?}", vector, slice); // [1, 2, 3, 4, 5] [1, 2, 3, 4, 5]
// Tuples //
// A tuple is a fixed-size set of values of possibly different types
let x: (i32, &str, f64) = (1, "hello", 3.4);
// Destructuring `let`
let (a, b, c) = x;
println!("{} {} {}", a, b, c); // 1 hello 3.4
// Indexing
println!("{}", x.1); // hello
//////////////
// 2. Types //
//////////////
// Struct
struct Point {
x: int,
y: int,
x: i32,
y: i32,
}
let origin: Point = Point { x: 0, y: 0 };
// Tuple struct
struct Point2(int, int);
// A struct with unnamed fields, called a tuple struct
struct Point2(i32, i32);
let origin2 = Point2(0, 0);
@ -110,16 +141,16 @@ fn main() {
Down,
}
let up = Up;
let up = Direction::Up;
// Enum with fields
enum OptionalInt {
AnInt(int),
enum OptionalI32 {
AnI32(i32),
Nothing,
}
let two: OptionalInt = AnInt(2);
let nothing: OptionalInt = Nothing;
let two: OptionalI32 = OptionalI32::AnI32(2);
let nothing = OptionalI32::Nothing;
// Generics //
@ -140,10 +171,10 @@ fn main() {
}
}
let a_foo = Foo { bar: 1i };
let a_foo = Foo { bar: 1 };
println!("{}", a_foo.get_bar()); // 1
// Traits (interfaces) //
// Traits (known as interfaces or typeclasses in other languages) //
trait Frobnicate<T> {
fn frobnicate(self) -> Option<T>;
@ -155,30 +186,31 @@ fn main() {
}
}
println!("{}", a_foo.frobnicate()); // Some(1)
let another_foo = Foo { bar: 1 };
println!("{:?}", another_foo.frobnicate()); // Some(1)
/////////////////////////
// 3. Pattern matching //
/////////////////////////
let foo = AnInt(1);
let foo = OptionalI32::AnI32(1);
match foo {
AnInt(n) => println!("its an int: {}", n),
Nothing => println!("its nothing!"),
OptionalI32::AnI32(n) => println!("its an i32: {}", n),
OptionalI32::Nothing => println!("its nothing!"),
}
// Advanced pattern matching
struct FooBar { x: int, y: OptionalInt }
let bar = FooBar { x: 15, y: AnInt(32) };
struct FooBar { x: i32, y: OptionalI32 }
let bar = FooBar { x: 15, y: OptionalI32::AnI32(32) };
match bar {
FooBar { x: 0, y: AnInt(0) } =>
FooBar { x: 0, y: OptionalI32::AnI32(0) } =>
println!("The numbers are zero!"),
FooBar { x: n, y: AnInt(m) } if n == m =>
FooBar { x: n, y: OptionalI32::AnI32(m) } if n == m =>
println!("The numbers are the same"),
FooBar { x: n, y: AnInt(m) } =>
FooBar { x: n, y: OptionalI32::AnI32(m) } =>
println!("Different numbers: {} {}", n, m),
FooBar { x: _, y: Nothing } =>
FooBar { x: _, y: OptionalI32::Nothing } =>
println!("The second number is Nothing!"),
}
@ -187,19 +219,20 @@ fn main() {
/////////////////////
// `for` loops/iteration
let array = [1i, 2, 3];
let array = [1, 2, 3];
for i in array.iter() {
println!("{}", i);
}
for i in range(0u, 10) {
// Ranges
for i in 0u32..10 {
print!("{} ", i);
}
println!("");
// prints `0 1 2 3 4 5 6 7 8 9 `
// `if`
if 1i == 1 {
if 1 == 1 {
println!("Maths is working!");
} else {
println!("Oh no...");
@ -213,7 +246,7 @@ fn main() {
};
// `while` loop
while 1i == 1 {
while 1 == 1 {
println!("The universe is operating normally.");
}
@ -225,40 +258,49 @@ fn main() {
/////////////////////////////////
// 5. Memory safety & pointers //
/////////////////////////////////
// Owned pointer - only one thing can own this pointer at a time
let mut mine: Box<int> = box 3;
// Owned pointer only one thing can own this pointer at a time
// This means that when the `Box` leaves its scope, it can be automatically deallocated safely.
let mut mine: Box<i32> = Box::new(3);
*mine = 5; // dereference
// Here, `now_its_mine` takes ownership of `mine`. In other words, `mine` is moved.
let mut now_its_mine = mine;
*now_its_mine += 2;
println!("{}", now_its_mine); // 7
// println!("{}", mine); // this would error
// Reference - an immutable pointer that refers to other data
let mut var = 4i;
println!("{}", now_its_mine); // 7
// println!("{}", mine); // this would not compile because `now_its_mine` now owns the pointer
// Reference an immutable pointer that refers to other data
// When a reference is taken to a value, we say that the value has been borrowed.
// While a value is borrowed immutably, it cannot be mutated or moved.
// A borrow lasts until the end of the scope it was created in.
let mut var = 4;
var = 3;
let ref_var: &int = &var;
let ref_var: &i32 = &var;
println!("{}", var); // Unlike `box`, `var` can still be used
println!("{}", *ref_var);
// var = 5; // this would error
// *ref_var = 6; // this would too
// var = 5; // this would not compile because `var` is borrowed
// *ref_var = 6; // this would too, because `ref_var` is an immutable reference
// Mutable reference
let mut var2 = 4i;
let ref_var2: &mut int = &mut var2;
// While a value is mutably borrowed, it cannot be accessed at all.
let mut var2 = 4;
let ref_var2: &mut i32 = &mut var2;
*ref_var2 += 2;
println!("{}", *ref_var2); // 6
// var2 = 2; // this would error
// var2 = 2; // this would not compile because `var2` is borrowed
}
```
## Further reading
Theres a lot more to Rust—this is just the basics of Rust so you can
understand the most important things. To learn more about Rust, read [The Rust
Guide](http://doc.rust-lang.org/guide.html) and check out the
[/r/rust](http://reddit.com/r/rust) subreddit. The folks on the #rust channel
on irc.mozilla.org are also always keen to help newcomers.
Theres a lot more to Rust—this is just the basics of Rust so you can understand
the most important things. To learn more about Rust, read [The Rust Programming
Language](http://doc.rust-lang.org/book/index.html) and check out the
[/r/rust](http://reddit.com/r/rust) subreddit. The folks on the #rust channel on
irc.mozilla.org are also always keen to help newcomers.
You can also try out features of Rust with an online compiler at the official
[Rust playpen](http://play.rust-lang.org) or on the main

View File

@ -186,7 +186,7 @@ val sq: Int => Int = x => x * x
// Anonymous functions can be called as usual:
sq(10) // => 100
// If your anonymous function has one or two arguments, and each argument is
// If each argument in your anonymous function is
// used only once, Scala gives you an even shorter way to define them. These
// anonymous functions turn out to be extremely common, as will be obvious in
// the data structure section.
@ -198,8 +198,10 @@ weirdSum(2, 4) // => 16
// The return keyword exists in Scala, but it only returns from the inner-most
// def that surrounds it. It has no effect on anonymous functions. For example:
def foo(x: Int) = {
// def that surrounds it.
// WARNING: Using return in Scala is error-prone and should be avoided.
// It has no effect on anonymous functions. For example:
def foo(x: Int): Int = {
val anonFunc: Int => Int = { z =>
if (z > 5)
return z // This line makes z the return value of foo!
@ -405,41 +407,55 @@ val otherGeorge = george.copy(phoneNumber = "9876")
// 6. Pattern Matching
/////////////////////////////////////////////////
val me = Person("George", "1234")
// Pattern matching is a powerful and commonly used feature in Scala. Here's how
// you pattern match a case class. NB: Unlike other languages, Scala cases do
// not need breaks, fall-through does not happen.
me match { case Person(name, number) => {
"We matched someone : " + name + ", phone : " + number }}
me match { case Person(name, number) => "Match : " + name; case _ => "Hm..." }
me match { case Person("George", number) => "Match"; case _ => "Hm..." }
me match { case Person("Kate", number) => "Match"; case _ => "Hm..." }
me match { case Person("Kate", _) => "Girl"; case Person("George", _) => "Boy" }
val kate = Person("Kate", "1234")
kate match { case Person("Kate", _) => "Girl"; case Person("George", _) => "Boy" }
// Regular expressions
val email = "(.*)@(.*)".r // Invoking r on String makes it a Regex
val serialKey = """(\d{5})-(\d{5})-(\d{5})-(\d{5})""".r // Using verbatim (multiline) syntax
val matcher = (value: String) => {
println(value match {
case email(name, domain) => s"It was an email: $name"
case serialKey(p1, p2, p3, p4) => s"Serial key: $p1, $p2, $p3, $p4"
case _ => s"No match on '$value'" // default if no match found
})
def matchPerson(person: Person): String = person match {
// Then you specify the patterns:
case Person("George", number) => "We found George! His number is " + number
case Person("Kate", number) => "We found Kate! Her number is " + number
case Person(name, number) => "We matched someone : " + name + ", phone : " + number
}
matcher("mrbean@pyahoo.com") // => "It was an email: mrbean"
matcher("nope..") // => "No match on 'nope..'"
matcher("52917") // => "No match on '52917'"
matcher("52752-16432-22178-47917") // => "Serial key: 52752, 16432, 22178, 47917"
val email = "(.*)@(.*)".r // Define a regex for the next example.
// Pattern matching might look familiar to the switch statements in the C family
// of languages, but this is much more powerful. In Scala, you can match much
// more:
def matchEverything(obj: Any): String = obj match {
// You can match values:
case "Hello world" => "Got the string Hello world"
// You can match by type:
case x: Double => "Got a Double: " + x
// You can specify conditions:
case x: Int if x > 10000 => "Got a pretty big number!"
// You can match case classes as before:
case Person(name, number) => s"Got contact info for $name!"
// You can match regular expressions:
case email(name, domain) => s"Got email address $name@$domain"
// You can match tuples:
case (a: Int, b: Double, c: String) => s"Got a tuple: $a, $b, $c"
// You can match data structures:
case List(1, b, c) => s"Got a list with three elements and starts with 1: 1, $b, $c"
// You can nest patterns:
case List(List((1, 2,"YAY"))) => "Got a list of list of tuple"
}
// In fact, you can pattern match any object with an "unapply" method. This
// 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(name, number) => s"Random person's number: $number"
}
/////////////////////////////////////////////////
@ -449,6 +465,7 @@ matcher("52752-16432-22178-47917") // => "Serial key: 52752, 16432, 22178, 47917
// Scala allows methods and functions to return, or take as parameters, other
// functions or methods.
val add10: Int => Int = _ + 10 // A function taking an Int and returning an Int
List(1, 2, 3) map add10 // List(11, 12, 13) - add10 is applied to each element
// Anonymous functions can be used instead of named functions:
@ -476,7 +493,7 @@ sSquared.reduce (_+_)
// The filter function takes a predicate (a function from A -> Boolean) and
// selects all elements which satisfy the predicate
List(1, 2, 3) filter (_ > 2) // List(3)
case class Person(name:String, phoneNumber:String)
case class Person(name:String, age:Int)
List(
Person(name = "Dom", age = 23),
Person(name = "Bob", age = 30)
@ -507,7 +524,60 @@ for { n <- s; nSquared = n * n if nSquared < 10} yield nSquared
// 8. Implicits
/////////////////////////////////////////////////
// Coming soon!
/* WARNING WARNING: Implicits are a set of powerful features of Scala, and
* therefore it is easy to abuse them. Beginners to Scala should resist the
* temptation to use them until they understand not only how they work, but also
* best practices around them. We only include this section in the tutorial
* because they are so commonplace in Scala libraries that it is impossible to
* do anything meaningful without using a library that has implicits. This is
* meant for you to understand and work with implicts, not declare your own.
*/
// Any value (vals, functions, objects, etc) can be declared to be implicit by
// using the, you guessed it, "implicit" keyword. Note we are using the Dog
// class from section 5 in these examples.
implicit val myImplicitInt = 100
implicit def myImplicitFunction(breed: String) = new Dog("Golden " + breed)
// By itself, implicit keyword doesn't change the behavior of the value, so
// above values can be used as usual.
myImplicitInt + 2 // => 102
myImplicitFunction("Pitbull").breed // => "Golden Pitbull"
// The difference is that these values are now eligible to be used when another
// piece of code "needs" an implicit value. One such situation is implicit
// function arguments:
def sendGreetings(toWhom: String)(implicit howMany: Int) =
s"Hello $toWhom, $howMany blessings to you and yours!"
// If we supply a value for "howMany", the function behaves as usual
sendGreetings("John")(1000) // => "Hello John, 1000 blessings to you and yours!"
// But if we omit the implicit parameter, an implicit value of the same type is
// used, in this case, "myImplicitInt":
sendGreetings("Jane") // => "Hello Jane, 100 blessings to you and yours!"
// Implicit function parameters enable us to simulate type classes in other
// functional languages. It is so often used that it gets its own shorthand. The
// following two lines mean the same thing:
def foo[T](implicit c: C[T]) = ...
def foo[T : C] = ...
// Another situation in which the compiler looks for an implicit is if you have
// obj.method(...)
// but "obj" doesn't have "method" as a method. In this case, if there is an
// implicit conversion of type A => B, where A is the type of obj, and B has a
// method called "method", that conversion is applied. So having
// myImplicitFunction above in scope, we can say:
"Retriever".breed // => "Golden Retriever"
"Sheperd".bark // => "Woof, woof!"
// Here the String is first converted to Dog using our function above, and then
// the appropriate method is called. This is an extremely powerful feature, but
// again, it is not to be used lightly. In fact, when you defined the implicit
// function above, your compiler should have given you a warning, that you
// shouldn't do this unless you really know what you're doing.
/////////////////////////////////////////////////

View File

@ -3,13 +3,15 @@ language: "Standard ML"
contributors:
- ["Simon Shine", "http://shine.eu.org/"]
- ["David Pedersen", "http://lonelyproton.com/"]
- ["James Baker", "http://www.jbaker.io/"]
- ["Leo Zovic", "http://langnostic.inaimathi.ca/"]
---
Standard ML is a functional programming language with type inference and some
side-effects. Some of the hard parts of learning Standard ML are: Recursion,
pattern matching, type inference (guessing the right types but never allowing
implicit type conversion). If you have an imperative background, not being able
to update variables can feel severely inhibiting.
implicit type conversion). Standard ML is distinguished from Haskell by including
references, allowing variables to be updated.
```ocaml
(* Comments in Standard ML begin with (* and end with *). Comments can be
@ -135,9 +137,29 @@ val mixup = [ ("Alice", 39),
val good_bad_stuff =
(["ice cream", "hot dogs", "chocolate"],
["liver", "paying the rent" ]) (* string list * string list *)
["liver", "paying the rent" ]) (* : string list * string list *)
(* Records are tuples with named slots *)
val rgb = { r=0.23, g=0.56, b=0.91 } (* : {b:real, g:real, r:real} *)
(* You don't need to declare their slots ahead of time. Records with
different slot names are considered different types, even if their
slot value types match up. For instance... *)
val Hsl = { H=310.3, s=0.51, l=0.23 } (* : {H:real, l:real, s:real} *)
val Hsv = { H=310.3, s=0.51, v=0.23 } (* : {H:real, s:real, v:real} *)
(* ...trying to evaluate `Hsv = Hsl` or `rgb = Hsl` would give a type
error. While they're all three-slot records composed only of `real`s,
they each have different names for at least some slots. *)
(* You can use hash notation to get values out of tuples. *)
val H = #H Hsv (* : real *)
val s = #s Hsl (* : real *)
(* Functions! *)
fun add_them (a, b) = a + b (* A simple function that adds two numbers *)
val test_it = add_them (3, 4) (* gives 7 *)
@ -224,17 +246,26 @@ fun fibonacci 0 = 0 (* Base case *)
| fibonacci 1 = 1 (* Base case *)
| fibonacci n = fibonacci (n - 1) + fibonacci (n - 2) (* Recursive case *)
(* Pattern matching is also possible on composite types like tuples and lists.
Writing "fun solve2 (a, b, c) = ..." is in fact a pattern match on the one
three-tuple solve2 takes as argument. Similarly, but less intuitively, you
can match on a list consisting of elements in it (from the beginning of the
list only). *)
(* Pattern matching is also possible on composite types like tuples, lists and
records. Writing "fun solve2 (a, b, c) = ..." is in fact a pattern match on
the one three-tuple solve2 takes as argument. Similarly, but less intuitively,
you can match on a list consisting of elements in it (from the beginning of
the list only). *)
fun first_elem (x::xs) = x
fun second_elem (x::y::xs) = y
fun evenly_positioned_elems (odd::even::xs) = even::evenly_positioned_elems xs
| evenly_positioned_elems [odd] = [] (* Base case: throw away *)
| evenly_positioned_elems [] = [] (* Base case *)
(* When matching on records, you must use their slot names, and you must bind
every slot in a record. The order of the slots doesn't matter though. *)
fun rgbToTup {r, g, b} = (r, g, b) (* fn : {b:'a, g:'b, r:'c} -> 'c * 'b * 'a *)
fun mixRgbToTup {g, b, r} = (r, g, b) (* fn : {b:'a, g:'b, r:'c} -> 'c * 'b * 'a *)
(* If called with {r=0.1, g=0.2, b=0.3}, either of the above functions
would return (0.1, 0.2, 0.3). But it would be a type error to call them
with {r=0.1, g=0.2, b=0.3, a=0.4} *)
(* Higher order functions: Functions can take other functions as arguments.
Functions are just other kinds of values, and functions don't need names
@ -383,6 +414,25 @@ val test_poem = readPoem "roses.txt" (* gives [ "Roses are red,",
"Violets are blue.",
"I have a gun.",
"Get in the van." ] *)
(* We can create references to data which can be updated *)
val counter = ref 0 (* Produce a reference with the ref function *)
(* Assign to a reference with the assignment operator *)
fun set_five reference = reference := 5
(* Read a reference with the dereference operator *)
fun equals_five reference = !reference = 5
(* We can use while loops for when recursion is messy *)
fun decrement_to_zero r = if !r < 0
then r := 0
else while !r >= 0 do r := !r - 1
(* This returns the unit value (in practical terms, nothing, a 0-tuple) *)
(* To allow returning a value, we can use the semicolon to sequence evaluations *)
fun decrement_ret x y = (x := !x - 1; y)
```
## Further learning

View File

@ -3,14 +3,15 @@ language: swift
contributors:
- ["Grant Timmerman", "http://github.com/grant"]
- ["Christopher Bess", "http://github.com/cbess"]
- ["Joey Huang", "http://github.com/kamidox"]
filename: learnswift.swift
---
Swift is a programming language for iOS and OS X development created by Apple. Designed to coexist with Objective-C and to be more resilient against erroneous code, Swift was introduced in 2014 at Apple's developer conference WWDC. It is built with the LLVM compiler included in Xcode 6 beta.
Swift is a programming language for iOS and OS X development created by Apple. Designed to coexist with Objective-C and to be more resilient against erroneous code, Swift was introduced in 2014 at Apple's developer conference WWDC. It is built with the LLVM compiler included in Xcode 6+.
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
@ -23,7 +24,7 @@ import UIKit
// Xcode supports landmarks to annotate your code and lists them in the jump bar
// MARK: Section mark
// TODO: Do something soon
// FIXME Fix this code
// FIXME: Fix this code
println("Hello, world")
@ -55,8 +56,8 @@ println("Build value: \(buildValue)") // Build value: 7
/*
Optionals are a Swift language feature that allows you to store a `Some` or
`None` value.
Because Swift requires every property to have a value, even nil must be
Because Swift requires every property to have a value, even nil must be
explicitly stored as an Optional value.
Optional<T> is an enum.
@ -94,7 +95,8 @@ var anyObjectVar: AnyObject = 7
anyObjectVar = "Changed value to a string, not good practice, but possible."
/*
Comment here
Comment here
/*
Nested comments are also supported
*/
@ -112,8 +114,9 @@ Comment here
// Array
var shoppingList = ["catfish", "water", "lemons"]
shoppingList[1] = "bottle of water"
let emptyArray = [String]() // immutable
var emptyMutableArray = [String]() // mutable
let emptyArray = [String]() // let == immutable
let emptyArray2 = Array<String>() // same as above
var emptyMutableArray = [String]() // var == mutable
// Dictionary
@ -122,8 +125,9 @@ var occupations = [
"kaylee": "Mechanic"
]
occupations["Jayne"] = "Public Relations"
let emptyDictionary = [String: Float]() // immutable
var emptyMutableDictionary = [String: Float]() // mutable
let emptyDictionary = [String: Float]() // let == immutable
let emptyDictionary2 = Dictionary<String, Float>() // same as above
var emptyMutableDictionary = [String: Float]() // var == mutable
//
@ -165,14 +169,16 @@ do {
} while 1 == 2
// Switch
// Very powerful, think `if` statements with syntax candy
// They support String, object instances, and primitives (Int, Double, etc)
let vegetable = "red pepper"
switch vegetable {
case "celery":
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)?"
case let localScopeValue where localScopeValue.hasSuffix("pepper"):
let vegetableComment = "Is it a spicy \(localScopeValue)?"
default: // required (in order to cover all possible input)
let vegetableComment = "Everything tastes good in soup."
}
@ -186,21 +192,28 @@ default: // required (in order to cover all possible input)
// in functions and can be passed around
// Function with Swift header docs (format as reStructedText)
/**
A greet operation
A greet operation
- A bullet in docs
- Another bullet in the docs
- 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.
: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)."
}
greet("Bob", "Tuesday")
// similar to above except for the function parameter behaviors
func greet2(#requiredName: String, externalParamName localParamName: String) -> String {
return "Hello \(requiredName), the day is \(localParamName)"
}
greet2(requiredName:"John", externalParamName: "Sunday")
// Function that returns multiple items in a tuple
func getGasPrices() -> (Double, Double, Double) {
return (3.59, 3.69, 3.79)
@ -281,7 +294,7 @@ print(numbers) // [3, 6, 18]
// Structures and classes have very similar capabilites
struct NamesTable {
let names: [String]
let names = [String]()
// Custom subscript
subscript(index: Int) -> String {
@ -291,8 +304,8 @@ struct NamesTable {
// Structures have an auto-generated (implicit) designated initializer
let namesTable = NamesTable(names: ["Me", "Them"])
//let name = namesTable[2]
//println("Name is \(name)") // Name is Them
let name = namesTable[1]
println("Name is \(name)") // Name is Them
//
// MARK: Classes
@ -341,7 +354,7 @@ internal class Rect: Shape {
init(sideLength: Int) {
self.sideLength = sideLength
// always super.init last when init custom properties
// always super.init last when init custom properties
super.init()
}
@ -368,11 +381,43 @@ print(mySquare.getArea()) // 25
mySquare.shrink()
print(mySquare.sideLength) // 4
// cast instance
let aShape = mySquare as Shape
// compare instances, not the same as == which compares objects (equal to)
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
@ -393,6 +438,39 @@ enum Suit {
}
}
// Enum values allow short hand syntax, no need to type the enum type
// when the variable is explicitly declared
var suitValue: Suit = .Hearts
// Non-Integer enums require direct raw value assignments
enum BookName: String {
case John = "John"
case Luke = "Luke"
}
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
@ -419,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?()
@ -455,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.
@ -490,5 +571,4 @@ println(mySquare.sideLength) // 4
// change side length using custom !!! operator, increases size by 3
!!!mySquare
println(mySquare.sideLength) // 12
```

447
tcl.html.markdown Executable file
View File

@ -0,0 +1,447 @@
---
language: Tcl
contributors:
- ["Poor Yorick", "http://pooryorick.com/"]
filename: learntcl.tcl
---
Tcl was created by [John Ousterhout](http://wiki.tcl.tk/John Ousterout) as a
reusable scripting language for chip design tools he was creating. In 1997 he
was awarded the [ACM Software System
Award](http://en.wikipedia.org/wiki/ACM_Software_System_Award) for Tcl. Tcl
can be used both as an embeddable scripting language and as a general
programming language. It can also be used as a portable C library, even in
cases where no scripting capability is needed, as it provides data structures
such as dynamic strings, lists, and hash tables. The C library also provides
portable functionality for loading dynamic libraries, string formatting and
code conversion, filesystem operations, network operations, and more.
Various features of Tcl stand out:
* Convenient cross-platform networking API
* Fully virtualized filesystem
* Stackable I/O channels
* Asynchronous to the core
* Full coroutines
* A threading model recognized as robust and easy to use
If Lisp is a list processor, then Tcl is a string processor. All values are
strings. A list is a string format. A procedure definition is a string
format. To achieve performance, Tcl internally caches structured
representations of these values. The list commands, for example, operate on
the internal cached representation, and Tcl takes care of updating the string
representation if it is ever actually needed in the script. The copy-on-write
design of Tcl allows script authors can pass around large data values without
actually incurring additional memory overhead. Procedures are automatically
byte-compiled unless they use the more dynamic commands such as "uplevel",
"upvar", and "trace".
Tcl is a pleasure to program in. It will appeal to hacker types who find Lisp,
Forth, or Smalltalk interesting, as well as to engineers and scientists who
just want to get down to business with a tool that bends to their will. Its
discipline of exposing all programmatic functionality as commands, including
things like loops and mathematical operations that are usually baked into the
syntax of other languages, allows it to fade into the background of whatever
domain-specific functionality a project needs. It's syntax, which is even
lighter that that of Lisp, just gets out of the way.
```tcl
#! /bin/env tclsh
################################################################################
## 1. Guidelines
################################################################################
# Tcl is not Bash or C! This needs to be said because standard shell quoting
# habits almost work in Tcl and it is common for people to pick up Tcl and try
# to get by with syntax they know from another language. It works at first,
# but soon leads to frustration with more complex scripts.
# Braces are just a quoting mechanism, not a code block constructor or a list
# constructor. Tcl doesn't have either of those things. Braces are used,
# though, to escape special characters in procedure bodies and in strings that
# are formatted as lists.
################################################################################
## 2. Syntax
################################################################################
# Every line is a command. The first word is the name of the command, and
# subsequent words are arguments to the command. Words are delimited by
# whitespace. Since every word is a string, in the simple case no special
# markup such as quotes, braces, or backslash, is necessary. Even when quotes
# are used, they are not a string constructor, but just another escaping
# character.
set greeting1 Sal
set greeting2 ut
set greeting3 ations
#semicolon also delimits commands
set greeting1 Sal; set greeting2 ut; set greeting3 ations
# Dollar sign introduces variable substitution
set greeting $greeting1$greeting2$greeting3
# Bracket introduces command substitution. The result of the command is
# substituted in place of the bracketed script. When the "set" command is
# given only the name of a variable, it returns the value of that variable.
set greeting $greeting1$greeting2[set greeting3]
# Command substitution should really be called script substitution, because an
# entire script, not just a command, can be placed between the brackets. The
# "incr" command increments the value of a variable and returns its value.
set greeting $greeting[
incr i
incr i
incr i
]
# backslash suppresses the special meaning of characters
set amount \$16.42
# backslash adds special meaning to certain characters
puts lots\nof\n\n\n\n\n\nnewlines
# A word enclosed in braces is not subject to any special interpretation or
# substitutions, except that a backslash before a brace is not counted when look#ing for the closing brace
set somevar {
This is a literal $ sign, and this \} escaped
brace remains uninterpreted
}
# In a word enclosed in double quotes, whitespace characters lose their special
# meaning
set name Neo
set greeting "Hello, $name"
#variable names can be any string
set {first name} New
# The brace form of variable substitution handles more complex variable names
set greeting "Hello, ${first name}"
# The "set" command can always be used instead of variable substitution
set greeting "Hello, [set {first name}]"
# To promote the words within a word to individual words of the current
# command, use the expansion operator, "{*}".
set {*}{name Neo}
# is equivalent to
set name Neo
# An array is a special variable that is a container for other variables.
set person(name) Neo
set person(gender) male
set greeting "Hello, $person(name)"
# A namespace holds commands and variables
namespace eval people {
namespace eval person1 {
set name Neo
}
}
#The full name of a variable includes its enclosing namespace(s), delimited by two colons:
set greeting "Hello $people::person1::name"
################################################################################
## 3. A Few Notes
################################################################################
# All other functionality is implemented via commands. From this point on,
# there is no new syntax. Everything else there is to learn about Tcl is about
# the behaviour of individual commands, and what meaning they assign to their
# arguments.
# To end up with an interpreter that can do nothing, delete the global
# namespace. It's not very useful to do such a thing, but it illustrates the
# nature of Tcl.
namespace delete ::
# 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
}
}
# The full name of a variable can always be used, if desired.
set people::person1::name Neo
################################################################################
## 4. Commands
################################################################################
# Math can be done with the "expr" command.
set a 3
set b 4
set c [expr {$a + $b}]
# Since "expr" performs variable substitution on its own, brace the expression
# to prevent Tcl from performing variable substitution first. See
# "http://wiki.tcl.tk/Brace%20your%20#%20expr-essions" for details.
# The "expr" command understands variable and command substitution
set c [expr {$a + [set b]}]
# The "expr" command provides a set of mathematical functions
set c [expr {pow($a,$b)}]
# Mathematical operators are available as commands in the ::tcl::mathop
# namespace
::tcl::mathop::+ 5 3
# Commands can be imported from other namespaces
namespace import ::tcl::mathop::+
set result [+ 5 3]
# New commands can be created via the "proc" command.
proc greet name {
return "Hello, $name!"
}
#multiple parameters can be specified
proc greet {greeting name} {
return "$greeting, $name!"
}
# As noted earlier, braces do not construct a code block. Every value, even
# the third argument of the "proc" command, is a string. The previous command
# rewritten to not use braces at all:
proc greet greeting\ name return\ \"Hello,\ \$name!
# When the last parameter is the literal value, "args", it collects all extra
# arguments when the command is invoked
proc fold {cmd args} {
set res 0
foreach arg $args {
set res [cmd $res $arg]
}
}
fold ::tcl::mathop::* 5 3 3 ;# -> 45
# Conditional execution is implemented as a command
if {3 > 4} {
puts {This will never happen}
} elseif {4 > 4} {
puts {This will also never happen}
} else {
puts {This will always happen}
}
# Loops are implemented as commands. The first, second, and third
# arguments of the "for" command are treated as mathematical expressions
for {set i 0} {$i < 10} {incr i} {
set res [expr {$res + $i}]
}
# The first argument of the "while" command is also treated as a mathematical
# expression
set i 0
while {$i < 10} {
incr i 2
}
# A list is a specially-formatted string. In the simple case, whitespace is sufficient to delimit values
set amounts 10\ 33\ 18
set amount [lindex $amounts 1]
# Braces and backslash can be used to format more complex values in a list. A
# list looks exactly like a script, except that the newline character and the
# semicolon character lose their special meanings. This feature makes Tcl
# homoiconic. There are three items in the following list.
set values {
one\ two
{three four}
five\{six
}
# Since a list is a string, string operations could be performed on it, at the
# risk of corrupting the formatting of the list.
set values {one two three four}
set values [string map {two \{} $values] ;# $values is no-longer a \
properly-formatted listwell-formed list
# The sure-fire way to get a properly-formmated list is to use "list" commands
set values [list one \{ three four]
lappend values { } ;# add a single space as an item in the list
# Use "eval" to evaluate a value as a script
eval {
set name Neo
set greeting "Hello, $name"
}
# A list can always be passed to "eval" as a script composed of a single
# command.
eval {set name Neo}
eval [list set greeting "Hello, $name"]
# Therefore, when using "eval", use [list] to build up a desired command
set command {set name}
lappend command {Archibald Sorbisol}
eval $command
# A common mistake is not to use list functions when building up a command
set command {set name}
append command { Archibald Sorbisol}
eval $command ;# There is an error here, because there are too many arguments \
to "set" in {set name Archibald Sorbisol}
# This mistake can easily occur with the "subst" command.
set replacement {Archibald Sorbisol}
set command {set name $replacement}
set command [subst $command]
eval $command ;# The same error as before: to many arguments to "set" in \
{set name Archibald Sorbisol}
# The proper way is to format the substituted value using use the "list"
# command.
set replacement [list {Archibald Sorbisol}]
set command {set name $replacement}
set command [subst $command]
eval $command
# It is extremely common to see the "list" command being used to properly
# format values that are substituted into Tcl script templates. There are
# several examples of this, below.
# The "apply" command evaluates a string as a command.
set cmd {{greeting name} {
return "$greeting, $name!"
}}
apply $cmd Whaddup Neo
# The "uplevel" command evaluates a script in some enclosing scope.
proc greet {} {
uplevel {puts "$greeting, $name"}
}
proc set_double {varname value} {
if {[string is double $value]} {
uplevel [list variable $varname $value]
} else {
error [list {not a double} $value]
}
}
# The "upvar" command links a variable in the current scope to a variable in
# some enclosing scope
proc set_double {varname value} {
if {[string is double $value]} {
upvar 1 $varname var
set var $value
} else {
error [list {not a double} $value]
}
}
#get rid of the built-in "while" command.
rename ::while {}
# Define a new while command with the "proc" command. More sophisticated error
# handling is left as an exercise.
proc while {condition script} {
if {[uplevel 1 [list expr $condition]]} {
uplevel 1 $script
tailcall [namespace which while] $condition $script
}
}
# The "coroutine" command creates a separate call stack, along with a command
# to enter that call stack. The "yield" command suspends execution in that
# stack.
proc countdown {} {
#send something back to the initial "coroutine" command
yield
set count 3
while {$count > 1} {
yield [incr count -1]
}
return 0
}
coroutine countdown1 countdown
coroutine countdown2 countdown
puts [countdown 1] ;# -> 2
puts [countdown 2] ;# -> 2
puts [countdown 1] ;# -> 1
puts [countdown 1] ;# -> 0
puts [coundown 1] ;# -> invalid command name "countdown1"
puts [countdown 2] ;# -> 1
```
## Reference
[Official Tcl Documentation](http://www.tcl.tk/man/tcl/)
[Tcl Wiki](http://wiki.tcl.tk)
[Tcl Subreddit](http://www.reddit.com/r/Tcl)

View File

@ -2,13 +2,13 @@
category: tool
tool: tmux
contributors:
- ["wzsk", "https://github.com/wzsk"]
- ["mdln", "https://github.com/mdln"]
filename: LearnTmux.txt
---
<a href="http://tmux.sourceforge.net/">
tmux</a> is a terminal multiplexer: it enables a number of terminals
[tmux](http://tmux.sourceforge.net)
is a terminal multiplexer: it enables a number of terminals
to be created, accessed, and controlled from a single screen. tmux
may be detached from a screen and continue running in the background
then later reattached.
@ -50,13 +50,15 @@ then later reattached.
-a # Kill all sessions
-a -t "#" # Kill all sessions but the target
```
## Key Bindings
### Key Bindings
# The method of controlling an attached tmux session is via key
# combinations called 'Prefix' keys.
The method of controlling an attached tmux session is via key
combinations called 'Prefix' keys.
```
----------------------------------------------------------------------
(C-b) = Ctrl + b # 'Prefix' combination required to use keybinds
@ -109,10 +111,9 @@ then later reattached.
### Configuring ~/.tmux.conf
tmux.conf can be used to set options automatically on start up, much
tmux.conf can be used to set options automatically on start up, much
like how .vimrc or init.el are used.
```
# Example tmux.conf
# 2014.10
@ -236,8 +237,15 @@ set -g status-right "#[fg=green] | #[fg=white]#(tmux-mem-cpu-load)#[fg=green] |
```
<a href="http://tmux.sourceforge.net/">Tmux | Home</a><br>
<a href="http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man1/tmux.1?query=tmux">Tmux Manual page</a><br>
<a href="http://wiki.gentoo.org/wiki/Tmux">Gentoo Wiki</a><br>
<a href="https://wiki.archlinux.org/index.php/Tmux">Archlinux Wiki</a><br>
<a href="https://stackoverflow.com/questions/11558907/is-there-a-better-way-to-display-cpu-usage-in-tmux">Display CPU/MEM % in statusbar</a><br>
### References
[Tmux | Home](http://tmux.sourceforge.net)
[Tmux Manual page](http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man1/tmux.1?query=tmux)
[Gentoo Wiki](http://wiki.gentoo.org/wiki/Tmux)
[Archlinux Wiki](https://wiki.archlinux.org/index.php/Tmux)
[Display CPU/MEM % in statusbar](https://stackoverflow.com/questions/11558907/is-there-a-better-way-to-display-cpu-usage-in-tmux)

View File

@ -0,0 +1,824 @@
---
language: c#
contributors:
- ["Irfan Charania", "https://github.com/irfancharania"]
- ["Max Yankov", "https://github.com/golergka"]
- ["Melvyn Laïly", "http://x2a.yt"]
- ["Shaun McCarthy", "http://www.shaunmccarthy.com"]
translators:
- ["Melih Mucuk", "http://melihmucuk.com"]
lang: tr-tr
filename: LearnCSharp.cs
---
C# zarif ve tip güvenli nesne yönelimli bir dil olup geliştiricilerin .NET framework üzerinde çalışan güçlü ve güvenli uygulamalar geliştirmesini sağlar.
[Yazım yanlışları ve öneriler için bana ulaşabilirsiniz](mailto:melihmucuk@gmail.com)
[Daha fazlasını okuyun.](http://msdn.microsoft.com/en-us/library/vstudio/z1zx9t92.aspx)
```c#
// Tek satırlık yorumlar // ile başlar
/*
Birden fazla satırlı yorumlar buna benzer
*/
/// <summary>
/// Bu bir XML dokümantasyon yorumu
/// </summary>
// Uygulamanın kullanacağı ad alanlarını belirtin
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Dynamic;
using System.Linq;
using System.Linq.Expressions;
using System.Net;
using System.Threading.Tasks;
using System.IO;
// Kodu düzenlemek için paketler içinde alan tanımlayın
namespace Learning
{
// Her .cs dosyası, dosya ile aynı isimde en az bir sınıf içermeli
// bu kurala uymak zorunda değilsiniz ancak mantıklı olan yol budur.
public class LearnCSharp
{
// TEMEL SÖZ DİZİMİ - daha önce Java ya da C++ kullandıysanız İLGİNÇ ÖZELLİKLER'e geçin
public static void Syntax()
{
// Satırları yazdırmak için Console.WriteLine kullanın
Console.WriteLine("Merhaba Dünya");
Console.WriteLine(
"Integer: " + 10 +
" Double: " + 3.14 +
" Boolean: " + true);
// Yeni satıra geçmeden yazdırmak için Console.Write kullanın
Console.Write("Merhaba ");
Console.Write("Dünya");
///////////////////////////////////////////////////
// Tipler & Değişkenler
//
// Bir değişken tanımlamak için <tip> <isim> kullanın
///////////////////////////////////////////////////
// Sbyte - Signed 8-bit integer
// (-128 <= sbyte <= 127)
sbyte fooSbyte = 100;
// Byte - Unsigned 8-bit integer
// (0 <= byte <= 255)
byte fooByte = 100;
// Short - 16-bit integer
// Signed - (-32,768 <= short <= 32,767)
// Unsigned - (0 <= ushort <= 65,535)
short fooShort = 10000;
ushort fooUshort = 10000;
// Integer - 32-bit integer
int fooInt = 1; // (-2,147,483,648 <= int <= 2,147,483,647)
uint fooUint = 1; // (0 <= uint <= 4,294,967,295)
// Long - 64-bit integer
long fooLong = 100000L; // (-9,223,372,036,854,775,808 <= long <= 9,223,372,036,854,775,807)
ulong fooUlong = 100000L; // (0 <= ulong <= 18,446,744,073,709,551,615)
// Sayılar boyutlarına göre ön tanımlı olarak int ya da uint olabilir.
// L, değişken değerinin long ya da ulong tipinde olduğunu belirtmek için kullanılır.
// Double - Çift hassasiyetli 64-bit IEEE 754 kayan sayı
double fooDouble = 123.4; // Hassasiyet: 15-16 basamak
// Float - Tek hassasiyetli 32-bit IEEE 754 kayan sayı
float fooFloat = 234.5f; // Hassasiyet: 7 basamak
// f, değişken değerinin float tipinde olduğunu belirtmek için kullanılır.
// Decimal - 128-bit veri tiğinde ve diğer kayan sayı veri tiplerinden daha hassastır,
// finansal ve mali hesaplamalar için uygundur.
decimal fooDecimal = 150.3m;
// Boolean - true & false
bool fooBoolean = true; // veya false
// Char - 16-bitlik tek bir unicode karakter
char fooChar = 'A';
// Strings -- Önceki baz tiplerinin hepsi değer tipiyken,
// string bir referans tipidir. Null değer atayabilirsiniz
string fooString = "\"escape\" quotes and add \n (new lines) and \t (tabs)";
Console.WriteLine(fooString);
// İndeks numarası kullanarak bir string'in bütün karakterlerine erişilebilirsiniz:
char charFromString = fooString[1]; // => 'e'
// String'ler değiştirilemez: fooString[1] = 'X' işlemini yapamazsınız;
// String'leri geçerli kültür değeri ve büyük küçük harf duyarlılığı olmadan karşılaştırma
string.Compare(fooString, "x", StringComparison.CurrentCultureIgnoreCase);
// sprintf baz alınarak formatlama
string fooFs = string.Format("Check Check, {0} {1}, {0} {1:0.0}", 1, 2);
// Tarihler & Formatlama
DateTime fooDate = DateTime.Now;
Console.WriteLine(fooDate.ToString("hh:mm, dd MMM yyyy"));
// Bir string'i iki satıra bölmek için @ sembolü kullanabilirsiniz. " işaretinden kaçmak için "" kullanın
string bazString = @"Here's some stuff
on a new line! ""Wow!"", the masses cried";
// Bir değişkeni değiştirilemez yapmak için const ya da read-only kullanın.
// const değerleri derleme sırasında hesaplanır
const int HOURS_I_WORK_PER_WEEK = 9001;
///////////////////////////////////////////////////
// Veri Yapıları
///////////////////////////////////////////////////
// Diziler - Sıfır indeksli
// Dizi boyutuna tanımlama sırasında karar verilmelidir.
// Dizi tanımlama formatı şöyledir:
// <veri tipi>[] <değişken ismi> = new <veri tipi>[<dizi boyutu>];
int[] intArray = new int[10];
// Bir diğer dizi tanımlama formatı şöyledir:
int[] y = { 9000, 1000, 1337 };
// Bir diziyi indeksleme - Bir elemente erişme
Console.WriteLine("intArray @ 0: " + intArray[0]);
// Diziler değiştirilebilir.
intArray[1] = 1;
// Listeler
// Listeler daha esnek oldukları için dizilerden daha sık kullanılırlar.
// Bir liste tanımlama formatı şöyledir:
// List<veri tipi> <değişken ismi> = new List<veri tipi>();
List<int> intList = new List<int>();
List<string> stringList = new List<string>();
List<int> z = new List<int> { 9000, 1000, 1337 }; // tanımlama
// <> işareti generic ifadeler içindir - Güzel özellikler sekmesini inceleyin
// Listelerin varsayılan bir değeri yoktur;
// İndekse erişmeden önce değer eklenmiş olmalıdır
intList.Add(1);
Console.WriteLine("intList @ 0: " + intList[0]);
// Diğer veri yapıları için şunlara bakın:
// Stack/Queue (Yığın/Kuyruk)
// Dictionary (hash map'in uygulanması) (Sözlük)
// HashSet (karma seti)
// Read-only Collections (Değiştirilemez koleksiyonlar)
// Tuple (.Net 4+) (tüp)
///////////////////////////////////////
// Operatörler
///////////////////////////////////////
Console.WriteLine("\n->Operators");
int i1 = 1, i2 = 2; // Birden çok tanımlamanın kısa yolu
// Aritmetik basittir
Console.WriteLine(i1 + i2 - i1 * 3 / 7); // => 3
// Mod
Console.WriteLine("11%3 = " + (11 % 3)); // => 2
// Karşılaştırma operatörleri
Console.WriteLine("3 == 2? " + (3 == 2)); // => false
Console.WriteLine("3 != 2? " + (3 != 2)); // => true
Console.WriteLine("3 > 2? " + (3 > 2)); // => true
Console.WriteLine("3 < 2? " + (3 < 2)); // => false
Console.WriteLine("2 <= 2? " + (2 <= 2)); // => true
Console.WriteLine("2 >= 2? " + (2 >= 2)); // => true
// Bit düzeyi operatörleri!
/*
~ Tekli bit tamamlayıcısı
<< Sola kaydırma Signed left shift
>> Sağa kaydırma Signed right shift
& Bit düzeyi AND
^ Bit düzeyi harici OR
| Bit düzeyi kapsayan OR
*/
// Arttırma
int i = 0;
Console.WriteLine("\n->Inc/Dec-rementation");
Console.WriteLine(i++); //i = 1. Post-Incrementation
Console.WriteLine(++i); //i = 2. Pre-Incrementation
Console.WriteLine(i--); //i = 1. Post-Decrementation
Console.WriteLine(--i); //i = 0. Pre-Decrementation
///////////////////////////////////////
// Kontrol Yapıları
///////////////////////////////////////
Console.WriteLine("\n->Control Structures");
// If ifadesi c benzeridir
int j = 10;
if (j == 10)
{
Console.WriteLine("I get printed");
}
else if (j > 10)
{
Console.WriteLine("I don't");
}
else
{
Console.WriteLine("I also don't");
}
// Üçlü operatörler
// Basit bir if/else ifadesi şöyle yazılabilir
// <koşul> ? <true> : <false>
string isTrue = (true) ? "True" : "False";
// While döngüsü
int fooWhile = 0;
while (fooWhile < 100)
{
//100 kere tekrarlanır, fooWhile 0->99
fooWhile++;
}
// Do While Döngüsü
int fooDoWhile = 0;
do
{
//100 kere tekrarlanır, fooDoWhile 0->99
fooDoWhile++;
} while (fooDoWhile < 100);
//for döngüsü yapısı => for(<başlangıç ifadesi>; <koşul>; <adım>)
for (int fooFor = 0; fooFor < 10; fooFor++)
{
//10 kere tekrarlanır, fooFor 0->9
}
// For Each Döngüsü
// foreach döngüsü yapısı => foreach(<yineleyici tipi> <yineleyici ismi> in <enumerable>)
// foreach döngüsü, IEnumerable ya da IEnumerable<T> e dönüştürülmüş herhangi bir obje üzerinde döngü yapabilir
// .Net framework üzerindeki bütün koleksiyon tiplerinden (Dizi, Liste, Sözlük...)
// biri ya da hepsi uygulanarak gerçekleştirilebilir.
// (ToCharArray() silindi, çünkü string'ler aynı zamanda IEnumerable'dır.)
foreach (char character in "Hello World".ToCharArray())
{
//String içindeki bütün karakterler üzerinde döner
}
// Switch Case
// Bir switch byte, short, char ve int veri tipleri ile çalışır.
// Aynı zamanda sıralı tipler ile de çalışabilir.(Enum Tipleri bölümünde tartışıldı),
// String sınıfı, ve bir kaç özel sınıf kaydırılır
// basit tipler: Character, Byte, Short, and Integer.
int month = 3;
string monthString;
switch (month)
{
case 1:
monthString = "January";
break;
case 2:
monthString = "February";
break;
case 3:
monthString = "March";
break;
// Bir aksiyon için birden fazla durum atayabilirsiniz
// Ancak, break olmadan yeni bir durum ekleyemezsiniz
// (Eğer bunu yapmak istiyorsanız, goto komutu eklemek zorundasınız)
case 6:
case 7:
case 8:
monthString = "Summer time!!";
break;
default:
monthString = "Some other month";
break;
}
///////////////////////////////////////
// Veri Tipleri Dönüştürme ve Typecasting
///////////////////////////////////////
// Veri Dönüştürme
// String'i Integer'a Dönüştürme
// bu başarısız olursa hata fırlatacaktır
int.Parse("123");// "123" 'in Integer değerini döndürür
// try parse hata durumunda değişkene varsayılan bir değer atamak için kullanılır
// bu durumda: 0
int tryInt;
if (int.TryParse("123", out tryInt)) // Fonksiyon boolean'dır
Console.WriteLine(tryInt); // 123
// Integer'ı String'e Dönüştürme
// Convert sınıfı dönüştürme işlemini kolaylaştırmak için bir dizi metoda sahiptir
Convert.ToString(123);
// veya
tryInt.ToString();
}
///////////////////////////////////////
// SINIFLAR - dosyanın sonunda tanımları görebilirsiniz
///////////////////////////////////////
public static void Classes()
{
// Obje tanımlamalarını dosyanın sonunda görebilirsiniz
// Bir sınıfı türetmek için new kullanın
Bicycle trek = new Bicycle();
// Obje metodlarını çağırma
trek.SpeedUp(3); // Her zaman setter ve getter metodları kullanmalısınız
trek.Cadence = 100;
// ToString objenin değerini göstermek için kullanılır.
Console.WriteLine("trek info: " + trek.Info());
// Yeni bir Penny Farthing sınıfı türetmek
PennyFarthing funbike = new PennyFarthing(1, 10);
Console.WriteLine("funbike info: " + funbike.Info());
Console.Read();
} // Ana metodun sonu
// KONSOLE BAŞLANGICI Bir konsol uygulaması başlangıç olarak mutlaka ana metod'a sahip olmalı
public static void Main(string[] args)
{
OtherInterestingFeatures();
}
//
// İLGİNÇ ÖZELLİKLER
//
// VARSAYILAN METOD TANIMLAMALARI
public // Görünebilir
static // Sınıf üzerinden obje türetmeden çağırılabilir
int // Dönüş Tipi,
MethodSignatures(
int maxCount, // İlk değişken, int değer bekler
int count = 0, // Eğer değer gönderilmezse varsayılan olarak 0 değerini alır
int another = 3,
params string[] otherParams // Metoda gönderilen diğer bütün parametreleri alır
)
{
return -1;
}
// Metodlar tanımlamalar benzersiz ise aynı isimleri alabilirler
public static void MethodSignatures(string maxCount)
{
}
// GENERIC'LER
// TKey ve TValue değerleri kullanıcı tarafından bu fonksiyon çağırılırken belirtilir.
// Bu metod Python'daki SetDefault'a benzer
public static TValue SetDefault<TKey, TValue>(
IDictionary<TKey, TValue> dictionary,
TKey key,
TValue defaultItem)
{
TValue result;
if (!dictionary.TryGetValue(key, out result))
return dictionary[key] = defaultItem;
return result;
}
// Gönderilen objeleri daraltabilirsiniz
public static void IterateAndPrint<T>(T toPrint) where T: IEnumerable<int>
{
// Eğer T IEnumerable ise tekrarlayabiliriz
foreach (var item in toPrint)
// Item bir int
Console.WriteLine(item.ToString());
}
public static void OtherInterestingFeatures()
{
// İSTEĞE BAĞLI PARAMETRELER
MethodSignatures(3, 1, 3, "Some", "Extra", "Strings");
MethodSignatures(3, another: 3); // isteğe bağlı olanlar gönderilmedi
// UZANTI METODLARI
int i = 3;
i.Print(); // Aşağıda tanımlandı
// NULLABLE TYPES - veri tabanı işlemleri için uygun / return values
// Herhangi bir değer tipi sonuna ? eklenerek nullable yapılabilir (sınıflar hariç)
// <tip>? <değiken ismi> = <değer>
int? nullable = null; // Nullable<int> için kısa yol
Console.WriteLine("Nullable variable: " + nullable);
bool hasValue = nullable.HasValue; // eğer null değilse true döner
// ?? varsayılan değer belirlemek için söz dizimsel güzel bir özellik
// bu durumda değişken null'dır
int notNullable = nullable ?? 0; // 0
// TİPİ BELİRTİLMEMİŞ DEĞİŞKENLER - compiler değişkenin tipini bilmeden çalışabilir:
var magic = "magic is a string, at compile time, so you still get type safety";
// magic = 9; string gibi çalışmayacaktır, bu bir int değil
// GENERIC'LER
//
var phonebook = new Dictionary<string, string>() {
{"Sarah", "212 555 5555"} // Telefon rehberine bir kaç numara ekleyelim.
};
// Yukarıda generic olarak tanımlanan SETDEFAULT'u çağırma
Console.WriteLine(SetDefault<string,string>(phonebook, "Shaun", "No Phone")); // Telefonu yok
// TKey ve TValue tipini belirtmek zorunda değilsiniz
Console.WriteLine(SetDefault(phonebook, "Sarah", "No Phone")); // 212 555 5555
// LAMBDA IFADELERİ - satır içinde kod yazmanıza olanak sağlar
Func<int, int> square = (x) => x * x; // Son T nesnesi dönüş değeridir
Console.WriteLine(square(3)); // 9
// TEK KULLANIMLIK KAYNAK YÖNETİMİ - Yönetilemeyen kaynakların üstesinden kolayca gelebilirsiniz.
// Bir çok obje yönetilemeyen kaynaklara (dosya yakalama, cihaz içeriği, vb.)
// IDisposable arabirimi ile erişebilir. Using ifadesi sizin için IDisposable objeleri temizler.
using (StreamWriter writer = new StreamWriter("log.txt"))
{
writer.WriteLine("Nothing suspicious here");
// Bu bölümün sonunda kaynaklar temilenir.
// Hata fırlatılmış olsa bile.
}
// PARALEL FRAMEWORK
// http://blogs.msdn.com/b/csharpfaq/archive/2010/06/01/parallel-programming-in-net-framework-4-getting-started.aspx
var websites = new string[] {
"http://www.google.com", "http://www.reddit.com",
"http://www.shaunmccarthy.com"
};
var responses = new Dictionary<string, string>();
// Her istek farklı bir thread de işlem görecek
// bir sonraki işleme geçmeden birleştirilecek.
Parallel.ForEach(websites,
new ParallelOptions() {MaxDegreeOfParallelism = 3}, // en fazla 3 thread kullanmak için
website =>
{
// Uzun sürecek bir işlem yapın
using (var r = WebRequest.Create(new Uri(website)).GetResponse())
{
responses[website] = r.ContentType;
}
});
// Bütün istekler tamamlanmadan bu döndü çalışmayacaktır.
foreach (var key in responses.Keys)
Console.WriteLine("{0}:{1}", key, responses[key]);
// DİNAMİK OBJELER (diğer dillerle çalışırken kullanmak için uygun)
dynamic student = new ExpandoObject();
student.FirstName = "First Name"; // Önce yeni bir sınıf tanımlamanız gerekmez!
// Hatta metod bile ekleyebilirsiniz (bir string döner, ve bir string alır)
student.Introduce = new Func<string, string>(
(introduceTo) => string.Format("Hey {0}, this is {1}", student.FirstName, introduceTo));
Console.WriteLine(student.Introduce("Beth"));
// IQUERYABLE<T> - neredeyse bütün koleksiyonlar bundan türer, bu size bir çok
// kullanışlı Map / Filter / Reduce stili metod sağlar.
var bikes = new List<Bicycle>();
bikes.Sort(); // Dizi sıralama
bikes.Sort((b1, b2) => b1.Wheels.CompareTo(b2.Wheels)); // Wheels baz alınarak sıralama
var result = bikes
.Where(b => b.Wheels > 3) // Filters- chainable (bir önceki tipin IQueryable'ını döner)
.Where(b => b.IsBroken && b.HasTassles)
.Select(b => b.ToString()); // Map - sadece bunu seçiyoruz, yani sonuç bir IQueryable<string> olacak
var sum = bikes.Sum(b => b.Wheels); // Reduce - koleksiyonda bulunan bütün wheel değerlerinin toplamı
// Bike içindeki bazı parametreleri baz alarak bir liste oluşturmak
var bikeSummaries = bikes.Select(b=>new { Name = b.Name, IsAwesome = !b.IsBroken && b.HasTassles });
// Burada göstermek zor ama, compiler yukaridaki tipleri çözümleyebilirse derlenmeden önce tipi verebilir.
foreach (var bikeSummary in bikeSummaries.Where(b => b.IsAwesome))
Console.WriteLine(bikeSummary.Name);
// ASPARALLEL
// Linq ve paralel işlemlerini birleştirme
var threeWheelers = bikes.AsParallel().Where(b => b.Wheels == 3).Select(b => b.Name);
// bu paralel bir şekilde gerçekleşecek! Threadler otomatik ve sihirli bir şekilde işleri paylaşacak!
// Birden fazla çekirdeğiniz varsa büyük veri setleri ile kullanmak için oldukça uygun bir yapı.
// LINQ - IQueryable<T> objelerini mapler ve saklar, gecikmeli bir işlemdir
// e.g. LinqToSql - veri tabanını mapler, LinqToXml xml dökümanlarını mapler.
var db = new BikeRepository();
// işlem gecikmelidir, bir veri tabanı üzerinde sorgulama yaparken harikadır.
var filter = db.Bikes.Where(b => b.HasTassles); // sorgu henüz çalışmadı
if (42 > 6) // Filtreler eklemeye devam edebilirsiniz - ileri düzey arama fonksiyonları için harikadır
filter = filter.Where(b => b.IsBroken); // sorgu henüz çalışmadı
var query = filter
.OrderBy(b => b.Wheels)
.ThenBy(b => b.Name)
.Select(b => b.Name); // hala sorgu çalışmadı
// Şimdi sorgu çalışıyor, reader'ı açar ama sadece sizin sorgunuza uyanlar foreach döngüsüne girer.
foreach (string bike in query)
Console.WriteLine(result);
}
} // LearnCSharp sınıfının sonu
// Bir .cs dosyasına diğer sınıflarıda dahil edebilirsiniz
public static class Extensions
{
// UZANTI FONKSİYONLARI
public static void Print(this object obj)
{
Console.WriteLine(obj.ToString());
}
}
// Sınıf Tanımlama Sözdizimi:
// <public/private/protected/internal> class <sınıf ismi>{
// //veri alanları, kurucular , fonksiyonlar hepsi içindedir.
// //Fonksiyonlar Java'daki gibi metod olarak çağırılır.
// }
public class Bicycle
{
// Bicycle'ın Alanları/Değişkenleri
public int Cadence // Public: herhangi bir yerden erişilebilir
{
get // get - değeri almak için tanımlanan metod
{
return _cadence;
}
set // set - değer atamak için tanımlanan metod
{
_cadence = value; // Değer setter'a gönderilen value değeridir
}
}
private int _cadence;
protected virtual int Gear // Protected: Sınıf ve alt sınıflar tarafından erişilebilir
{
get; // bir üye alanına ihtiyacınız yok, bu otomatik olarak bir değer oluşturacaktır
set;
}
internal int Wheels // Internal: Assembly tarafından erişilebilir
{
get;
private set; // Nitelik belirleyicileri get/set metodlarında atayabilirsiniz
}
int _speed; // Her şey varsayılan olarak private'dır : Sadece sınıf içinden erişilebilir.
// İsterseniz yinede private kelimesini kullanabilirsiniz.
public string Name { get; set; }
// Enum sabitler kümesinden oluşan bir değer tipidir.
// Gerçekten sadece bir isim ile bir değeri tutmak için kullanılır. (aksi belirtilmedikçe bir int'dir).
// İzin verilen enum tipleri şunlardır byte, sbyte, short, ushort, int, uint, long, veya ulong.
// Bir enum aynı değeri birden fazla sayıda barındıramaz.
public enum BikeBrand
{
AIST,
BMC,
Electra = 42, // bir isme tam bir değer verebilirsiniz
Gitane // 43
}
// Bu tipi Bicycle sınıfı içinde tanımladığımız için bu bir bağımlı tipdir.
// Bu sınıf dışında kullanmak için tipi Bicycle.Brand olarak kullanmamız gerekir
public BikeBrand Brand; // Enum tipini tanımladıktan sonra alan tipini tanımlayabiliriz
// Static üyeler belirli bir obje yerine kendi tipine aittir
// Onlara bir obje referans göstermeden erişebilirsiniz:
// Console.WriteLine("Bicycles created: " + Bicycle.bicyclesCreated);
static public int BicyclesCreated = 0;
// readonly değerleri çalışma zamanında atanır
// onlara sadece tanımlama yapılarak ya da kurucular içinden atama yapılabilir
readonly bool _hasCardsInSpokes = false; // read-only private
// Kurucular sınıf oluşturmanın bir yoludur
// Bu bir varsayılan kurucudur.
public Bicycle()
{
this.Gear = 1; // bu objenin üyelerine this anahtar kelimesi ile ulaşılır
Cadence = 50; // ama her zaman buna ihtiyaç duyulmaz
_speed = 5;
Name = "Bontrager";
Brand = BikeBrand.AIST;
BicyclesCreated++;
}
// Bu belirlenmiş bir kurucudur. (argümanlar içerir)
public Bicycle(int startCadence, int startSpeed, int startGear,
string name, bool hasCardsInSpokes, BikeBrand brand)
: base() // önce base'i çağırın
{
Gear = startGear;
Cadence = startCadence;
_speed = startSpeed;
Name = name;
_hasCardsInSpokes = hasCardsInSpokes;
Brand = brand;
}
// Kurucular zincirleme olabilir
public Bicycle(int startCadence, int startSpeed, BikeBrand brand) :
this(startCadence, startSpeed, 0, "big wheels", true, brand)
{
}
// Fonksiyon Sözdizimi:
// <public/private/protected> <dönüş tipi> <fonksiyon ismi>(<argümanlar>)
// sınıflar getter ve setter'ları alanları için kendisi uygular
// veya property'ler eklenebilir (C# da tercih edilen yol budur)
// Metod parametreleri varsayılan değerlere sahip olabilir.
// Bu durumda, metodlar bu parametreler olmadan çağırılabilir.
public void SpeedUp(int increment = 1)
{
_speed += increment;
}
public void SlowDown(int decrement = 1)
{
_speed -= decrement;
}
// property'lerin get/set değerleri
// sadece veri gerektiği zaman erişilebilir, kullanmak için bunu göz önünde bulundurun.
// property'ler sadece get ya da set'e sahip olabilir veya ikisine birden
private bool _hasTassles; // private değişken
public bool HasTassles // public accessor
{
get { return _hasTassles; }
set { _hasTassles = value; }
}
// Ayrıca tek bir satırda otomatik property tanımlayabilirsiniz.
// bu söz dizimi otomatik olarak alan oluşturacaktır.
// Erişimi kısıtlamak için nitelik belirleyiciler getter veya setter'a ya da ikisine birden atanabilir:
public bool IsBroken { get; private set; }
// Property'ler otomatik eklenmiş olabilir
public int FrameSize
{
get;
// nitelik beliryecileri get veya set için tanımlayabilirsiniz
// bu sadece Bicycle sınıfı Framesize değerine atama yapabilir demektir
private set;
}
// Ayrıca obje üzerinde özel indeksleyici belirlemek mümkündür.
// Tüm bunlar bu örnek için çok kullanışlı değil,
// bicycle[0] ile ilk yolcu olan "chris" i almak mümkün veya
// bicycle[1] = "lisa" ile yolcuyu atayabilirsiniz. (bariz quattrocycle)
private string[] passengers = { "chris", "phil", "darren", "regina" }
public string this[int i]
{
get {
return passengers[i];
}
set {
return passengers[i] = value;
}
}
//Bu objenin nitelik değerlerini göstermek için bir metod.
public virtual string Info()
{
return "Gear: " + Gear +
" Cadence: " + Cadence +
" Speed: " + _speed +
" Name: " + Name +
" Cards in Spokes: " + (_hasCardsInSpokes ? "yes" : "no") +
"\n------------------------------\n"
;
}
// Metodlar static olabilir. Yardımcı metodlar için kullanışlı olabilir.
public static bool DidWeCreateEnoughBycles()
{
// Bir static metod içinde sadece static sınıf üyeleri referans gösterilebilir
return BicyclesCreated > 9000;
} // Eğer sınıfınızın sadece static üyelere ihtiyacı varsa, sınıfın kendisini static yapmayı düşünebilirsiniz.
} // Bicycle sınıfı sonu
// PennyFarthing , Bicycle sınıfının alt sınıfıdır.
class PennyFarthing : Bicycle
{
// (Penny Farthing'ler ön jantı büyük bisikletlerdir.
// Vitesleri yoktur.)
// Ana kurucuyu çağırmak
public PennyFarthing(int startCadence, int startSpeed) :
base(startCadence, startSpeed, 0, "PennyFarthing", true, BikeBrand.Electra)
{
}
protected override int Gear
{
get
{
return 0;
}
set
{
throw new ArgumentException("You can't change gears on a PennyFarthing");
}
}
public override string Info()
{
string result = "PennyFarthing bicycle ";
result += base.ToString(); // Metodun temel versiyonunu çağırmak
return result;
}
}
// Arabirimler sadece üyelerin izlerini içerir, değerlerini değil.
interface IJumpable
{
void Jump(int meters); // bütün arbirim üyeleri public'tir
}
interface IBreakable
{
bool Broken { get; } // arabirimler property'leri, metodları ve olayları içerebilir
}
// Sınıflar sadece tek bir sınıftan miras alabilir ama sınırsız sayıda arabirime sahip olabilir
class MountainBike : Bicycle, IJumpable, IBreakable
{
int damage = 0;
public void Jump(int meters)
{
damage += meters;
}
public bool Broken
{
get
{
return damage > 100;
}
}
}
/// <summary>
/// LinqToSql örneği veri tabanına bağlanmak için kullanılır.
/// EntityFramework Code First harika! (Ruby'deki ActiveRecord'a benzer, ama iki yönlü)
/// http://msdn.microsoft.com/en-us/data/jj193542.aspx
/// </summary>
public class BikeRepository : DbSet
{
public BikeRepository()
: base()
{
}
public DbSet<Bicycle> Bikes { get; set; }
}
} // namespace sonu
```
## İşlenmeyen Konular
* Flags
* Attributes
* Static properties
* Exceptions, Abstraction
* ASP.NET (Web Forms/MVC/WebMatrix)
* Winforms
* Windows Presentation Foundation (WPF)
## Daha Fazlasını Okuyun
* [DotNetPerls](http://www.dotnetperls.com)
* [C# in Depth](http://manning.com/skeet2)
* [Programming C#](http://shop.oreilly.com/product/0636920024064.do)
* [LINQ](http://shop.oreilly.com/product/9780596519254.do)
* [MSDN Library](http://msdn.microsoft.com/en-us/library/618ayhy6.aspx)
* [ASP.NET MVC Tutorials](http://www.asp.net/mvc/tutorials)
* [ASP.NET Web Matrix Tutorials](http://www.asp.net/web-pages/tutorials)
* [ASP.NET Web Forms Tutorials](http://www.asp.net/web-forms/tutorials)
* [Windows Forms Programming in C#](http://www.amazon.com/Windows-Forms-Programming-Chris-Sells/dp/0321116208)
[C# Kodlama Adetleri](http://msdn.microsoft.com/en-us/library/vstudio/ff926074.aspx)

View File

@ -0,0 +1,251 @@
---
language: markdown
contributors:
- ["Dan Turkel", "http://danturkel.com/"]
translators:
- ["Eray AYDIN", "http://erayaydin.me/"]
lang: tr-tr
filename: markdown-tr.md
---
Markdown, 2004 yılında John Gruber tarafından oluşturuldu. Asıl amacı kolay okuma ve yazmayı sağlamakla beraber kolayca HTML (artık bir çok diğer formatlara) dönüşüm sağlamaktır.
```markdown
<!-- Markdown, HTML'i kapsar, yani her HTML dosyası geçerli bir Markdown dosyasıdır, bu demektir
ki Markdown içerisinde HTML etiketleri kullanabiliriz, örneğin bu yorum elementi, ve
markdown işleyicisinde etki etmezler. Fakat, markdown dosyası içerisinde HTML elementi oluşturursanız,
bu elementin içeriğinde markdown söz dizimlerini kullanamazsınız. -->
<!-- Markdown ayrıca işleyiciden işleyiciye farklılık gösterebilir. Bu rehberde
evrensel özelliklere uygun anlatımlar olacaktır. Bir çok işleyici bu rehberdeki
anlatımları destekler -->
<!-- Başlıklar -->
<!-- Kolayca <h1>'den <h6>'ya HTML etiketleri oluşturabilirsiniz.
Kare (#) sayısı bu elementin numarasını belirleyecek ve devamında getirdiğiniz
yazı bu elementin içeriği olacaktır
-->
# Bu bir <h1>
## Bu bir <h2>
### Bu bir <h3>
#### Bu bir <h4>
##### Bu bir <h5>
###### Bu bir <h6>
<!-- Markdown ayrıca h1 ve h2 için 2 alternatif yol daha taşır -->
Bu bir h1
=========
Bu bir h2
---------
<!-- Basit yazı stilleri -->
<!-- Markdown ile yazılar kolayca italik ve kalın belirtilebilir -->
*Bu yazı italik.*
_Bu yazı da italik._
**Bu yazı kalın.**
__Bu yazı da kalın.__
***Bu yazı hem kalın hem italik.***
**_Bu da öyle!_**
*__Hatta bu bile!__*
<!-- Github Flavored Markdown'da ayrıca üstü çizgili karakter de desteklenir: -->
~~Bu yazı üstü çizili olarak gözükecek.~~
<!-- Paragraflar bir veya daha fazla boş satırla ayrılır. -->
Bu bir paragraf. Paragrafın içeriğine devam ediyorum, eğlenceli değil mi?
Şimdi 2. paragrafıma geçtim.
Hala 2. paragraftayım, çünkü boş bir satır bırakmadım.
Bu da 3. paragrafım!
<!-- HTML'de her satır için <br /> etiketi kullanmak ister misiniz, Bir
paragrafı bitirdikten sonra 2 veya daha fazla boşluk bırakın ve yeni paragrafa
başlayın, bu bir <br /> etiketi sayılacaktır -->
Bu yazının sonunda 2 boşluk var (bu satırı seçerek kontrol edebilirsiniz).
Bir üst satırda <br /> etiketi var!
<!-- Blok yazılarının yapımı oldukça kolay, (>) karakteri ile yapabilirsiniz -->
> Bu bir blok etiketi. Satırlara ayırmak için
> her satırın başında `>` karakter yerleştirmeli veya tek satırda bütün içeriği yazabilirsiniz.
> Satır `>` karakteri ile başladığı sürece sorun yok.
> Ayrıca alt alta da blok elementi açabilirsiniz
>> iç içe yani
> düzgün değil mi ?
<!-- Listeler -->
<!-- Numarasız listeler için yıldız, artı, veya tire kullanabilirsiniz -->
* Nesne
* Nesne
* Bir başka nesne
veya
+ Nesne
+ Nesne
+ Bir başka nesne
veya
- Nesne
- Nesne
- Son bir nesne
<!-- Numaralı liste için başına sıralı bir şekilde sayı eklemeniz yeterli -->
1. İlk nesne
2. İkinci nesne
3. Üçüncü nesne
<!-- İsterseniz sıralı bir şekilde yazmak zorunda değilsiniz, markdown
biçimlendirirken sizin için sıralayacaktır, fakat bunu önermiyorum. Markdown dosyasının
düzgün gözükmesi için önerilen metodu uygulamanızı tavsiye ederim -->
1. İlk nesne
1. İkinci nesne
1. Üçüncü nesne
<!-- (Bunun çıktısı ile, sıralı olarak yazdığımız örneğin çıktısı aynı olacaktır) -->
<!-- Ayrıca alt alta liste oluşturabilirsiniz -->
1. İlk nesne
2. İkinci nesne
3. Üçüncü nesne
* Alt nesne
* Alt nesne
4. Dördüncü nesne
<!-- Ayrıca görev listeleri de bulunmakta. HTML seçim kutusu(checkbox) oluşturacaktır. -->
Kutunun içerisinde `x` yoksa eğer seçim kutusu boş olacaktır.
- [ ] Yapılacak ilk görev.
- [ ] Yapılması gereken bir başka görev
Aşağıdaki seçim kutusu ise içi dolu olacaktır.
- [x] Bu görev başarıyla yapıldı
<!-- Kod blokları -->
<!-- Kod bloklarını(<code> elementi) belirtmek için 4 adet boşluk veya bir
tab karakterini kullanabilirsiniz -->
Bu bir kod
öyle mi?
<!-- Ayrıca kod içerisinde girinti kullanmak istiyorsanız tekrar `tab` veya `4 boşluk`
kullanabilirsiniz -->
my_array.each do |item|
puts item
end
<!-- Yazı içerisinde kod belirtmek için sorgu tırnağı (`) kullanabilirsiniz -->
Ahmet `go_to()` fonksiyonun ne yaptığını bilmiyor!
<!-- Github Flavored Markdown'da, kod içerisinde aydınlatma kullanabilirsiniz -->
\`\`\`ruby <!-- buradaki ters slaş (\) işaretlerini kullanmayın, sadece ```ruby ! -->
def foobar
puts "Hello world!"
end
\`\`\` <!-- burada da (\) işaretlerini kullanmayın, sadece ``` -->
<!-- Yukarıdaki örnekte girinti kullanmanıza gerek yok, Github da
``` işaretinden sonra belirttiğiniz yazılım diline göre gerekli
syntax aydınlatmaları uygulanacaktır -->
<!-- Düz çizgi (<hr />) -->
<!-- Düz çizgiler 3 veya daha fazla yıldız/çizgi ile yapılabilir. Boşluklar önemsiz. -->
***
---
- - -
****************
<!-- Linkler -->
<!-- Markdown'daki en güzel şeylerden biri kolayca link oluşturmaktır.
Linkte göstermek istediğiniz yazıyı [] içerisine yerleştirin ve sonuna parantezler içerisinde ()
gideceği adresi belirtin -->
[Bana tıkla!](http://test.com)
<!-- Ayrıca linke `title` özelliği eklemek için tırnakları kullanabilirsiniz -->
[Bana tıkla!](http://test.com "Test.com'a gider")
<!-- Bağıl yollar da çalışıyor. -->
[Müzik dinle](/muzik/).
<!-- Markdown ayrıca referans linklerini de destekler -->
[Bu linke tıklayarak][link1] daha detaylı bilgi alabilirsiniz!
[Ayrıca bu linki de inceleyin][foobar] tabi istiyorsanız.
[link1]: http://test.com/ "harika!"
[foobar]: http://foobar.biz/ "okey!"
<!--Başlık ayrıca tek tırnak veya parantez içinde olabilir, veya direk yazılabilir.
Referans döküman içerisindeki herhangi bir yer olabilir ve referans IDsi
benzersiz olduğu sürece sorunsuz çalışacaktır. -->
<!-- Ayrıca "dolaylı adlandırma" bulunmaktadır, "dolaylı adlandırma", linkin yazısının
aynı zamanda onun idsi olmasıdır -->
[Bu][] bir link.
[bu]: http://bubirlink.com
<!-- Fakat bu çok tercih edilen bir yöntem değil. -->
<!-- Resimler -->
<!-- Resimler aslında linklere çok benziyor fakat başında ünlem bulunuyor! -->
![Bu alt etiketine gelecek içerik](http://imgur.com/resmim.jpg "Bu da isteğe bağlı olan bir başlık")
<!-- Referanslar resimler için de geçerli -->
![Bu alt etiketi.][resmim]
[resmim]: bagil/linkler/de/calisiyor.jpg "Başlık isterseniz buraya girebilirsiniz"
<!-- Çeşitli -->
<!-- Oto-linkler -->
<http://testwebsite.com/> ile
[http://testwebsite.com/](http://testwebsite.com) aynı şeyler
<!-- Oto-linkler epostaları da destekler -->
<foo@bar.com>
<!-- Kaçış karakterleri -->
Bu yazının *yıldızlar arasında gözükmesini* istiyorum fakat italik olmamasını istiyorum,
bunun için, şu şekilde: \*bu yazı italik değil, yıldızlar arasında\*.
<!-- Tablolar -->
<!-- Tablolar sadece Github Flavored Markdown'da destekleniyor ve açıkçası
performansı çok yoruyorlar, fakat illa ki kullanmak isterseniz: -->
| Sütun1 | Sütun 2 | Sütün 3 |
| :----------- | :------: | ------------: |
| Sola dayalı | Ortalı | Sağa dayalı |
| test | test | test |
<!-- ayrıca, bunun aynısı -->
Sütun 1 | Sütun 2 | Sütun 3
:-- | :-: | --:
Çok çirkin göözüküyor | değil | mi?
<!-- Bitiş! -->
```
Daha detaylı bilgi için, John Gruber'in resmi söz dizimi yazısını [buradan](http://daringfireball.net/projects/markdown/syntax) veya Adam Pritchard'ın mükemmel hatırlatma kağıdını [buradan](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet) inceleyebilirsiniz.

View File

@ -0,0 +1,635 @@
---
language: python3
contributors:
- ["Louie Dinh", "http://pythonpracticeprojects.com"]
- ["Steven Basart", "http://github.com/xksteven"]
- ["Andre Polykanine", "https://github.com/Oire"]
- ["Andre Polykanine", "https://github.com/Oire"]
translators:
- ["Eray AYDIN", "http://erayaydin.me/"]
lang: tr-tr
filename: learnpython3-tr.py
---
Python,90ların başlarında Guido Van Rossum tarafından oluşturulmuştur. En popüler olan dillerden biridir. Beni Python'a aşık eden sebep onun syntax beraklığı. Çok basit bir çalıştırılabilir söz koddur.
Not: Bu makale Python 3 içindir. Eğer Python 2.7 öğrenmek istiyorsanız [burayı](http://learnxinyminutes.com/docs/python/) kontrol edebilirsiniz.
```python
# Tek satırlık yorum satırı kare(#) işareti ile başlamaktadır.
""" Çok satırlı olmasını istediğiniz yorumlar
üç adet tırnak(") işareti ile
yapılmaktadır
"""
####################################################
## 1. Temel Veri Türleri ve Operatörler
####################################################
# Sayılar
3 # => 3
# Tahmin edebileceğiniz gibi matematik
1 + 1 # => 2
8 - 1 # => 7
10 * 2 # => 20
# Bölme işlemi varsayılan olarak onluk döndürür
35 / 5 # => 7.0
# Tam sayı bölmeleri, pozitif ve negatif sayılar için aşağıya yuvarlar
5 // 3 # => 1
5.0 // 3.0 # => 1.0 # onluklar için de bu böyledir
-5 // 3 # => -2
-5.0 // 3.0 # => -2.0
# Onluk kullanırsanız, sonuç da onluk olur
3 * 2.0 # => 6.0
# Kalan operatörü
7 % 3 # => 1
# Üs (2 üzeri 4)
2**4 # => 16
# Parantez ile önceliği değiştirebilirsiniz
(1 + 3) * 2 # => 8
# Boolean(Doğru-Yanlış) değerleri standart
True
False
# 'değil' ile terse çevirme
not True # => False
not False # => True
# Boolean Operatörleri
# "and" ve "or" büyük küçük harf duyarlıdır
True and False #=> False
False or True #=> True
# Bool operatörleri ile sayı kullanımı
0 and 2 #=> 0
-5 or 0 #=> -5
0 == False #=> True
2 == True #=> False
1 == True #=> True
# Eşitlik kontrolü ==
1 == 1 # => True
2 == 1 # => False
# Eşitsizlik Kontrolü !=
1 != 1 # => False
2 != 1 # => True
# Diğer karşılaştırmalar
1 < 10 # => True
1 > 10 # => False
2 <= 2 # => True
2 >= 2 # => True
# Zincirleme şeklinde karşılaştırma da yapabilirsiniz!
1 < 2 < 3 # => True
2 < 3 < 2 # => False
# Yazı(Strings) " veya ' işaretleri ile oluşturulabilir
"Bu bir yazı."
'Bu da bir yazı.'
# Yazılar da eklenebilir! Fakat bunu yapmanızı önermem.
"Merhaba " + "dünya!" # => "Merhaba dünya!"
# Bir yazı(string) karakter listesi gibi işlenebilir
"Bu bir yazı"[0] # => 'B'
# .format ile yazıyı biçimlendirebilirsiniz, şu şekilde:
"{} da ayrıca {}".format("yazılar", "işlenebilir")
# Biçimlendirme işleminde aynı argümanı da birden fazla kullanabilirsiniz.
"{0} çeviktir, {0} hızlıdır, {0} , {1} üzerinden atlayabilir".format("Ahmet", "şeker çubuğu")
#=> "Ahmet çeviktir, Ahmet hızlıdır, Ahmet , şeker çubuğu üzerinden atlayabilir"
# Argümanın sırasını saymak istemiyorsanız, anahtar kelime kullanabilirsiniz.
"{isim} yemek olarak {yemek} istiyor".format(isim="Ahmet", yemek="patates") #=> "Ahmet yemek olarak patates istiyor"
# Eğer Python 3 kodunuz ayrıca Python 2.5 ve üstünde çalışmasını istiyorsanız,
# eski stil formatlamayı kullanabilirsiniz:
"%s bu %s yolla da %s" % ("yazılar", "eski", "biçimlendirilebilir")
# Hiçbir şey(none) da bir objedir
None # => None
# Bir değerin none ile eşitlik kontrolü için "==" sembolünü kullanmayın
# Bunun yerine "is" kullanın. Obje türünün eşitliğini kontrol edecektir.
"vb" is None # => False
None is None # => True
# None, 0, ve boş yazılar/listeler/sözlükler hepsi False değeri döndürü.
# Diğer veriler ise True değeri döndürür
bool(0) # => False
bool("") # => False
bool([]) #=> False
bool({}) #=> False
####################################################
## 2. Değişkenler ve Koleksiyonlar
####################################################
# Python bir yazdırma fonksiyonuna sahip
print("Ben Python. Tanıştığıma memnun oldum!")
# Değişkenlere veri atamak için önce değişkeni oluşturmanıza gerek yok.
# Düzenli bir değişken için hepsi_kucuk_ve_alt_cizgi_ile_ayirin
bir_degisken = 5
bir_degisken # => 5
# Önceden tanımlanmamış değişkene erişmek hata oluşturacaktır.
# Kontrol akışları başlığından hata kontrolünü öğrenebilirsiniz.
bir_bilinmeyen_degisken # NameError hatası oluşturur
# Listeler ile sıralamaları tutabilirsiniz
li = []
# Önceden doldurulmuş listeler ile başlayabilirsiniz
diger_li = [4, 5, 6]
# 'append' ile listenin sonuna ekleme yapabilirsiniz
li.append(1) # li artık [1] oldu
li.append(2) # li artık [1, 2] oldu
li.append(4) # li artık [1, 2, 4] oldu
li.append(3) # li artık [1, 2, 4, 3] oldu
# 'pop' ile listenin son elementini kaldırabilirsiniz
li.pop() # => 3 ve li artık [1, 2, 4]
# Çıkarttığımız tekrardan ekleyelim
li.append(3) # li yeniden [1, 2, 4, 3] oldu.
# Dizi gibi listeye erişim sağlayın
li[0] # => 1
# Son elemente bakın
li[-1] # => 3
# Listede olmayan bir elemente erişim sağlamaya çalışmak IndexError hatası oluşturur
li[4] # IndexError hatası oluşturur
# Bir kısmını almak isterseniz.
li[1:3] # => [2, 4]
# Başlangıç belirtmezseniz
li[2:] # => [4, 3]
# Sonu belirtmesseniz
li[:3] # => [1, 2, 4]
# Her ikişer objeyi seçme
li[::2] # =>[1, 4]
# Listeyi tersten almak
li[::-1] # => [3, 4, 2, 1]
# Kombinasyonları kullanarak gelişmiş bir şekilde listenin bir kısmını alabilirsiniz
# li[baslangic:son:adim]
# "del" ile isteğe bağlı, elementleri listeden kaldırabilirsiniz
del li[2] # li artık [1, 2, 3] oldu
# Listelerde de ekleme yapabilirsiniz
# Not: değerler üzerinde değişiklik yapılmaz.
li + diger_li # => [1, 2, 3, 4, 5, 6]
# Listeleri birbirine bağlamak için "extend()" kullanılabilir
li.extend(diger_li) # li artık [1, 2, 3, 4, 5, 6] oldu
# Listedeki bir elementin olup olmadığı kontrolü "in" ile yapılabilir
1 in li # => True
# Uzunluğu öğrenmek için "len()" kullanılabilir
len(li) # => 6
# Tüpler listeler gibidir fakat değiştirilemez.
tup = (1, 2, 3)
tup[0] # => 1
tup[0] = 3 # TypeError hatası oluşturur
# Diğer liste işlemlerini tüplerde de uygulayabilirsiniz
len(tup) # => 3
tup + (4, 5, 6) # => (1, 2, 3, 4, 5, 6)
tup[:2] # => (1, 2)
2 in tup # => True
# Tüpleri(veya listeleri) değişkenlere açabilirsiniz
a, b, c = (1, 2, 3) # 'a' artık 1, 'b' artık 2 ve 'c' artık 3
# Eğer parantez kullanmazsanız varsayılan oalrak tüpler oluşturulur
d, e, f = 4, 5, 6
# 2 değeri birbirine değiştirmek bu kadar kolay
e, d = d, e # 'd' artık 5 ve 'e' artık 4
# Sözlükler anahtar kodlarla verileri tutar
bos_sozl = {}
# Önceden doldurulmuş sözlük oluşturma
dolu_sozl = {"bir": 1, "iki": 2, "uc": 3}
# Değere bakmak için [] kullanalım
dolu_sozl["bir"] # => 1
# Bütün anahtarları almak için "keys()" kullanılabilir.
# Listelemek için list() kullanacağınız çünkü dönen değerin işlenmesi gerekiyor. Bu konuya daha sonra değineceğiz.
# Not - Sözlük anahtarlarının sıralaması kesin değildir.
# Beklediğiniz çıktı sizinkiyle tam uyuşmuyor olabilir.
list(dolu_sozl.keys()) # => ["uc", "iki", "bir"]
# Tüm değerleri almak için "values()" kullanacağız. Dönen değeri biçimlendirmek için de list() kullanmamız gerekiyor
# Not - Sıralama değişebilir.
list(dolu_sozl.values()) # => [3, 2, 1]
# Bir anahtarın sözlükte olup olmadığını "in" ile kontrol edebilirsiniz
"bir" in dolu_sozl # => True
1 in dolu_sozl # => False
# Olmayan bir anahtardan değer elde etmek isterseniz KeyError sorunu oluşacaktır.
dolu_sozl["dort"] # KeyError hatası oluşturur
# "get()" metodu ile değeri almaya çalışırsanız KeyError sorunundan kurtulursunuz
dolu_sozl.get("bir") # => 1
dolu_sozl.get("dort") # => None
# "get" metoduna parametre belirterek değerin olmaması durumunda varsayılan bir değer döndürebilirsiniz.
dolu_sozl.get("bir", 4) # => 1
dolu_sozl.get("dort", 4) # => 4
# "setdefault()" metodu sözlükte, belirttiğiniz anahtarın [olmaması] durumunda varsayılan bir değer atayacaktır
dolu_sozl.setdefault("bes", 5) # dolu_sozl["bes"] artık 5 değerine sahip
dolu_sozl.setdefault("bes", 6) # dolu_sozl["bes"] değişmedi, hala 5 değerine sahip
# Sözlüğe ekleme
dolu_sozl.update({"dort":4}) #=> {"bir": 1, "iki": 2, "uc": 3, "dort": 4}
#dolu_sozl["dort"] = 4 #sözlüğe eklemenin bir diğer yolu
# Sözlükten anahtar silmek için 'del' kullanılabilir
del dolu_sozl["bir"] # "bir" anahtarını dolu sözlükten silecektir
# Setler ... set işte :D
bos_set = set()
# Seti bir veri listesi ile de oluşturabilirsiniz. Evet, biraz sözlük gibi duruyor. Üzgünüm.
bir_set = {1, 1, 2, 2, 3, 4} # bir_set artık {1, 2, 3, 4}
# Sete yeni setler ekleyebilirsiniz
dolu_set = bir_set
# Sete bir diğer öğe ekleme
dolu_set.add(5) # dolu_set artık {1, 2, 3, 4, 5} oldu
# Setlerin çakışan kısımlarını almak için '&' kullanabilirsiniz
diger_set = {3, 4, 5, 6}
dolu_set & diger_set # => {3, 4, 5}
# '|' ile aynı olan elementleri almayacak şekilde setleri birleştirebilirsiniz
dolu_set | diger_set # => {1, 2, 3, 4, 5, 6}
# Farklılıkları almak için "-" kullanabilirsiniz
{1, 2, 3, 4} - {2, 3, 5} # => {1, 4}
# Bir değerin olup olmadığının kontrolü için "in" kullanılabilir
2 in dolu_set # => True
10 in dolu_set # => False
####################################################
## 3. Kontrol Akışları ve Temel Soyutlandırma
####################################################
# Bir değişken oluşturalım
bir_degisken = 5
# Burada bir "if" ifadesi var. Girinti(boşluk,tab) python için önemlidir!
# çıktı olarak "bir_degisken 10 dan küçük" yazar
if bir_degisken > 10:
print("bir_degisken 10 dan büyük")
elif bir_degisken < 10: # Bu 'elif' ifadesi zorunlu değildir.
print("bir_degisken 10 dan küçük")
else: # Bu ifade de zorunlu değil.
print("bir_degisken değeri 10")
"""
Döngülerle lsiteleri döngüye alabilirsiniz
çıktı:
köpek bir memeli hayvandır
kedi bir memeli hayvandır
fare bir memeli hayvandır
"""
for hayvan in ["köpek", "kedi, "fare"]:
# format ile kolayca yazıyı biçimlendirelim
print("{} bir memeli hayvandır".format(hayvan))
"""
"range(sayi)" bir sayı listesi döndür
0'dan belirttiğiniz sayıyıa kadar
çıktı:
0
1
2
3
"""
for i in range(4):
print(i)
"""
'While' döngüleri koşul çalıştıkça işlemleri gerçekleştirir.
çıktı:
0
1
2
3
"""
x = 0
while x < 4:
print(x)
x += 1 # Uzun hali x = x + 1
# Hataları kontrol altına almak için try/except bloklarını kullanabilirsiniz
try:
# Bir hata oluşturmak için "raise" kullanabilirsiniz
raise IndexError("Bu bir index hatası")
except IndexError as e:
pass # Önemsiz, devam et.
except (TypeError, NameError):
pass # Çoklu bir şekilde hataları kontrol edebilirsiniz, tabi gerekirse.
else: # İsteğe bağlı bir kısım. Eğer hiçbir hata kontrol mekanizması desteklemiyorsa bu blok çalışacaktır
print("Her şey iyi!") # IndexError, TypeError ve NameError harici bir hatada bu blok çalıştı
# Temel Soyutlandırma, bir objenin işlenmiş halidir.
# Aşağıdaki örnekte; Obje, range fonksiyonuna temel soyutlandırma gönderdi.
dolu_sozl = {"bir": 1, "iki": 2, "uc": 3}
temel_soyut = dolu_sozl.keys()
print(temel_soyut) #=> range(1,10). Bu obje temel soyutlandırma arayüzü ile oluşturuldu
# Temel Soyutlandırılmış objeyi döngüye sokabiliriz.
for i in temel_soyut:
print(i) # Çıktısı: bir, iki, uc
# Fakat, elementin anahtarına değerine.
temel_soyut[1] # TypeError hatası!
# 'iterable' bir objenin nasıl temel soyutlandırıldığıdır.
iterator = iter(temel_soyut)
# 'iterator' o obje üzerinde yaptığımız değişiklikleri hatırlayacaktır
# Bir sonraki objeyi almak için __next__ fonksiyonunu kullanabilirsiniz.
iterator.__next__() #=> "bir"
# Bir önceki __next__ fonksiyonumuzu hatırlayıp bir sonraki kullanımda bu sefer ondan bir sonraki objeyi döndürecektir
iterator.__next__() #=> "iki"
iterator.__next__() #=> "uc"
# Bütün nesneleri aldıktan sonra bir daha __next__ kullanımınızda, StopIterator hatası oluşturacaktır.
iterator.__next__() # StopIteration hatası
# iterator'deki tüm nesneleri almak için list() kullanabilirsiniz.
list(dolu_sozl.keys()) #=> Returns ["bir", "iki", "uc"]
####################################################
## 4. Fonksiyonlar
####################################################
# "def" ile yeni fonksiyonlar oluşturabilirsiniz
def topla(x, y):
print("x = {} ve y = {}".format(x, y))
return x + y # Değer döndürmek için 'return' kullanmalısınız
# Fonksiyonu parametleri ile çağırıyoruz
topla(5, 6) # => çıktı "x = 5 ve y = 6" ve değer olarak 11 döndürür
# Bir diğer fonksiyon çağırma yöntemi de anahtar değerleri ile belirtmek
topla(y=6, x=5) # Anahtar değeri belirttiğiniz için parametre sıralaması önemsiz.
# Sınırsız sayıda argüman da alabilirsiniz
def argumanlar(*argumanlar):
return argumanlar
argumanlar(1, 2, 3) # => (1, 2, 3)
# Parametrelerin anahtar değerlerini almak isterseniz
def anahtar_par(**anahtarlar):
return anahtar
# Çalıştırdığımızda
anahtar_par(anah1="deg1", anah2="deg2") # => {"anah1": "deg1", "anah2": "deg2"}
# İsterseniz, bu ikisini birden kullanabilirsiniz
def tum_argumanlar(*argumanlar, **anahtarla):
print(argumanlar)
print(anahtarla)
"""
tum_argumanlar(1, 2, a=3, b=4) çıktı:
(1, 2)
{"a": 3, "b": 4}
"""
# Fonksiyonu çağırırken de aynısını kullanabilirsiniz
argumanlar = (1, 2, 3, 4)
anahtarla = {"a": 3, "b": 4}
tum_argumanlar(*argumanlar) # = foo(1, 2, 3, 4)
tum_argumanlar(**anahtarla) # = foo(a=3, b=4)
tum_argumanlar(*argumanlar, **anahtarla) # = foo(1, 2, 3, 4, a=3, b=4)
# Fonksiyonlarda kullanacağımız bir değişken oluşturalım
x = 5
def belirleX(sayi):
# Fonksiyon içerisindeki x ile global tanımladığımız x aynı değil
x = sayi # => 43
print (x) # => 43
def globalBelirleX(sayi):
global x
print (x) # => 5
x = sayi # global olan x değişkeni artık 6
print (x) # => 6
belirleX(43)
globalBelirleX(6)
# Sınıf fonksiyonları oluşturma
def toplama_olustur(x):
def topla(y):
return x + y
return topla
ekle_10 = toplama_olustur(10)
ekle_10(3) # => 13
# Bilinmeyen fonksiyon
(lambda x: x > 2)(3) # => True
# TODO - Fix for iterables
# Belirli sayıdan yükseğini alma fonksiyonu
map(ekle_10, [1, 2, 3]) # => [11, 12, 13]
filter(lambda x: x > 5, [3, 4, 5, 6, 7]) # => [6, 7]
# Filtreleme işlemi için liste comprehensions da kullanabiliriz
[ekle_10(i) for i in [1, 2, 3]] # => [11, 12, 13]
[x for x in [3, 4, 5, 6, 7] if x > 5] # => [6, 7]
####################################################
## 5. Sınıflar
####################################################
# Sınıf oluşturmak için objeden alt sınıf oluşturacağız.
class Insan(obje):
# Sınıf değeri. Sınıfın tüm nesneleri tarafından kullanılabilir
tur = "H. sapiens"
# Basit başlatıcı, Sınıf çağrıldığında tetiklenecektir.
# Dikkat edin, iki adet alt çizgi(_) bulunmakta. Bunlar
# python tarafından tanımlanan isimlerdir.
# Kendinize ait bir fonksiyon oluştururken __fonksiyon__ kullanmayınız!
def __init__(self, isim):
# Parametreyi sınıfın değerine atayalım
self.isim = isim
# Bir metot. Bütün metotlar ilk parametre olarak "self "alır.
def soyle(self, mesaj):
return "{isim}: {mesaj}".format(isim=self.name, mesaj=mesaj)
# Bir sınıf metotu bütün nesnelere paylaştırılır
# İlk parametre olarak sınıf alırlar
@classmethod
def getir_tur(snf):
return snf.tur
# Bir statik metot, sınıf ve nesnesiz çağrılır
@staticmethod
def grunt():
return "*grunt*"
# Sınıfı çağıralım
i = Insan(isim="Ahmet")
print(i.soyle("merhaba")) # çıktı "Ahmet: merhaba"
j = Insan("Ali")
print(j.soyle("selam")) # çıktı "Ali: selam"
# Sınıf metodumuzu çağıraim
i.getir_tur() # => "H. sapiens"
# Paylaşılan değeri değiştirelim
Insan.tur = "H. neanderthalensis"
i.getir_tur() # => "H. neanderthalensis"
j.getir_tur() # => "H. neanderthalensis"
# Statik metodumuzu çağıralım
Insan.grunt() # => "*grunt*"
####################################################
## 6. Moduller
####################################################
# Modülleri içe aktarabilirsiniz
import math
print(math.sqrt(16)) # => 4
# Modülden belirli bir fonksiyonları alabilirsiniz
from math import ceil, floor
print(ceil(3.7)) # => 4.0
print(floor(3.7)) # => 3.0
# Modüldeki tüm fonksiyonları içe aktarabilirsiniz
# Dikkat: bunu yapmanızı önermem.
from math import *
# Modül isimlerini değiştirebilirsiniz.
# Not: Modül ismini kısaltmanız çok daha iyi olacaktır
import math as m
math.sqrt(16) == m.sqrt(16) # => True
# Python modulleri aslında birer python dosyalarıdır.
# İsterseniz siz de yazabilir ve içe aktarabilirsiniz Modulün
# ismi ile dosyanın ismi aynı olacaktır.
# Moduldeki fonksiyon ve değerleri öğrenebilirsiniz.
import math
dir(math)
####################################################
## 7. Gelişmiş
####################################################
# Oluşturucular uzun uzun kod yazmamanızı sağlayacak ve yardımcı olacaktır
def kare_sayilar(nesne):
for i in nesne:
yield i + i
# Bir oluşturucu(generator) değerleri anında oluşturur.
# Bir seferde tüm değerleri oluşturup göndermek yerine teker teker her oluşumdan
# sonra geri döndürür. Bu demektir ki, kare_sayilar fonksiyonumuzda 15'ten büyük
# değerler işlenmeyecektir.
# Not: range() da bir oluşturucu(generator)dur. 1-900000000 arası bir liste yapmaya çalıştığınızda
# çok fazla vakit alacaktır.
# Python tarafından belirlenen anahtar kelimelerden kaçınmak için basitçe alt çizgi(_) kullanılabilir.
range_ = range(1, 900000000)
# kare_sayilar'dan dönen değer 30'a ulaştığında durduralım
for i in kare_sayilar(range_):
print(i)
if i >= 30:
break
# Dekoratörler
# Bu örnekte,
# Eğer lutfen_soyle True ise dönen değer değişecektir.
from functools import wraps
def yalvar(hedef_fonksiyon):
@wraps(hedef_fonksiyon)
def metot(*args, **kwargs):
msj, lutfen_soyle = hedef_fonksiyon(*args, **kwargs)
if lutfen_soyle:
return "{} {}".format(msj, "Lütfen! Artık dayanamıyorum :(")
return msj
return metot
@yalvar
def soyle(lutfen_soyle=False):
msj = "Bana soda alır mısın?"
return msj, lutfen_soyle
print(soyle()) # Bana soda alır mısın?
print(soyle(lutfen_soyle=True)) # Ban soda alır mısın? Lutfen! Artık dayanamıyorum :(
```
## Daha Fazlasına Hazır Mısınız?
### Ücretsiz Online
* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/)
* [Dive Into Python](http://www.diveintopython.net/)
* [Ideas for Python Projects](http://pythonpracticeprojects.com)
* [The Official Docs](http://docs.python.org/3/)
* [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/)
* [A Crash Course in Python for Scientists](http://nbviewer.ipython.org/5920182)
* [Python Course](http://www.python-course.eu/index.php)
### Kitaplar
* [Programming Python](http://www.amazon.com/gp/product/0596158106/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596158106&linkCode=as2&tag=homebits04-20)
* [Dive Into Python](http://www.amazon.com/gp/product/1441413022/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1441413022&linkCode=as2&tag=homebits04-20)
* [Python Essential Reference](http://www.amazon.com/gp/product/0672329786/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0672329786&linkCode=as2&tag=homebits04-20)

View File

@ -9,105 +9,116 @@ TypeScript is a language that aims at easing development of large scale applicat
TypeScript adds common concepts such as classes, modules, interfaces, generics and (optional) static typing to JavaScript.
It is a superset of JavaScript: all JavaScript code is valid TypeScript code so it can be added seamlessly to any project. The TypeScript compiler emits JavaScript.
This article will focus only on TypeScript extra syntax, as oposed to [JavaScript] (../javascript/).
This article will focus only on TypeScript extra syntax, as opposed to [JavaScript] (../javascript/).
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
// Functions are first class citizens, support the lambda "fat arrow" syntax and
// use type inference
//Interfaces are structural, anything that has the properties is compliant with the interface
// 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" />
```

View File

@ -159,7 +159,7 @@ Module Module1
Console.Write(a.ToString() + " - " + b.ToString())
Console.WriteLine(" = " + e.ToString.PadLeft(3))
Console.Write(a.ToString() + " / " + b.ToString())
Console.WriteLine(" = " + e.ToString.PadLeft(3))
Console.WriteLine(" = " + f.ToString.PadLeft(3))
Console.ReadLine()
End Sub
@ -189,7 +189,7 @@ Module Module1
Console.Write(a.ToString() + " - " + b.ToString())
Console.WriteLine(" = " + e.ToString.PadLeft(3))
Console.Write(a.ToString() + " / " + b.ToString())
Console.WriteLine(" = " + e.ToString.PadLeft(3))
Console.WriteLine(" = " + f.ToString.PadLeft(3))
Console.ReadLine()
'Ask the question, does the user wish to continue? Unfortunately it
'is case sensitive.

View File

@ -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>
```
```

View File

@ -5,7 +5,14 @@ contributors:
- ["Max Yankov", "https://github.com/golergka"]
- ["Darren Lin", "https://github.com/CogBear"]
- ["Alexandre Medeiros", "http://alemedeiros.sdf.org"]
- ["Denis Arh", "https://github.com/darh"]
- ["akirahirose", "https://twitter.com/akirahirose"]
- ["Anton Strömkvist", "http://lutic.org/"]
- ["Rahil Momin", "https://github.com/iamrahil"]
- ["Gregrory Kielian", "https://github.com/gskielian"]
- ["Etan Reisner", "https://github.com/deryni"]
translators:
- ["Jinchang Ye", "https://github.com/Alwayswithme"]
- ["Chunyang Xu", "https://github.com/XuChunyang"]
filename: LearnBash-cn.sh
lang: zh-cn
@ -23,31 +30,45 @@ Bash 是一个为 GNU 计划编写的 Unix shell是 Linux 和 Mac OS X 下的
# 如你所见,注释以 # 开头shebang 也是注释。
# 显示 “Hello world!”
echo Hello, world!
echo Hello world!
# 每一句指令以换行或分号隔开:
echo 'This is the first line'; echo 'This is the second line'
# 声明一个变量:
VARIABLE="Some string"
Variable="Some string"
# 下面是错误的做法:
VARIABLE = "Some string"
# Bash 会把 VARIABLE 当做一个指令,由于找不到该指令,因此这里会报错。
Variable = "Some string"
# Bash 会把 Variable 当做一个指令,由于找不到该指令,因此这里会报错。
# 也不可以这样:
Variable= 'Some string'
# Bash 会认为 'Some string' 是一条指令,由于找不到该指令,这里再次报错。
# (这个例子中 'Variable=' 这部分会被当作仅对 'Some string' 起作用的赋值。)
# 使用变量:
echo $VARIABLE
echo "$VARIABLE"
echo '$VARIABLE'
echo $Variable
echo "$Variable"
echo '$Variable'
# 当你赋值 (assign) 、导出 (export),或者以其他方式使用变量时,变量名前不加 $。
# 如果要使用变量的值, 则要加 $。
# 注意: ' (单引号) 不会展开变量(即会屏蔽掉变量)。
# 在变量内部进行字符串代换
echo ${VARIABLE/Some/A}
# 会把 VARIABLE 中首次出现的 "some" 替换成 “A”。
echo ${Variable/Some/A}
# 会把 Variable 中首次出现的 "some" 替换成 “A”。
# 变量的截取
Length=7
echo ${Variable:0:Length}
# 这样会仅返回变量值的前7个字符
# 变量的默认值
echo ${Foo:-"DefaultValueIfFooIsMissingOrEmpty"}
# 对 null (Foo=) 和空串 (Foo="") 起作用; 零Foo=0时返回0
# 注意这仅返回默认值而不是改变变量的值
# 内置变量:
# 下面的内置变量很有用
@ -55,26 +76,37 @@ echo "Last program return value: $?"
echo "Script's PID: $$"
echo "Number of arguments: $#"
echo "Scripts arguments: $@"
echo "Scripts arguments separeted in different variables: $1 $2..."
echo "Scripts arguments separated in different variables: $1 $2..."
# 读取输入:
echo "What's your name?"
read NAME # 这里不需要声明新变量
echo Hello, $NAME!
read Name # 这里不需要声明新变量
echo Hello, $Name!
# 通常的 if 结构看起来像这样:
# 'man test' 可查看更多的信息
if [ $NAME -ne $USER ]
if [ $Name -ne $USER ]
then
echo "Your name is you username"
echo "Your name isn't your username"
else
echo "Your name isn't you username"
echo "Your name is your username"
fi
# 根据上一个指令执行结果决定是否执行下一个指令
echo "Always executed" || echo "Only executed if first command fail"
echo "Always executed" || echo "Only executed if first command fails"
echo "Always executed" && echo "Only executed if first command does NOT fail"
# 在 if 语句中使用 && 和 || 需要多对方括号
if [ $Name == "Steve" ] && [ $Age -eq 15 ]
then
echo "This will run if $Name is Steve AND $Age is 15."
fi
if [ $Name == "Daniya" ] || [ $Name == "Zach" ]
then
echo "This will run if $Name is Daniya OR Zach."
fi
# 表达式的格式如下:
echo $(( 10 + 5 ))
@ -88,18 +120,54 @@ ls -l # 列出文件和目录的详细信息
# 用下面的指令列出当前目录下所有的 txt 文件:
ls -l | grep "\.txt"
# 重定向输入和输出(标准输入,标准输出,标准错误)。
# 以 ^EOF$ 作为结束标记从标准输入读取数据并覆盖 hello.py :
cat > hello.py << EOF
#!/usr/bin/env python
from __future__ import print_function
import sys
print("#stdout", file=sys.stdout)
print("#stderr", file=sys.stderr)
for line in sys.stdin:
print(line, file=sys.stdout)
EOF
# 重定向可以到输出,输入和错误输出。
python2 hello.py < "input.in"
python2 hello.py > "output.out"
python2 hello.py 2> "error.err"
python hello.py < "input.in"
python hello.py > "output.out"
python hello.py 2> "error.err"
python hello.py > "output-and-error.log" 2>&1
python hello.py > /dev/null 2>&1
# > 会覆盖已存在的文件, >> 会以累加的方式输出文件中。
python hello.py >> "output.out" 2>> "error.err"
# 覆盖 output.out , 追加 error.err 并统计行数
info bash 'Basic Shell Features' 'Redirections' > output.out 2>> error.err
wc -l output.out error.err
# 运行指令并打印文件描述符 (比如 /dev/fd/123
# 具体可查看: man fd
echo <(echo "#helloworld")
# 以 "#helloworld" 覆盖 output.out:
cat > output.out <(echo "#helloworld")
echo "#helloworld" > output.out
echo "#helloworld" | cat > output.out
echo "#helloworld" | tee output.out >/dev/null
# 清理临时文件并显示详情(增加 '-i' 选项启用交互模式)
rm -v output.out error.err output-and-error.log
# 一个指令可用 $( ) 嵌套在另一个指令内部:
# 以下的指令会打印当前目录下的目录和文件总数
echo "There are $(ls | wc -l) items here."
# 反引号 `` 起相同作用,但不允许嵌套
# 优先使用 $( ).
echo "There are `ls | wc -l` items here."
# Bash 的 case 语句与 Java 和 C++ 中的 switch 语句类似:
case "$VARIABLE" in
case "$Variable" in
# 列出需要匹配的字符串
0) echo "There is a zero.";;
1) echo "There is a one.";;
@ -107,11 +175,37 @@ case "$VARIABLE" in
esac
# 循环遍历给定的参数序列:
# 变量$VARIABLE 的值会被打印 3 次。
# 注意 ` ` 和 $( ) 等价。seq 返回长度为 3 的数组。
for VARIABLE in `seq 3`
# 变量$Variable 的值会被打印 3 次。
for Variable in {1..3}
do
echo "$VARIABLE"
echo "$Variable"
done
# 或传统的 “for循环”
for ((a=1; a <= 3; a++))
do
echo $a
done
# 也可以用于文件
# 用 cat 输出 file1 和 file2 内容
for Variable in file1 file2
do
cat "$Variable"
done
# 或作用于其他命令的输出
# 对 ls 输出的文件执行 cat 指令。
for Output in $(ls)
do
cat "$Output"
done
# while 循环:
while [ true ]
do
echo "loop body here..."
break
done
# 你也可以使用函数
@ -132,17 +226,52 @@ bar ()
}
# 调用函数
foo "My name is" $NAME
foo "My name is" $Name
# 有很多有用的指令需要学习:
tail -n 10 file.txt
# 打印 file.txt 的最后 10 行
head -n 10 file.txt
tail -n 10 file.txt
# 打印 file.txt 的前 10 行
sort file.txt
head -n 10 file.txt
# 将 file.txt 按行排序
uniq -d file.txt
sort file.txt
# 报告或忽略重复的行,用选项 -d 打印重复的行
cut -d ',' -f 1 file.txt
uniq -d file.txt
# 打印每行中 ',' 之前内容
cut -d ',' -f 1 file.txt
# 将 file.txt 文件所有 'okay' 替换为 'great', (兼容正则表达式)
sed -i 's/okay/great/g' file.txt
# 将 file.txt 中匹配正则的行打印到标准输出
# 这里打印以 "foo" 开头, "bar" 结尾的行
grep "^foo.*bar$" file.txt
# 使用选项 "-c" 统计行数
grep -c "^foo.*bar$" file.txt
# 如果只是要按字面形式搜索字符串而不是按正则表达式,使用 fgrep (或 grep -F)
fgrep "^foo.*bar$" file.txt
# 以 bash 内建的 'help' 指令阅读 Bash 自带文档:
help
help help
help for
help return
help source
help .
# 用 mam 指令阅读相关的 Bash 手册
apropos bash
man 1 bash
man bash
# 用 info 指令查阅命令的 info 文档 info 中按 ? 显示帮助信息)
apropos info | grep '^info.*('
man info
info info
info 5 info
# 阅读 Bash 的 info 文档:
info bash
info bash 'Bash Features'
info bash 6
info --apropos bash
```

572
zh-cn/c++-cn.html.markdown Normal file
View File

@ -0,0 +1,572 @@
---
language: c++
filename: learncpp-cn.cpp
contributors:
- ["Steven Basart", "http://github.com/xksteven"]
- ["Matt Kline", "https://github.com/mrkline"]
translators:
- ["Arnie97", "https://github.com/Arnie97"]
lang: zh-cn
---
C++是一种系统编程语言。用它的发明者,
[Bjarne Stroustrup的话](http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2014/Keynote)来说C++的设计目标是:
- 成为“更好的C语言”
- 支持数据的抽象与封装
- 支持面向对象编程
- 支持泛型编程
C++提供了对硬件的紧密控制正如C语言一样
能够编译为机器语言,由处理器直接执行。
与此同时,它也提供了泛型、异常和类等高层功能。
虽然C++的语法可能比某些出现较晚的语言更复杂,它仍然得到了人们的青睞——
功能与速度的平衡使C++成为了目前应用最广泛的系统编程语言之一。
```c++
////////////////
// 与C语言的比较
////////////////
// C++_几乎_是C语言的一个超集它与C语言的基本语法有许多相同之处
// 例如变量和函数的声明,原生数据类型等等。
// 和C语言一样在C++中你的程序会从main()开始执行,
// 该函数的返回值应当为int型这个返回值会作为程序的退出状态值。
// 不过大多数的编译器gccclang等也接受 void main() 的函数原型。
// (参见 http://en.wikipedia.org/wiki/Exit_status 来获取更多信息)
int main(int argc, char** argv)
{
// 和C语言一样命令行参数通过argc和argv传递。
// argc代表命令行参数的数量
// 而argv是一个包含“C语言风格字符串”char *)的数组,
// 其中每个字符串代表一个命令行参数的内容,
// 首个命令行参数是调用该程序时所使用的名称。
// 如果你不关心命令行参数的值argc和argv可以被忽略。
// 此时你可以用int main()作为函数原型。
// 退出状态值为0时表示程序执行成功
return 0;
}
// 然而C++和C语言也有一些区别
// 在C++中,字符字面量的大小是一个字节。
sizeof('c') == 1
// 在C语言中字符字面量的大小与int相同。
sizeof('c') == sizeof(10)
// C++的函数原型与函数定义是严格匹配的
void func(); // 这个函数不能接受任何参数
// 而在C语言中
void func(); // 这个函数能接受任意数量的参数
// 在C++中用nullptr代替C语言中的NULL
int* ip = nullptr;
// C++也可以使用C语言的标准头文件
// 但是需要加上前缀“c”并去掉末尾的“.h”。
#include <cstdio>
int main()
{
printf("Hello, world!\n");
return 0;
}
///////////
// 函数重载
///////////
// C++支持函数重载,你可以定义一组名称相同而参数不同的函数。
void print(char const* myString)
{
printf("String %s\n", myString);
}
void print(int myInt)
{
printf("My int is %d", myInt);
}
int main()
{
print("Hello"); // 解析为 void print(const char*)
print(15); // 解析为 void print(int)
}
///////////////////
// 函数参数的默认值
///////////////////
// 你可以为函数的参数指定默认值,
// 它们将会在调用者没有提供相应参数时被使用。
void doSomethingWithInts(int a = 1, int b = 4)
{
// 对两个参数进行一些操作
}
int main()
{
doSomethingWithInts(); // a = 1, b = 4
doSomethingWithInts(20); // a = 20, b = 4
doSomethingWithInts(20, 5); // a = 20, b = 5
}
// 默认参数必须放在所有的常规参数之后。
void invalidDeclaration(int a = 1, int b) // 这是错误的!
{
}
///////////
// 命名空间
///////////
// 命名空间为变量、函数和其他声明提供了分离的的作用域。
// 命名空间可以嵌套使用。
namespace First {
namespace Nested {
void foo()
{
printf("This is First::Nested::foo\n");
}
} // 结束嵌套的命名空间Nested
} // 结束命名空间First
namespace Second {
void foo()
{
printf("This is Second::foo\n")
}
}
void foo()
{
printf("This is global foo\n");
}
int main()
{
// 如果没有特别指定就从“Second”中取得所需的内容。
using namespace Second;
foo(); // 显示“This is Second::foo”
First::Nested::foo(); // 显示“This is First::Nested::foo”
::foo(); // 显示“This is global foo”
}
////////////
// 输入/输出
////////////
// C++使用“流”来输入输出。<<是流的插入运算符>>是流提取运算符。
// cin、cout、和cerr分别代表
// stdin标准输入、stdout标准输出和stderr标准错误
#include <iostream> // 引入包含输入/输出流的头文件
using namespace std; // 输入输出流在std命名空间也就是标准库中。
int main()
{
int myInt;
// 在标准输出(终端/显示器)中显示
cout << "Enter your favorite number:\n";
// 从标准输入(键盘)获得一个值
cin >> myInt;
// cout也提供了格式化功能
cout << "Your favorite number is " << myInt << "\n";
// 显示“Your favorite number is <myInt>
cerr << "Used for error messages";
}
/////////
// 字符串
/////////
// C++中的字符串是对象,它们有很多成员函数
#include <string>
using namespace std; // 字符串也在std命名空间标准库中。
string myString = "Hello";
string myOtherString = " World";
// + 可以用于连接字符串。
cout << myString + myOtherString; // "Hello World"
cout << myString + " You"; // "Hello You"
// C++中的字符串是可变的,具有“值语义”。
myString.append(" Dog");
cout << myString; // "Hello Dog"
/////////////
// 引用
/////////////
// 除了支持C语言中的指针类型以外C++还提供了_引用_。
// 引用是一种特殊的指针类型,一旦被定义就不能重新赋值,并且不能被设置为空值。
// 使用引用时的语法与原变量相同:
// 也就是说,对引用类型进行解引用时,不需要使用*
// 赋值时也不需要用&来取地址。
using namespace std;
string foo = "I am foo";
string bar = "I am bar";
string& fooRef = foo; // 建立了一个对foo的引用。
fooRef += ". Hi!"; // 通过引用来修改foo的值
cout << fooRef; // "I am foo. Hi!"
// 这句话的并不会改变fooRef的指向其效果与“foo = bar”相同。
// 也就是说在执行这条语句之后foo == "I am bar"。
fooRef = bar;
const string& barRef = bar; // 建立指向bar的常量引用。
// 和C语言中一样指针和引用声明为常量时对应的值不能被修改。
barRef += ". Hi!"; // 这是错误的,不能修改一个常量引用的值。
///////////////////
// 类与面向对象编程
///////////////////
// 有关类的第一个示例
#include <iostream>
// 声明一个类。
// 类通常在头文件(.h或.hpp中声明。
class Dog {
// 成员变量和成员函数默认情况下是私有private的。
std::string name;
int weight;
// 在这个标签之后所有声明都是公有public
// 直到重新指定“private:”私有继承或“protected:”(保护继承)为止
public:
// 默认的构造器
Dog();
// 这里是成员函数声明的一个例子。
// 可以注意到我们在此处使用了std::string而不是using namespace std
// 语句using namespace绝不应当出现在头文件当中。
void setName(const std::string& dogsName);
void setWeight(int dogsWeight);
// 如果一个函数不对对象的状态进行修改,
// 应当在声明中加上const。
// 这样,你就可以对一个以常量方式引用的对象执行该操作。
// 同时可以注意到,当父类的成员函数需要被子类重写时,
// 父类中的函数必须被显式声明为_虚函数virtual_。
// 考虑到性能方面的因素,函数默认情况下不会被声明为虚函数。
virtual void print() const;
// 函数也可以在class body内部定义。
// 这样定义的函数会自动成为内联函数。
void bark() const { std::cout << name << " barks!\n" }
// 除了构造器以外C++还提供了析构器。
// 当一个对象被删除或者脱离其定义域时,它的析构函数会被调用。
// 这使得RAII这样的强大范式参见下文成为可能。
// 为了衍生出子类来,基类的析构函数必须定义为虚函数。
virtual ~Dog();
}; // 在类的定义之后,要加一个分号
// 类的成员函数通常在.cpp文件中实现。
void Dog::Dog()
{
std::cout << "A dog has been constructed\n";
}
// 对象(例如字符串)应当以引用的形式传递,
// 对于不需要修改的对象,最好使用常量引用。
void Dog::setName(const std::string& dogsName)
{
name = dogsName;
}
void Dog::setWeight(int dogsWeight)
{
weight = dogsWeight;
}
// 虚函数的virtual关键字只需要在声明时使用不需要在定义时重复
void Dog::print() const
{
std::cout << "Dog is " << name << " and weighs " << weight << "kg\n";
}
void Dog::~Dog()
{
cout << "Goodbye " << name << "\n";
}
int main() {
Dog myDog; // 此时显示“A dog has been constructed”
myDog.setName("Barkley");
myDog.setWeight(10);
myDog.printDog(); // 显示“Dog is Barkley and weighs 10 kg”
return 0;
} // 显示“Goodbye Barkley”
// 继承:
// 这个类继承了Dog类中的公有public和保护protected对象
class OwnedDog : public Dog {
void setOwner(const std::string& dogsOwner)
// 重写OwnedDogs类的print方法。
// 如果你不熟悉子类多态的话,可以参考这个页面中的概述:
// http://zh.wikipedia.org/wiki/%E5%AD%90%E7%B1%BB%E5%9E%8B
// override关键字是可选的它确保你所重写的是基类中的方法。
void print() const override;
private:
std::string owner;
};
// 与此同时,在对应的.cpp文件里
void OwnedDog::setOwner(const std::string& dogsOwner)
{
owner = dogsOwner;
}
void OwnedDog::print() const
{
Dog::print(); // 调用基类Dog中的print方法
// "Dog is <name> and weights <weight>"
std::cout << "Dog is owned by " << owner << "\n";
// "Dog is owned by <owner>"
}
/////////////////////
// 初始化与运算符重载
/////////////////////
// 在C++中,通过定义一些特殊名称的函数,
// 你可以重载+、-、*、/等运算符的行为。
// 当运算符被使用时,这些特殊函数会被调用,从而实现运算符重载。
#include <iostream>
using namespace std;
class Point {
public:
// 可以以这样的方式为成员变量设置默认值。
double x = 0;
double y = 0;
// 定义一个默认的构造器。
// 除了将Point初始化为(0, 0)以外,这个函数什么都不做。
Point() { };
// 下面使用的语法称为初始化列表,
// 这是初始化类中成员变量的正确方式。
Point (double a, double b) :
x(a),
y(b)
{ /* 除了初始化成员变量外,什么都不做 */ }
// 重载 + 运算符
Point operator+(const Point& rhs) const;
// 重载 += 运算符
Point& operator+=(const Point& rhs);
// 增加 - 和 -= 运算符也是有意义的,但这里不再赘述。
};
Point Point::operator+(const Point& rhs) const
{
// 创建一个新的点,
// 其横纵坐标分别为这个点与另一点在对应方向上的坐标之和。
return Point(x + rhs.x, y + rhs.y);
}
Point& Point::operator+=(const Point& rhs)
{
x += rhs.x;
y += rhs.y;
return *this;
}
int main () {
Point up (0,1);
Point right (1,0);
// 这里使用了Point类型的运算符“+”
// 调用upPoint类型的“+”方法并以right作为函数的参数
Point result = up + right;
// 显示“Result is upright (1,1)”
cout << "Result is upright (" << result.x << ',' << result.y << ")\n";
return 0;
}
///////////
// 异常处理
///////////
// 标准库中提供了一些基本的异常类型
// 参见http://en.cppreference.com/w/cpp/error/exception
// 但是,其他任何类型也可以作为一个异常被拋出
#include <exception>
// 在_try_代码块中拋出的异常可以被随后的_catch_捕获。
try {
// 不要用 _new_关键字在堆上为异常分配空间。
throw std::exception("A problem occurred");
}
// 如果拋出的异常是一个对象,可以用常量引用来捕获它
catch (const std::exception& ex)
{
std::cout << ex.what();
// 捕获尚未被_catch_处理的所有错误
} catch (...)
{
std::cout << "Unknown exception caught";
throw; // 重新拋出异常
}
///////
// RAII
///////
// RAII指的是“资源获取就是初始化”Resource Allocation Is Initialization
// 它被视作C++中最强大的编程范式之一。
// 简单说来,它指的是,用构造函数来获取一个对象的资源,
// 相应的,借助析构函数来释放对象的资源。
// 为了理解这一范式的用处,让我们考虑某个函数使用文件句柄时的情况:
void doSomethingWithAFile(const char* filename)
{
// 首先,让我们假设一切都会顺利进行。
FILE* fh = fopen(filename, "r"); // 以只读模式打开文件
doSomethingWithTheFile(fh);
doSomethingElseWithIt(fh);
fclose(fh); // 关闭文件句柄
}
// 不幸的是,随着错误处理机制的引入,事情会变得复杂。
// 假设fopen函数有可能执行失败
// 而doSomethingWithTheFile和doSomethingElseWithIt会在失败时返回错误代码。
// 虽然异常是C++中处理错误的推荐方式,
// 但是某些程序员尤其是有C语言背景的并不认可异常捕获机制的作用
// 现在,我们必须检查每个函数调用是否成功执行,并在问题发生的时候关闭文件句柄。
bool doSomethingWithAFile(const char* filename)
{
FILE* fh = fopen(filename, "r"); // 以只读模式打开文件
if (fh == nullptr) // 当执行失败是返回的指针是nullptr
return false; // 向调用者汇报错误
// 假设每个函数会在执行失败时返回false
if (!doSomethingWithTheFile(fh)) {
fclose(fh); // 关闭文件句柄,避免造成内存泄漏。
return false; // 反馈错误
}
if (!doSomethingElseWithIt(fh)) {
fclose(fh); // 关闭文件句柄
return false; // 反馈错误
}
fclose(fh); // 关闭文件句柄
return true; // 指示函数已成功执行
}
// C语言的程序员通常会借助goto语句简化上面的代码
bool doSomethingWithAFile(const char* filename)
{
FILE* fh = fopen(filename, "r");
if (fh == nullptr)
return false;
if (!doSomethingWithTheFile(fh))
goto failure;
if (!doSomethingElseWithIt(fh))
goto failure;
fclose(fh); // 关闭文件
return true; // 执行成功
failure:
fclose(fh);
return false; // 反馈错误
}
// 如果用异常捕获机制来指示错误的话,
// 代码会变得清晰一些,但是仍然有优化的余地。
void doSomethingWithAFile(const char* filename)
{
FILE* fh = fopen(filename, "r"); // 以只读模式打开文件
if (fh == nullptr)
throw std::exception("Could not open the file.");
try {
doSomethingWithTheFile(fh);
doSomethingElseWithIt(fh);
}
catch (...) {
fclose(fh); // 保证出错的时候文件被正确关闭
throw; // 之后,重新抛出这个异常
}
fclose(fh); // 关闭文件
// 所有工作顺利完成
}
// 相比之下使用C++中的文件流类fstream
// fstream会利用自己的析构器来关闭文件句柄。
// 只要离开了某一对象的定义域,它的析构函数就会被自动调用。
void doSomethingWithAFile(const std::string& filename)
{
// ifstream是输入文件流input file stream的简称
std::ifstream fh(filename); // 打开一个文件
// 对文件进行一些操作
doSomethingWithTheFile(fh);
doSomethingElseWithIt(fh);
} // 文件已经被析构器自动关闭
// 与上面几种方式相比这种方式有着_明显_的优势
// 1. 无论发生了什么情况,资源(此例当中是文件句柄)都会被正确关闭。
// 只要你正确使用了析构器就_不会_因为忘记关闭句柄造成资源的泄漏。
// 2. 可以注意到,通过这种方式写出来的代码十分简洁。
// 析构器会在后台关闭文件句柄,不再需要你来操心这些琐事。
// 3. 这种方式的代码具有异常安全性。
// 无论在函数中的何处拋出异常,都不会阻碍对文件资源的释放。
// 地道的C++代码应当把RAII的使用扩展到各种类型的资源上包括
// - 用unique_ptr和shared_ptr管理的内存
// - 各种数据容器,例如标准库中的链表、向量(容量自动扩展的数组)、散列表等;
// 当它们脱离作用域时,析构器会自动释放其中储存的内容。
// - 用lock_guard和unique_lock实现的互斥
```
扩展阅读:
<http://cppreference.com/w/cpp> 提供了最新的语法参考。
可以在 <http://cplusplus.com> 找到一些补充资料。

View File

@ -5,24 +5,25 @@ contributors:
- ["Adit Bhargava", "http://adit.io"]
translators:
- ["Peiyong Lin", ""]
- ["chad luo", "http://yuki.rocks"]
lang: zh-cn
---
Haskell 被设计成一种实用的纯函数式编程语言。它因为 monads 及其类型系统而出名但是我回归到它本身因为。Haskell 使得编程对于我而言是一种真正的快乐。
Haskell 是一门实用的函数式编程语言,因其 Monads 与类型系统而闻名。而我使用它则是因为它异常优雅。用 Haskell 编程令我感到非常快乐。
```haskell
-- 单行注释以两个破折号开头
-- 单行注释以两个号开头
{- 多行注释像这样
被一个闭合的块包围
被一个闭合的块包围
-}
----------------------------------------------------
-- 1. 简单的数据类型和操作符
----------------------------------------------------
-- 你有数字
-- 数字
3 -- 3
-- 数学计算就像你所期待的那样
-- 数学计算
1 + 1 -- 2
8 - 1 -- 7
10 * 2 -- 20
@ -34,7 +35,7 @@ Haskell 被设计成一种实用的纯函数式编程语言。它因为 monads
-- 整除
35 `div` 4 -- 8
-- 布尔值也简单
-- 布尔值
True
False
@ -45,21 +46,22 @@ not False -- True
1 /= 1 -- False
1 < 10 -- True
-- 在上述的例子中,`not` 是一个接受一个值的函数。
-- Haskell 不需要括号来调用函数。。。所有的参数
-- 都只是在函数名之后列出来。因此,通常的函数调用模式是:
-- func arg1 arg2 arg3...
-- 查看关于函数的章节以获得如何写你自己的函数的相关信息
-- 在上面的例子中,`not` 是一个接受一个参数的函数。
-- Haskell 不需要括号来调用函数,所有的参数都只是在函数名之后列出来
-- 因此,通常的函数调用模式是:
-- func arg1 arg2 arg3...
-- 你可以查看函数部分了解如何自行编写
-- 字符串和字符
"This is a string."
"This is a string." -- 字符串
'a' -- 字符
'对于字符串你不能使用单引号。' -- 错误!
-- 连字符串
-- 连字符串
"Hello " ++ "world!" -- "Hello world!"
-- 一个字符串是一系列字符
['H', 'e', 'l', 'l', 'o'] -- "Hello"
"This is a string" !! 0 -- 'T'
@ -67,162 +69,164 @@ not False -- True
-- 列表和元组
----------------------------------------------------
-- 一个列表中的每一个元素都必须是相同的类型
-- 下面两个列表一样
-- 一个列表中的每一个元素都必须是相同的类型
-- 下面两个列表等价
[1, 2, 3, 4, 5]
[1..5]
-- 在 Haskell 你可以拥有含有无限元素的列表
-- 区间也可以这样
['A'..'F'] -- "ABCDEF"
-- 你可以在区间中指定步进
[0,2..10] -- [0, 2, 4, 6, 8, 10]
[5..1] -- 这样不行,因为 Haskell 默认递增
[5,4..1] -- [5, 4, 3, 2, 1]
-- 列表下标
[0..] !! 5 -- 5
-- 在 Haskell 你可以使用无限列表
[1..] -- 一个含有所有自然数的列表
-- 因为 Haskell 有“懒惰计算”,所以无限元素的列表可以正常运作。这意味着
-- Haskell 可以只在它需要的时候计算。所以你可以请求
-- 列表中的第1000个元素Haskell 会返回给你
-- 无限列表的原理是Haskell 有“惰性求值”。
-- 这意味着 Haskell 只在需要时才会计算。
-- 所以当你获取列表的第 1000 项元素时Haskell 会返回给你:
[1..] !! 999 -- 1000
-- Haskell 计算了列表中第 1 至 1000 项元素,但这个无限列表中剩下的元素还不存在。
-- Haskell 只有在需要时才会计算它们。
-- Haskell 计算了列表中 1 - 1000 个元素。。。但是
-- 这个无限元素的列表中剩下的元素还不存在! Haskell 不会
-- 真正地计算它们知道它需要。
<FS>- 连接两个列表
-- 连接两个列表
[1..5] ++ [6..10]
-- 往列表头增加元素
0:[1..5] -- [0, 1, 2, 3, 4, 5]
-- 列表中的下标
[0..] !! 5 -- 5
-- 更多列表操作
-- 其它列表操作
head [1..5] -- 1
tail [1..5] -- [2, 3, 4, 5]
init [1..5] -- [1, 2, 3, 4]
last [1..5] -- 5
-- 列表推导
-- 列表推导 (list comprehension)
[x*2 | x <- [1..5]] -- [2, 4, 6, 8, 10]
-- 附带条件
[x*2 | x <-[1..5], x*2 > 4] -- [6, 8, 10]
-- 元组中的每一个元素可以是不同类型的,但是一个元组
-- 的长度是固定的
-- 元组中的每一个元素可以是不同类型,但是一个元组的长度是固定的
-- 一个元组
("haskell", 1)
-- 获取元组中的元素
-- 获取元组中的元素(例如,一个含有 2 个元素的元祖)
fst ("haskell", 1) -- "haskell"
snd ("haskell", 1) -- 1
----------------------------------------------------
-- 3. 函数
----------------------------------------------------
-- 一个接受两个变量的简单函数
add a b = a + b
-- 注意,如果你使用 ghci (Hakell 解释器)
-- 你将需要使用 `let`,也就是
-- 注意,如果你使用 ghci (Hakell 解释器),你需要使用 `let`,也就是
-- let add a b = a + b
-- 使用函数
-- 用函数
add 1 2 -- 3
-- 你也可以把函数放置在两个参数之间
-- 附带倒引号:
-- 你也可以使用反引号中置函数名:
1 `add` 2 -- 3
-- 你也可以定义不带字符的函数!这使得
-- 你定义自己的操作符!这里有一个操作符
-- 来做整除
-- 你也可以定义不带字母的函数名,这样你可以定义自己的操作符。
-- 这里有一个做整除的操作符
(//) a b = a `div` b
35 // 4 -- 8
-- 守卫:一个简单的方法在函数里做分支
-- Guard一个在函数中做条件判断的简单方法
fib x
| x < 2 = x
| otherwise = fib (x - 1) + fib (x - 2)
-- 模式匹配是类型的。这里有三种不同的 fib
-- 定义。Haskell 将自动调用第一个
-- 匹配值的模式的函数。
-- 模式匹配与 Guard 类似。
-- 这里给出了三个不同的 fib 定义。
-- Haskell 会自动调用第一个符合参数模式的声明
fib 1 = 1
fib 2 = 2
fib x = fib (x - 1) + fib (x - 2)
-- 元组的模式匹配
-- 元组的模式匹配
foo (x, y) = (x + 1, y + 2)
-- 列表的模式匹配。这里 `x` 是列表中第一个元素,
-- 并且 `xs` 是列表剩余的部分。我们可以写
-- 自己的 map 函数:
-- 列表的模式匹配
-- 这里 `x` 是列表中第一个元素,`xs` 是列表剩余的部分。
-- 我们可以实现自己的 map 函数:
myMap func [] = []
myMap func (x:xs) = func x:(myMap func xs)
-- 编写出来的匿名函数带有一个反斜杠,后面跟着
-- 所有的参数。
-- 匿名函数带有一个反斜杠,后面跟着所有的参数
myMap (\x -> x + 2) [1..5] -- [3, 4, 5, 6, 7]
-- 使用 fold (在一些语言称为`inject`)随着一个匿名的
-- 函数。foldl1 意味着左折叠(fold left), 并且使用列表中第一个值
-- 作为累加器的初始化值。
-- 在 fold在一些语言称 为`inject`)中使用匿名函数
-- foldl1 意味着左折叠 (fold left), 并且使用列表中第一个值作为累加器的初始值。
foldl1 (\acc x -> acc + x) [1..5] -- 15
----------------------------------------------------
-- 4. 更多的函数
-- 4. 其它函数
----------------------------------------------------
-- 柯里化(currying):如果你不传递函数中所有的参数,
-- 它就变成“柯里化的”。这意味着,它返回一个接受剩余参数的函数
-- 部分调用
-- 如果你调用函数时没有给出所有参数,它就被“部分调用”
-- 它将返回一个接受余下参数的函数。
add a b = a + b
foo = add 10 -- foo 现在是一个接受一个数并对其加 10 的函数
foo 5 -- 15
-- 另外一种方式去做同样的事
-- 另一种等价写法
foo = (+10)
foo 5 -- 15
-- 函数组
-- (.) 函数把其它函数链接到一起
-- 举个列子,这里 foo 是一个接受一个值的函数。它对接受的值加 10
-- 并对结果乘以 5之后返回最后的值。
-- 函列表
-- (.) 函数把其它函数链接到一起
-- 例如,这里 foo 是一个接受一个值的函数。
-- 它对接受的值加 10并对结果乘以 5之后返回最后的值。
foo = (*5) . (+10)
-- (5 + 10) * 5 = 75
foo 5 -- 75
-- 修复优先级
-- Haskell 有另外一个函数称为 `$`。它改变优先级
-- 使得其左侧的每一个操作先计算然后应用到
-- 右侧的每一个操作。你可以使用 `.``$` 来除去很多
-- 括号:
-- 修正优先级
-- Haskell 有另外一个函数 `$` 可以改变优先级。
-- `$` 使得 Haskell 先计算其右边的部分,然后调用左边的部分。
-- 你可以使用 `$` 来移除多余的括号。
-- before
-- 修改前
(even (fib 7)) -- true
-- after
-- 修改后
even . fib $ 7 -- true
-- 等价地
even $ fib 7 -- true
----------------------------------------------------
-- 5. 类型签名
-- 5. 类型声明
----------------------------------------------------
-- Haskell 有一个非常强壮的类型系统,一切都有一个类型签名
-- Haskell 有一个非常强大的类型系统,一切都有一个类型声明
-- 一些基本的类型:
5 :: Integer
"hello" :: String
True :: Bool
-- 函数也有类型
-- `not` 接受一个布尔型返回一个布尔型
-- 函数也有类型
-- `not` 接受一个布尔型返回一个布尔型
-- not :: Bool -> Bool
-- 这是接受两个参数的函数
-- 这是接受两个参数的函数
-- add :: Integer -> Integer -> Integer
-- 当你定义一个值,在其上写明它的类型是一个好实践:
-- 当你定义一个值,声明其类型是一个好做法
double :: Integer -> Integer
double x = x * 2
@ -230,159 +234,148 @@ double x = x * 2
-- 6. 控制流和 If 语句
----------------------------------------------------
-- if 语句
-- if 语句
haskell = if 1 == 1 then "awesome" else "awful" -- haskell = "awesome"
-- if 语句也可以有多行,缩进是很重要的
-- if 语句也可以有多行,注意缩进:
haskell = if 1 == 1
then "awesome"
else "awful"
-- case 语句:这里是你可以怎样去解析命令行参数
-- case 语句
-- 解析命令行参数:
case args of
"help" -> printHelp
"start" -> startProgram
_ -> putStrLn "bad args"
-- Haskell 没有循环因为它使用递归取代之。
-- map 应用一个函数到一个数组中的每一个元素
-- Haskell 没有循环,它使用递归
-- map 对一个列表中的每一个元素调用一个函数
map (*2) [1..5] -- [2, 4, 6, 8, 10]
-- 你可以使用 map 来编写 for 函数
for array func = map func array
-- 然后使用它
-- 调用
for [0..5] $ \i -> show i
-- 我们也可以像这样写
-- 我们也可以像这样写
for [0..5] show
-- 你可以使用 foldl 或者 foldr 来分解列表
-- foldl <fn> <initial value> <list>
foldl (\x y -> 2*x + y) 4 [1,2,3] -- 43
-- 这和下面是一样的
-- 等价于
(2 * (2 * (2 * 4 + 1) + 2) + 3)
-- foldl 是左手边的foldr 是右手边的-
-- foldl 从左开始foldr 从右
foldr (\x y -> 2*x + y) 4 [1,2,3] -- 16
-- 这和下面是一样的
-- 现在它等价于
(2 * 3 + (2 * 2 + (2 * 1 + 4)))
----------------------------------------------------
-- 7. 数据类型
----------------------------------------------------
-- 这里展示在 Haskell 中你怎样编写自己的数据类型
-- 在 Haskell 中声明你自己的数据类型:
data Color = Red | Blue | Green
-- 现在你可以在函数中使用它:
say :: Color -> String
say Red = "You are Red!"
say Blue = "You are Blue!"
say Green = "You are Green!"
-- 你的数据类型也可以有参数:
data Maybe a = Nothing | Just a
-- 类型 Maybe 的所有
Just "hello" -- of type `Maybe String`
Just 1 -- of type `Maybe Int`
Nothing -- of type `Maybe a` for any `a`
-- 这些都是 Maybe 类型:
Just "hello" -- `Maybe String` 类型
Just 1 -- `Maybe Int` 类型
Nothing -- 对任意 `a``Maybe a` 类型
----------------------------------------------------
-- 8. Haskell IO
----------------------------------------------------
-- 虽然在没有解释 monads 的情况下 IO不能被完全地解释
-- 着手解释到位并不难。
-- 当一个 Haskell 程序被执行,函数 `main` 就被调用。
-- 它必须返回一个类型 `IO ()` 的值。举个列子:
-- 虽然不解释 Monads 就无法完全解释 IO但大致了解并不难。
-- 当执行一个 Haskell 程序时,函数 `main` 就被调用。
-- 它必须返回一个类型 `IO ()` 的值。例如:
main :: IO ()
main = putStrLn $ "Hello, sky! " ++ (say Blue)
-- putStrLn has type String -> IO ()
-- putStrLn 的类型是 String -> IO ()
-- 如果你能实现你的程序依照函数从 String 到 String那样编写 IO 是最简单的。
-- 如果你的程序输入 String 返回 String那样编写 IO 是最简单的。
-- 函数
-- interact :: (String -> String) -> IO ()
-- 输入一些文本,在其上运行一个函数,并打印出输出
-- 输入一些文本,对其调用一个函数,并打印输出。
countLines :: String -> String
countLines = show . length . lines
main' = interact countLines
-- 你可以考虑一个 `IO()` 类型的值,当做一系列计算机所完成的动作的代表,
-- 就像一个以命令式语言编写的计算机程序。我们可以使用 `do` 符号来把动作链接到一起。
-- 举个列子:
-- 你可以认为一个 `IO ()` 类型的值是表示计算机做的一系列操作,类似命令式语言。
-- 我们可以使用 `do` 声明来把动作连接到一起。
-- 举个列子
sayHello :: IO ()
sayHello = do
putStrLn "What is your name?"
name <- getLine -- this gets a line and gives it the name "input"
name <- getLine -- 这里接受一行输入并绑定至 "name"
putStrLn $ "Hello, " ++ name
-- 练习:编写只读取一行输入的 `interact`
-- 然而,`sayHello` 中的代码将不会被执行。唯一被执行的动作是 `main` 的值。
-- 为了运行 `sayHello`,注释上面 `main` 的定义,并代替它
-- 为了运行 `sayHello`,注释上面 `main` 的定义,替换为
-- main = sayHello
-- 让我们来更好地理解刚才所使用的函数 `getLine` 是怎样工作的。它的类型是:
-- 让我们来更进一步理解刚才所使用的函数 `getLine` 是怎样工作的。它的类型是:
-- getLine :: IO String
-- 你可以考虑一个 `IO a` 类型的值,代表一个当被执行的时候
-- 将产生一个 `a` 类型的值的计算机程序(除了它所做的任何事之外)。我们可以保存和重用这个值通过 `<-`
-- 我们也可以写自己的 `IO String` 类型的动作:
-- 你可以认为一个 `IO a` 类型的值代表了一个运行时会生成一个 `a` 类型值的程序。
-- (可能伴随其它行为)
-- 我们可以通过 `<-` 保存和重用这个值。
-- 我们也可以实现自己的 `IO String` 类型函数:
action :: IO String
action = do
putStrLn "This is a line. Duh"
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
-- `do` 语句的类型是它的最后一行
-- `return` 不是关键字,只是一个普通函数
return (input1 ++ "\n" ++ input2) -- return :: String -> IO String
-- 我们可以使用这个动作就像我们使用 `getLine`:
-- 我们可以像调用 `getLine` 一样调用它
main'' = do
putStrLn "I will echo two lines!"
result <- action
putStrLn result
putStrLn "This was all, folks!"
-- `IO` 类型是一个 "monad" 的例子。Haskell 使用一个 monad 来做 IO的方式允许它是一门纯函数式语言
-- 任何与外界交互的函数(也就是 IO) 都在它的类型签名处做一个 `IO` 标志
-- 着让我们推出 什么样的函数是“纯洁的”(不与外界交互,不修改状态) 和 什么样的函数不是 “纯洁的”
-- 这是一个强有力的特征因为并发地运行纯函数是简单的因此Haskell 中并发是非常简单的
-- `IO` 类型是一个 "Monad" 的例子
-- Haskell 通过使用 Monad 使得其本身为纯函数式语言。
-- 任何与外界交互的函数(即 IO都在它的类型声明中标记为 `IO`
-- 这告诉我们什么样的函数是“纯洁的”(不与外界交互,不修改状态)
-- 什么样的函数不是 “纯洁的”
-- 这个功能非常强大,因为纯函数并发非常容易,由此在 Haskell 中做并发非常容易。
----------------------------------------------------
-- 9. The Haskell REPL
-- 9. Haskell REPL
----------------------------------------------------
-- 键入 `ghci` 开始 repl
-- 键入 `ghci` 开始 REPL
-- 现在你可以键入 Haskell 代码。
-- 任何新值都需要通过 `let` 来创建:
-- 任何新值都需要通过 `let` 来创建
let foo = 5
-- 你可以查看任何值的类型,通过命令 `:t`
-- 你可以通过命令 `:t` 查看任何值的类型
>:t foo
foo :: Integer
-- 你也可以运行任何 `IO ()`类型的动作
> sayHello
What is your name?
Friend!
@ -390,7 +383,7 @@ Hello, Friend!
```
还有很多关于 Haskell包括类型类和 monads。这些是使得编码 Haskell 是如此有趣的主意。我用一个最后的 Haskell 例子来结束:一个 Haskell 的快排实现:
Haskell 还有许多内容,包括类型类 (typeclasses) 与 Monads。这些都是令 Haskell 编程非常有趣的好东西。我们最后给出 Haskell 的一个例子,一个快速排序的实现:
```haskell
qsort [] = []
@ -399,9 +392,9 @@ qsort (p:xs) = qsort lesser ++ [p] ++ qsort greater
greater = filter (>= p) xs
```
安装 Haskell 是简单的。你可以从[这里](http://www.haskell.org/platform/)获得它
安装 Haskell 很简单。你可以[从这里获得](http://www.haskell.org/platform/)
你可以从优秀的
[Learn you a Haskell](http://learnyouahaskell.com/) 或者
[Real World Haskell](http://book.realworldhaskell.org/)
找到优雅不少的入门介绍。
找到更平缓的入门介绍。

View File

@ -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
{

View File

@ -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
// javascript中的对象相当于其他语言中的字典或映射是键-值的集合
{key1: "Hello", key2: "World"}
// 数组是可变的,并拥有变量 length。
myArray.push("World");
myArray.length; // = 4
// 键是字符串但是引号也并非是必须的如果键本身是合法的js标识符
// 而值则可以是任意类型的值
var myObj = {myKey: "myValue", "my other key": 4}
// 在指定下标添加/修改
myArray[3] = "Hello";
// 对象的访问可以通过下标
myObj["my other key"] // = 4
// javascript中的对象相当于其他语言中的“字典”或“映射”是键-值对的无序集合。
var myObj = {key1: "Hello", key2: "World"};
// 键是字符串但如果键本身是合法的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"
myFunction("foo"); // = "FOO"
// 函数也可以是匿名的:
function(thing){
return thing.toLowerCase()
}
// (我们无法调用此函数,因为我们不知道这个函数的名字)
// javascript中的函数也是对象所以函数也能够赋给一个变量并且被传递
// 比如一个事件处理函数:
function myFunction(){
// this code will be called in 5 seconds' time
}
setTimeout(myFunction, 5000)
// 你甚至可以直接把一个函数写到另一个函数的参数中
setTimeout(function myFunction(){
// 5秒之后会执行这里的代码
}, 5000)
// JavaScript 仅有函数作用于,而其他的语句则没有作用域
if (true){
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最强大的功能之一就是闭包
// 如果一个函数在另一个函数中定义,那么这个函数就拥有外部函数的所有访问权
function sayHelloInFiveSeconds(name){
var prompt = "Hello, " + name + "!"
function inner(){
alert(prompt)
// 注意被返回的值必须开始于`return`关键字的那一行,
// 否则由于自动的分号补齐,你将返回`undefined`。
// 在使用Allman风格的时候要注意.
function myFunction()
{
return // <- 分号自动插在这里
{
thisIsAn: 'object literal'
}
setTimeout(inner, 5000)
// setTimeout 是异步的,所以这个函数会马上终止不会等待。
// 然而在5秒结束后inner函数仍然会弹出prompt信息。
}
sayHelloInFiveSeconds("Adam") // 会在5秒后弹出 "Hello, Adam!"
myFunction(); // = undefined
// javascript中函数是一等对象所以函数也能够赋给一个变量
// 并且被作为参数传递 —— 比如一个事件处理函数:
function myFunction(){
// 这段代码将在5秒钟后被调用
}
setTimeout(myFunction, 5000);
// 注意setTimeout不是js语言的一部分而是由浏览器和Node.js提供的。
// 函数对象甚至不需要声明名称 —— 你可以直接把一个函数定义写到另一个函数的参数中
setTimeout(function(){
// 这段代码将在5秒钟后被调用
}, 5000);
// JavaScript 有函数作用域;函数有其自己的作用域而其他的代码块则没有。
if (true){
var i = 5;
}
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`声明的。
function inner(){
alert(prompt);
}
setTimeout(inner, 5000);
// setTimeout是异步的所以 sayHelloInFiveSeconds 函数会立即退出,
// 而 setTimeout 会在后面调用inner
// 然而由于inner是由sayHelloInFiveSeconds“闭合包含”的
// 所以inner在其最终被调用时仍然能够访问`prompt`变量。
}
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!"
myObj.myOtherFunc = myOtherFunc;
myObj.myOtherFunc(); // = "HELLO WORLD!"
// 当你通过new关键字调用一个函数时就会生成一个对象
// 而对象的成员需要通过this来定义。
// 这样的函数就叫做构造函数
// 当我们通过`call`或者`apply`调用函数的时候,也可以为其指定一个执行上下文。
var anotherFunc = function(s){
return this.myString + s;
}
anotherFunc.call(myObj, " And Hello Moon!"); // = "Hello World! And Hello Moon!"
// `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
};
myObj.myBoolean; // = true
// 这其中并没有对象的拷贝。每个对象的原型实际上是持有原型对象的引用
// 这说明当我们改变对象的原型时,会影响到其他以这个原型为原型的对象
myPrototype.meaningOfLife = 43
myObj.meaningOfLife // = 43
// 这其中并没有对象的拷贝;每个对象实际上是持有原型对象的引用。
// 这意味着当我们改变对象的原型时,会影响到其他以这个原型为原型的对象
myPrototype.meaningOfLife = 43;
myObj.meaningOfLife; // = 43
// 我们知道 __proto__ 并非标准规定,实际上也没有办法更改已经指定好的原型。
// 但是,我们有两种方式可以为新的对象指定原型
// 我们知道 `__proto__` 并非标准规定,实际上也没有标准办法来修改一个已存在对象的原型。
// 然而,我们有两种方式为指定原型创建一个新的对象
// 第一种方式是 Object.create这个方法是在最近才被添加到Js中的
// 也因此并不是所有的JS实现都有这个放啊
var myObj = Object.create(myPrototype)
myObj.meaningOfLife // = 43
// 第一种方式是 Object.create这个方法是在最近才被添加到Js中的
// 因此并不是所有的JS实现都有这个方法
var myObj = Object.create(myPrototype);
myObj.meaningOfLife; // = 43
// 第二种方式可以在任意版本中使用,不过需要通过构造函数。
// 构造函数有一个属性prototype。但是这 *不是* 构造函数本身的函数
// 而是通过构造函数和new关键字生成新对象时自动生成的。
myConstructor.prototype = {
// 第二种方式可以在任意版本中使用,不过必须通过构造函数。
// 构造函数有一个属性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)

View File

@ -63,8 +63,8 @@ foo = anUnknownVariable -- 现在 foo = nil.
aBoolValue = false
--只有nil和false为假; 0和 ''均为真!
if not aBoolValue then print('twas false') end
--只有nil和false为假; 0和 ''均为真!
if not aBoolValue then print('false') end
-- 'or'和 'and'短路
-- 类似于C/js里的 a?b:c 操作符:
@ -149,7 +149,7 @@ print {} -- 一样可以工作。
-- Table = Lua唯一的组合数据结构;
-- 它们是关联数组。
-- 类似于PHP的数组或者js的对象
-- 它们是哈希表或者字典,也可以当列表使用。
-- 它们是哈希表或者字典,也可以当列表使用。
-- 按字典/map的方式使用Table

View File

@ -127,7 +127,7 @@ __此文本也是__
<!-- 代码段落 -->
<!-- 代码段落HTML中 <code>标签可以由缩进四格spaces
或者一个标签页tab实现-->
或者一个制表符tab实现-->
This is code
So is this

View File

@ -0,0 +1,491 @@
---
language: Matlab
contributors:
- ["mendozao", "http://github.com/mendozao"]
- ["jamesscottbrown", "http://jamesscottbrown.com"]
translators:
- ["sunxb10", "https://github.com/sunxb10"]
lang: zh-cn
---
MATLAB 是 MATrix LABoratory (矩阵实验室)的缩写,它是一种功能强大的数值计算语言,在工程和数学领域中应用广泛。
如果您有任何需要反馈或交流的内容,请联系本教程作者[@the_ozzinator](https://twitter.com/the_ozzinator)、[osvaldo.t.mendoza@gmail.com](mailto:osvaldo.t.mendoza@gmail.com)。
```matlab
% 以百分号作为注释符
%{
多行注释
可以
这样
表示
%}
% 指令可以随意跨行,但需要在跨行处用 '...' 标明:
a = 1 + 2 + ...
+ 4
% 可以在MATLAB中直接向操作系统发出指令
!ping google.com
who % 显示内存中的所有变量
whos % 显示内存中的所有变量以及它们的类型
clear % 清除内存中的所有变量
clear('A') % 清除指定的变量
openvar('A') % 在变量编辑器中编辑指定变量
clc % 清除命令窗口中显示的所有指令
diary % 将命令窗口中的内容写入本地文件
ctrl-c % 终止当前计算
edit('myfunction.m') % 在编辑器中打开指定函数或脚本
type('myfunction.m') % 在命令窗口中打印指定函数或脚本的源码
profile on % 打开 profile 代码分析工具
profile of % 关闭 profile 代码分析工具
profile viewer % 查看 profile 代码分析工具的分析结果
help command % 在命令窗口中显示指定命令的帮助文档
doc command % 在帮助窗口中显示指定命令的帮助文档
lookfor command % 在所有 MATLAB 内置函数的头部注释块的第一行中搜索指定命令
lookfor command -all % 在所有 MATLAB 内置函数的整个头部注释块中搜索指定命令
% 输出格式
format short % 浮点数保留 4 位小数
format long % 浮点数保留 15 位小数
format bank % 金融格式,浮点数只保留 2 位小数
fprintf('text') % 在命令窗口中显示 "text"
disp('text') % 在命令窗口中显示 "text"
% 变量与表达式
myVariable = 4 % 命令窗口中将新创建的变量
myVariable = 4; % 加上分号可使命令窗口中不显示当前语句执行结果
4 + 6 % ans = 10
8 * myVariable % ans = 32
2 ^ 3 % ans = 8
a = 2; b = 3;
c = exp(a)*sin(pi/2) % c = 7.3891
% 调用函数有两种方式:
% 标准函数语法:
load('myFile.mat', 'y') % 参数放在括号内,以英文逗号分隔
% 指令语法:
load myFile.mat y % 不加括号,以空格分隔参数
% 注意在指令语法中参数不需要加引号:在这种语法下,所有输入参数都只能是文本文字,
% 不能是变量的具体值,同样也不能是输出变量
[V,D] = eig(A); % 这条函数调用无法转换成等价的指令语法
[~,D] = eig(A); % 如果结果中只需要 D 而不需要 V 则可以这样写
% 逻辑运算
1 > 5 % 假ans = 0
10 >= 10 % 真ans = 1
3 ~= 4 % 不等于 -> ans = 1
3 == 3 % 等于 -> ans = 1
3 > 1 && 4 > 1 % 与 -> ans = 1
3 > 1 || 4 > 1 % 或 -> ans = 1
~1 % 非 -> ans = 0
% 逻辑运算可直接应用于矩阵,运算结果也是矩阵
A > 5
% 对矩阵中每个元素做逻辑运算,若为真,则在运算结果的矩阵中对应位置的元素就是 1
A( A > 5 )
% 如此返回的向量,其元素就是 A 矩阵中所有逻辑运算为真的元素
% 字符串
a = 'MyString'
length(a) % ans = 8
a(2) % ans = y
[a,a] % ans = MyStringMyString
b = '字符串' % MATLAB目前已经可以支持包括中文在内的多种文字
length(b) % ans = 3
b(2) % ans = 符
[b,b] % ans = 字符串字符串
% 元组cell 数组)
a = {'one', 'two', 'three'}
a(1) % ans = 'one' - 返回一个元组
char(a(1)) % ans = one - 返回一个字符串
% 结构体
A.b = {'one','two'};
A.c = [1 2];
A.d.e = false;
% 向量
x = [4 32 53 7 1]
x(2) % ans = 32MATLAB中向量的下标索引从1开始不是0
x(2:3) % ans = 32 53
x(2:end) % ans = 32 53 7 1
x = [4; 32; 53; 7; 1] % 列向量
x = [1:10] % x = 1 2 3 4 5 6 7 8 9 10
% 矩阵
A = [1 2 3; 4 5 6; 7 8 9]
% 以分号分隔不同的行,以空格或逗号分隔同一行中的不同元素
% A =
% 1 2 3
% 4 5 6
% 7 8 9
A(2,3) % ans = 6A(row, column)
A(6) % ans = 8
% (隐式地将 A 的三列首尾相接组成一个列向量,然后取其下标为 6 的元素)
A(2,3) = 42 % 将第 2 行第 3 列的元素设为 42
% A =
% 1 2 3
% 4 5 42
% 7 8 9
A(2:3,2:3) % 取原矩阵中的一块作为新矩阵
%ans =
% 5 42
% 8 9
A(:,1) % 第 1 列的所有元素
%ans =
% 1
% 4
% 7
A(1,:) % 第 1 行的所有元素
%ans =
% 1 2 3
[A ; A] % 将两个矩阵上下相接构成新矩阵
%ans =
% 1 2 3
% 4 5 42
% 7 8 9
% 1 2 3
% 4 5 42
% 7 8 9
% 等价于
vertcat(A, A);
[A , A] % 将两个矩阵左右相接构成新矩阵
%ans =
% 1 2 3 1 2 3
% 4 5 42 4 5 42
% 7 8 9 7 8 9
% 等价于
horzcat(A, A);
A(:, [3 1 2]) % 重新排布原矩阵的各列
%ans =
% 3 1 2
% 42 4 5
% 9 7 8
size(A) % 返回矩阵的行数和列数ans = 3 3
A(1, :) =[] % 删除矩阵的第 1 行
A(:, 1) =[] % 删除矩阵的第 1 列
transpose(A) % 矩阵转置,等价于 A'
ctranspose(A) % 矩阵的共轭转置(对矩阵中的每个元素取共轭复数)
% 元素运算 vs. 矩阵运算
% 单独运算符就是对矩阵整体进行矩阵运算
% 在运算符加上英文句点就是对矩阵中的元素进行元素计算
% 示例如下:
A * B % 矩阵乘法,要求 A 的列数等于 B 的行数
A .* B % 元素乘法,要求 A 和 B 形状一致A 的行数等于 B 的行数, A 的列数等于 B 的列数)
% 元素乘法的结果是与 A 和 B 形状一致的矩阵,其每个元素等于 A 对应位置的元素乘 B 对应位置的元素
% 以下函数中,函数名以 m 结尾的执行矩阵运算,其余执行元素运算:
exp(A) % 对矩阵中每个元素做指数运算
expm(A) % 对矩阵整体做指数运算
sqrt(A) % 对矩阵中每个元素做开方运算
sqrtm(A) % 对矩阵整体做开放运算(即试图求出一个矩阵,该矩阵与自身的乘积等于 A 矩阵)
% 绘图
x = 0:.10:2*pi; % 生成一向量,其元素从 0 开始,以 0.1 的间隔一直递增到 2*pipi 就是圆周率)
y = sin(x);
plot(x,y)
xlabel('x axis')
ylabel('y axis')
title('Plot of y = sin(x)')
axis([0 2*pi -1 1]) % x 轴范围是从 0 到 2*piy 轴范围是从 -1 到 1
plot(x,y1,'-',x,y2,'--',x,y3,':') % 在同一张图中绘制多条曲线
legend('Line 1 label', 'Line 2 label') % 为图片加注图例
% 图例数量应当小于或等于实际绘制的曲线数目,从 plot 绘制的第一条曲线开始对应
% 在同一张图上绘制多条曲线的另一种方法:
% 使用 hold on令系统保留前次绘图结果并在其上直接叠加新的曲线
% 如果没有 hold on则每个 plot 都会首先清除之前的绘图结果再进行绘制。
% 在 hold on 和 hold off 中可以放置任意多的 plot 指令,
% 它们和 hold on 前最后一个 plot 指令的结果都将显示在同一张图中。
plot(x, y1)
hold on
plot(x, y2)
plot(x, y3)
plot(x, y4)
hold off
loglog(x, y) % 对数—对数绘图
semilogx(x, y) % 半对数x 轴对数)绘图
semilogy(x, y) % 半对数y 轴对数)绘图
fplot (@(x) x^2, [2,5]) % 绘制函数 x^2 在 [2, 5] 区间的曲线
grid on % 在绘制的图中显示网格,使用 grid off 可取消网格显示
axis square % 将当前坐标系设定为正方形(保证在图形显示上各轴等长)
axis equal % 将当前坐标系设定为相等(保证在实际数值上各轴等长)
scatter(x, y); % 散点图
hist(x); % 直方图
z = sin(x);
plot3(x,y,z); % 绘制三维曲线
pcolor(A) % 伪彩色图(热图)
contour(A) % 等高线图
mesh(A) % 网格曲面图
h = figure % 创建新的图片对象并返回其句柄 h
figure(h) % 将句柄 h 对应的图片作为当前图片
close(h) % 关闭句柄 h 对应的图片
close all % 关闭 MATLAB 中所用打开的图片
close % 关闭当前图片
shg % 显示图形窗口
clf clear % 清除图形窗口中的图像,并重置图像属性
% 图像属性可以通过图像句柄进行设定
% 在创建图像时可以保存图像句柄以便于设置
% 也可以用 gcf 函数返回当前图像的句柄
h = plot(x, y); % 在创建图像时显式地保存图像句柄
set(h, 'Color', 'r')
% 颜色代码:'y' 黄色,'m' 洋红色,'c' 青色,'r' 红色,'g' 绿色,'b' 蓝色,'w' 白色,'k' 黑色
set(h, 'Color', [0.5, 0.5, 0.4])
% 也可以使用 RGB 值指定颜色
set(h, 'LineStyle', '--')
% 线型代码:'--' 实线,'---' 虚线,':' 点线,'-.' 点划线,'none' 不划线
get(h, 'LineStyle')
% 获取当前句柄的线型
% 用 gca 函数返回当前图像的坐标轴句柄
set(gca, 'XDir', 'reverse'); % 令 x 轴反向
% 用 subplot 指令创建平铺排列的多张子图
subplot(2,3,1); % 选择 2 x 3 排列的子图中的第 1 张图
plot(x1); title('First Plot') % 在选中的图中绘图
subplot(2,3,2); % 选择 2 x 3 排列的子图中的第 2 张图
plot(x2); title('Second Plot') % 在选中的图中绘图
% 要调用函数或脚本,必须保证它们在你的当前工作目录中
path % 显示当前工作目录
addpath /path/to/dir % 将指定路径加入到当前工作目录中
rmpath /path/to/dir % 将指定路径从当前工作目录中删除
cd /path/to/move/into % 以制定路径作为当前工作目录
% 变量可保存到 .mat 格式的本地文件
save('myFileName.mat') % 保存当前工作空间中的所有变量
load('myFileName.mat') % 将指定文件中的变量载入到当前工作空间
% .m 脚本文件
% 脚本文件是一个包含多条 MATLAB 指令的外部文件,以 .m 为后缀名
% 使用脚本文件可以避免在命令窗口中重复输入冗长的指令
% .m 函数文件
% 与脚本文件类似,同样以 .m 作为后缀名
% 但函数文件可以接受用户输入的参数并返回运算结果
% 并且函数拥有自己的工作空间(变量域),不必担心变量名称冲突
% 函数文件的名称应当与其所定义的函数的名称一致(比如下面例子中函数文件就应命名为 double_input.m
% 使用 'help double_input.m' 可返回函数定义中第一行注释信息
function output = double_input(x)
% double_input(x) 返回 x 的 2 倍
output = 2*x;
end
double_input(6) % ans = 12
% 同样还可以定义子函数和内嵌函数
% 子函数与主函数放在同一个函数文件中,且只能被这个主函数调用
% 内嵌函数放在另一个函数体内,可以直接访问被嵌套函数的各个变量
% 使用匿名函数可以不必创建 .m 函数文件
% 匿名函数适用于快速定义某函数以便传递给另一指令或函数(如绘图、积分、求根、求极值等)
% 下面示例的匿名函数返回输入参数的平方根,可以使用句柄 sqr 进行调用:
sqr = @(x) x.^2;
sqr(10) % ans = 100
doc function_handle % find out more
% 接受用户输入
a = input('Enter the value: ')
% 从文件中读取数据
fopen(filename)
% 类似函数还有 xlsreadexcel 文件、importdataCSV 文件、imread图像文件
% 输出
disp(a) % 在命令窗口中打印变量 a 的值
disp('Hello World') % 在命令窗口中打印字符串
fprintf % 按照指定格式在命令窗口中打印内容
% 条件语句if 和 elseif 语句中的括号并非必需,但推荐加括号避免混淆)
if (a > 15)
disp('Greater than 15')
elseif (a == 23)
disp('a is 23')
else
disp('neither condition met')
end
% 循环语句
% 注意:对向量或矩阵使用循环语句进行元素遍历的效率很低!!
% 注意:只要有可能,就尽量使用向量或矩阵的整体运算取代逐元素循环遍历!!
% MATLAB 在开发时对向量和矩阵运算做了专门优化,做向量和矩阵整体运算的效率高于循环语句
for k = 1:5
disp(k)
end
k = 0;
while (k < 5)
k = k + 1;
end
% 程序运行计时:'tic' 是计时开始,'toc' 是计时结束并打印结果
tic
A = rand(1000);
A*A*A*A*A*A*A;
toc
% 链接 MySQL 数据库
dbname = 'database_name';
username = 'root';
password = 'root';
driver = 'com.mysql.jdbc.Driver';
dburl = ['jdbc:mysql://localhost:8889/' dbname];
javaclasspath('mysql-connector-java-5.1.xx-bin.jar'); % 此处 xx 代表具体版本号
% 这里的 mysql-connector-java-5.1.xx-bin.jar 可从 http://dev.mysql.com/downloads/connector/j/ 下载
conn = database(dbname, username, password, driver, dburl);
sql = ['SELECT * from table_name where id = 22'] % SQL 语句
a = fetch(conn, sql) % a 即包含所需数据
% 常用数学函数
sin(x)
cos(x)
tan(x)
asin(x)
acos(x)
atan(x)
exp(x)
sqrt(x)
log(x)
log10(x)
abs(x)
min(x)
max(x)
ceil(x)
floor(x)
round(x)
rem(x)
rand % 均匀分布的伪随机浮点数
randi % 均匀分布的伪随机整数
randn % 正态分布的伪随机浮点数
% 常用常数
pi
NaN
inf
% 求解矩阵方程(如果方程无解,则返回最小二乘近似解)
% \ 操作符等价于 mldivide 函数,/ 操作符等价于 mrdivide 函数
x=A\b % 求解 Ax=b比先求逆再左乘 inv(A)*b 更加高效、准确
x=b/A % 求解 xA=b
inv(A) % 逆矩阵
pinv(A) % 伪逆矩阵
% 常用矩阵函数
zeros(m, n) % m x n 阶矩阵,元素全为 0
ones(m, n) % m x n 阶矩阵,元素全为 1
diag(A) % 返回矩阵 A 的对角线元素
diag(x) % 构造一个对角阵,对角线元素就是向量 x 的各元素
eye(m, n) % m x n 阶单位矩阵
linspace(x1, x2, n) % 返回介于 x1 和 x2 之间的 n 个等距节点
inv(A) % 矩阵 A 的逆矩阵
det(A) % 矩阵 A 的行列式
eig(A) % 矩阵 A 的特征值和特征向量
trace(A) % 矩阵 A 的迹(即对角线元素之和),等价于 sum(diag(A))
isempty(A) % 测试 A 是否为空
all(A) % 测试 A 中所有元素是否都非 0 或都为真(逻辑值)
any(A) % 测试 A 中是否有元素非 0 或为真(逻辑值)
isequal(A, B) % 测试 A 和 B是否相等
numel(A) % 矩阵 A 的元素个数
triu(x) % 返回 x 的上三角这部分
tril(x) % 返回 x 的下三角这部分
cross(A, B) % 返回 A 和 B 的叉积(矢量积、外积)
dot(A, B) % 返回 A 和 B 的点积(数量积、内积),要求 A 和 B 必须等长
transpose(A) % A 的转置,等价于 A'
fliplr(A) % 将一个矩阵左右翻转
flipud(A) % 将一个矩阵上下翻转
% 矩阵分解
[L, U, P] = lu(A) % LU 分解PA = LUL 是下三角阵U 是上三角阵P 是置换阵
[P, D] = eig(A) % 特征值分解AP = PDD 是由特征值构成的对角阵P 的各列就是对应的特征向量
[U, S, V] = svd(X) % 奇异值分解XV = USU 和 V 是酉矩阵S 是由奇异值构成的半正定实数对角阵
% 常用向量函数
max % 最大值
min % 最小值
length % 元素个数
sort % 按升序排列
sum % 各元素之和
prod % 各元素之积
mode % 众数
median % 中位数
mean % 平均值
std % 标准差
perms(x) % x 元素的全排列
```
## 相关资料
* 官方网页:[http://http://www.mathworks.com/products/matlab/](http://www.mathworks.com/products/matlab/)
* 官方论坛:[http://www.mathworks.com/matlabcentral/answers/](http://www.mathworks.com/matlabcentral/answers/)

View File

@ -4,12 +4,15 @@ filename: learnscala-zh.scala
contributors:
- ["George Petrov", "http://github.com/petrovg"]
- ["Dominic Bou-Samra", "http://dbousamra.github.com"]
- ["Geoff Liu", "http://geoffliu.me"]
translators:
- ["Peiyong Lin", ""]
- ["Jinchang Ye", "http://github.com/alwayswithme"]
- ["Guodong Qu", "https://github.com/jasonqu"]
lang: zh-cn
---
Scala - 一门可拓展的语言
Scala - 一门可拓展的语言
```scala
@ -17,23 +20,31 @@ Scala - 一门可拓展性的语言
自行设置:
1) 下载 Scala - http://www.scala-lang.org/downloads
2) unzip/untar 到你喜欢的地方,放在路径中的 bin 目录下
3) 在终端输入 scala开启 Scala 的 REPL会看到提示符:
2) unzip/untar 到您喜欢的地方,并把 bin 子目录添加到 path 环境变量
3) 在终端输入 scala启动 Scala 的 REPL会看到提示符:
scala>
这就是所谓的 REPL你现在可以在其中运行命令让我们做到这一点
这就是所谓的 REPL (读取-求值-输出循环,英语: Read-Eval-Print Loop)
您可以在其中输入合法的表达式,结果会被打印。
在教程中我们会进一步解释 Scala 文件是怎样的,但现在先了解一点基础。
*/
println(10) // 打印整数 10
println("Boo!") // 打印字符串 "BOO!"
/////////////////////////////////////////////////
// 1. 基础
/////////////////////////////////////////////////
// 单行注释开始于两个斜杠
// 一些基础
/*
多行注释,如您之前所见,看起来像这样
*/
// 打印并强制换行
println("Hello world!")
println(10)
// 没有强制换行的打印
print("Hello world")
@ -41,13 +52,19 @@ print("Hello world")
// val 声明是不可变的var 声明是可修改的。不可变性是好事。
val x = 10 // x 现在是 10
x = 20 // 错误: 对 val 声明的变量重新赋值
var x = 10
x = 20 // x 现在是 20
var y = 10
y = 20 // y 现在是 20
// 单行注释开始于两个斜杠
/*
多行注释看起来像这样。
/*
Scala 是静态语言,但注意上面的声明方式,我们没有指定类型。
这是因为类型推导的语言特性。大多数情况, Scala 编译器可以推测变量的类型,
所以您不需要每次都输入。可以像这样明确声明变量类型:
*/
val z: Int = 10
val a: Double = 1.0
// 注意从 Int 到 Double 的自动转型,结果是 10.0, 不是 10
val b: Double = 10
// 布尔值
true
@ -64,9 +81,11 @@ true == false // false
2 - 1 // 1
5 * 3 // 15
6 / 2 // 3
6 / 4 // 1
6.0 / 4 // 1.5
// 在 REPL 计算一个命令会返回给你结果的类型和值
// 在 REPL 计算一个表达式会返回给您结果的类型和值
1 + 7
@ -77,149 +96,134 @@ true == false // false
这意味着计算 1 + 7 的结果是一个 Int 类型的对象,其值为 8
1+7 的结果是一样的
注意 "res29" 是一个连续生成的变量名,用以存储您输入的表达式结果,
您看到的输出可能不一样。
*/
"Scala strings are surrounded by double quotes"
'a' // Scala 的字符
// '不存在单引号字符串' <= 这会导致错误
// 包括函数在内,每一个事物都是对象。在 REPL 中输入:
// String 有常见的 Java 字符串方法
"hello world".length
"hello world".substring(2, 6)
"hello world".replace("C", "3")
7 // 结果 res30: Int = 7 (res30 是一个生成的结果的 var 命名)
// 也有一些额外的 Scala 方法另请参见scala.collection.immutable.StringOps
"hello world".take(5)
"hello world".drop(5)
// 下一行给你一个接收一个 Int 类型并返回该数的平方的函数
(x:Int) => x * x
// 字符串改写:留意前缀 "s"
val n = 45
s"We have $n apples" // => "We have 45 apples"
// 你可以分配给函数一个标识符,像这样:
val sq = (x:Int) => x * x
// 在要改写的字符串中使用表达式也是可以的
val a = Array(11, 9, 6)
s"My second daughter is ${a(0) - a(2)} years old." // => "My second daughter is 5 years old."
s"We have double the amount of ${n / 2.0} in apples." // => "We have double the amount of 22.5 in apples."
s"Power of 2: ${math.pow(2, 2)}" // => "Power of 2: 4"
/* 上面的例子说明
sq: Int => Int = <function1>
// 添加 "f" 前缀对要改写的字符串进行格式化
f"Power of 5: ${math.pow(5, 2)}%1.0f" // "Power of 5: 25"
f"Square root of 122: ${math.sqrt(122)}%1.4f" // "Square root of 122: 11.0454"
意味着这次我们给予了 sq 这样一个显式的名字给一个接受一个 Int 类型值并返回 一个 Int 类型值的函数
// 未处理的字符串,忽略特殊字符。
raw"New line feed: \n. Carriage return: \r." // => "New line feed: \n. Carriage return: \r."
sq 可以像下面那样被执行:
*/
// 一些字符需要转义,比如字符串中的双引号
"They stood outside the \"Rose and Crown\"" // => "They stood outside the "Rose and Crown""
sq(10) // 返回给你res33: Int = 100.
// Scala 允许方法和函数返回或者接受其它的函数或者方法作为参数。
val add10: Int => Int = _ + 10 // 一个接受一个 Int 类型参数并返回一个 Int 类型值的函数
List(1, 2, 3) map add10 // List(11, 12, 13) - add10 被应用到每一个元素
// 匿名函数可以被使用来代替有命名的函数:
List(1, 2, 3) map (x => x + 10)
// 下划线标志,如果匿名函数只有一个参数可以被使用来表示该参数变量
List(1, 2, 3) map (_ + 10)
// 如果你所应用的匿名块和匿名函数都接受一个参数,那么你甚至可以省略下划线
List("Dom", "Bob", "Natalia") foreach println
// 三个双引号可以使字符串跨越多行,并包含引号
val html = """<form id="daform">
<p>Press belo', Joe</p>
<input type="submit">
</form>"""
/////////////////////////////////////////////////
// 2. 函数
/////////////////////////////////////////////////
// 数据结构
// 函数可以这样定义:
//
// def functionName(args...): ReturnType = { body... }
//
// 如果您以前学习过传统的编程语言,注意 return 关键字的省略。
// 在 Scala 中, 函数代码块最后一条表达式就是返回值。
def sumOfSquares(x: Int, y: Int): Int = {
val x2 = x * x
val y2 = y * y
x2 + y2
}
val a = Array(1, 2, 3, 5, 8, 13)
a(0)
a(3)
a(21) // 这会抛出一个异常
// 如果函数体是单行表达式,{ } 可以省略:
def sumOfSquaresShort(x: Int, y: Int): Int = x * x + y * y
val m = Map("fork" -> "tenedor", "spoon" -> "cuchara", "knife" -> "cuchillo")
m("fork")
m("spoon")
m("bottle") // 这会抛出一个异常
// 函数调用的语法是熟知的:
sumOfSquares(3, 4) // => 25
val safeM = m.withDefaultValue("no lo se")
safeM("bottle")
// 在多数情况下 (递归函数是需要注意的例外), 函数返回值可以省略,
// 变量所用的类型推导一样会应用到函数返回值中:
def sq(x: Int) = x * x // 编译器会推断得知返回值是 Int
val s = Set(1, 3, 7)
s(0)
s(1)
// 函数可以有默认参数
def addWithDefault(x: Int, y: Int = 5) = x + y
addWithDefault(1, 2) // => 3
addWithDefault(1) // => 6
/* 查看 map 的文档
* 点击[这里](http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.Map)
* 确保你可以读它
// 匿名函数是这样的:
(x:Int) => x * x
// 和 def 不同,如果语义清晰,匿名函数的参数类型也可以省略。
// 类型 "Int => Int" 意味着这个函数接收一个 Int 并返回一个 Int。
val sq: Int => Int = x => x * x
// 匿名函数的调用也是类似的:
sq(10) // => 100
// 如果您的匿名函数中每个参数仅使用一次,
// Scala 提供一个更简洁的方式来定义他们。这样的匿名函数极为常见,
// 在数据结构部分会明显可见。
val addOne: Int => Int = _ + 1
val weirdSum: (Int, Int) => Int = (_ * 2 + _ * 3)
addOne(5) // => 6
weirdSum(2, 4) // => 16
// return 关键字是存在的,但它只从最里面包裹了 return 的 def 函数中返回。
// 警告: 在 Scala 中使用 return 容易出错,应该避免使用。
// 在匿名函数中没有效果,例如:
def foo(x: Int): Int = {
val anonFunc: Int => Int = { z =>
if (z > 5)
return z // 这一行令 z 成为 foo 函数的返回值!
else
z + 2 // 这一行是 anonFunc 函数的返回值
}
anonFunc(x) // 这一行是 foo 函数的返回值
}
/*
* 译者注:此处是指匿名函数中的 return z 成为最后执行的语句,
* 在 anonFunc(x) 下面的表达式(假设存在)不再执行。如果 anonFunc
* 是用 def 定义的函数, return z 仅返回到 anonFunc(x)
* 在 anonFunc(x) 下面的表达式(假设存在)会继续执行。
*/
// 元组
(1, 2)
(4, 3, 2)
(1, 2, "three")
(a, 2, "three")
// 为什么有这个?
val divideInts = (x:Int, y:Int) => (x / y, x % y)
divideInts(10,3) // 函数 divideInts 返回你结果和余数
// 要读取元组的元素,使用 _._nn是从1开始的元素索引
val d = divideInts(10,3)
d._1
d._2
// 选择器
s.map(sq)
val sSquared = s. map(sq)
sSquared.filter(_ < 10)
sSquared.reduce (_+_)
// filter 函数接受一个预测(一个函数,形式为 A -> Boolean) 并选择出所有的元素满足这个预测
List(1, 2, 3) filter (_ > 2) // List(3)
List(
Person(name = "Dom", age = 23),
Person(name = "Bob", age = 30)
).filter(_.age > 25) // List(Person("Bob", 30))
// Scala 的 foreach 方法定义在特定的接受一个类型的集合上
// 返回 Unit(一个 void 方法)
aListOfNumbers foreach (x => println(x))
aListOfNumbers foreach println
// For 包含
for { n <- s } yield sq(n)
val nSquared2 = for { n <- s } yield sq(n)
for { n <- nSquared2 if n < 10 } yield n
for { n <- s; nSquared = n * n if nSquared < 10} yield nSquared
/* 注意:这些不是 for 循环. 一个 for 循环的语义是 '重复'('repeat')
然而,一个 for-包含 定义了一个两个数据结合间的关系 */
// 循环和迭代
/////////////////////////////////////////////////
// 3. 控制语句
/////////////////////////////////////////////////
1 to 5
val r = 1 to 5
r.foreach( println )
r foreach println
// 注意Scala 是相当宽容的当它遇到点和括号 - 分别地学习这些规则
// 这帮助你编写读起来像英语的 DSLs 和 APIs
r foreach println
// 附注: Scala 对点和括号的要求想当宽松,注意其规则是不同的。
// 这有助于写出读起来像英语的 DSL(领域特定语言) 和 API(应用编程接口)。
(5 to 1 by -1) foreach ( println )
@ -227,27 +231,27 @@ r foreach println
var i = 0
while (i < 10) { println("i " + i); i+=1 }
while (i < 10) { println("i " + i); i+=1 } // 发生了什么为什么
while (i < 10) { println("i " + i); i+=1 } // 没错再执行一次发生了什么为什么
i // 展示 i 的值。注意到 while 是一个传统意义上的循环
// 它顺序地执行并且改变循环变量的值。while 非常快,比 Java // 循环快,
// 但是在其上使用选择器和包含易理解和并行。
i // 显示 i 的值。注意 while 是经典的循环方式,它连续执行并改变循环中的变量。
// while 执行很快,比 Java 的循环快,但像上面所看到的那样用组合子和推导式
// 更易理解和并行
// do while 循环
do {
println("x is still less then 10");
println("x is still less than 10");
x += 1
} while (x < 10)
// 在 Scala中尾递归是一种惯用的执行循环的方式。
// 递归函数需要显示的返回类型,编译器不能推断出类型
// 这里它是 Unit。
// Scala 中尾递归是一种符合语言习惯的递归方式。
// 递归函数需要清晰的返回类型,编译器不能推断得知
// 这是一个 Unit。
def showNumbersInRange(a:Int, b:Int):Unit = {
print(a)
if (a < b)
showNumbersInRange(a + 1, b)
}
showNumbersInRange(1,14)
// 条件语句
@ -262,140 +266,340 @@ if (x == 11) println ("yeah") else println("nay")
println(if (x == 10) "yeah" else "nope")
val text = if (x == 10) "yeah" else "nope"
var i = 0
while (i < 10) { println("i " + i); i+=1 }
/////////////////////////////////////////////////
// 4. 数据结构
/////////////////////////////////////////////////
val a = Array(1, 2, 3, 5, 8, 13)
a(0)
a(3)
a(21) // 抛出异常
val m = Map("fork" -> "tenedor", "spoon" -> "cuchara", "knife" -> "cuchillo")
m("fork")
m("spoon")
m("bottle") // 抛出异常
val safeM = m.withDefaultValue("no lo se")
safeM("bottle")
val s = Set(1, 3, 7)
s(0)
s(1)
/* 这里查看 map 的文档 -
* http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.Map
* 并确保你会阅读
*/
// 元组
// 面向对象特性
(1, 2)
// 类名是 Dog
class Dog {
//bark 方法,返回字符串
def bark: String = {
// the body of the method
"Woof, woof!"
}
(4, 3, 2)
(1, 2, "three")
(a, 2, "three")
// 为什么有这个?
val divideInts = (x:Int, y:Int) => (x / y, x % y)
divideInts(10,3) // 函数 divideInts 同时返回结果和余数
// 要读取元组的元素,使用 _._nn是从1开始的元素索引
val d = divideInts(10,3)
d._1
d._2
/////////////////////////////////////////////////
// 5. 面向对象编程
/////////////////////////////////////////////////
/*
旁白: 教程中到现在为止我们所做的一切只是简单的表达式(值,函数等)。
这些表达式可以输入到命令行解释器中作为快速测试,但它们不能独立存在于 Scala
文件。举个例子,您不能在 Scala 文件上简单的写上 "val x = 5"。相反 Scala 文件
允许的顶级结构是:
- objects
- classes
- case classes
- traits
现在来解释这些是什么。
*/
// 类和其他语言的类相似,构造器参数在类名后声明,初始化在类结构体中完成。
class Dog(br: String) {
// 构造器代码在此
var breed: String = br
// 定义名为 bark 的方法,返回字符串
def bark = "Woof, woof!"
// 值和方法作用域假定为 public。"protected" 和 "private" 关键字也是可用的。
private def sleep(hours: Int) =
println(s"I'm sleeping for $hours hours")
// 抽象方法是没有方法体的方法。如果取消下面那行注释Dog 类必须被声明为 abstract
// abstract class Dog(...) { ... }
// def chaseAfter(what: String): String
}
// 类可以包含几乎其它的构造,包括其它的类,
// 函数方法对象case 类,特性等等。
val mydog = new Dog("greyhound")
println(mydog.breed) // => "greyhound"
println(mydog.bark) // => "Woof, woof!"
// Case 类
case class Person(name:String, phoneNumber:String)
Person("George", "1234") == Person("Kate", "1236")
// 模式匹配
val me = Person("George", "1234")
me match { case Person(name, number) => {
"We matched someone : " + name + ", phone : " + number }}
me match { case Person(name, number) => "Match : " + name; case _ => "Hm..." }
me match { case Person("George", number) => "Match"; case _ => "Hm..." }
me match { case Person("Kate", number) => "Match"; case _ => "Hm..." }
me match { case Person("Kate", _) => "Girl"; case Person("George", _) => "Boy" }
val kate = Person("Kate", "1234")
kate match { case Person("Kate", _) => "Girl"; case Person("George", _) => "Boy" }
// 正则表达式
val email = "(.*)@(.*)".r // 在字符串上调用 r 会使它变成一个正则表达式
val email(user, domain) = "henry@zkpr.com"
"mrbean@pyahoo.com" match {
case email(name, domain) => "I know your name, " + name
// "object" 关键字创造一种类型和该类型的单例。
// Scala 的 class 常常也含有一个 “伴生对象”class 中包含每个实例的行为,所有实例
// 共用的行为则放入 object 中。两者的区别和其他语言中类方法和静态方法类似。
// 请注意 object 和 class 可以同名。
object Dog {
def allKnownBreeds = List("pitbull", "shepherd", "retriever")
def createDog(breed: String) = new Dog(breed)
}
// Case 类是有额外内建功能的类。Scala 初学者常遇到的问题之一便是何时用类
// 和何时用 case 类。界线比较模糊,但通常类倾向于封装,多态和行为。类中的值
// 的作用域一般为 private 只有方向是暴露的。case 类的主要目的是放置不可变
// 数据。它们通常只有几个方法,且方法几乎没有副作用。
case class Person(name: String, phoneNumber: String)
// 字符串
// 创造新实例,注意 case 类不需要使用 "new" 关键字
val george = Person("George", "1234")
val kate = Person("Kate", "4567")
"Scala 字符串被双引号包围" //
'a' // Scala 字符
'单引号的字符串不存在' // 错误
"字符串拥有通常的 Java 方法定义在其上".length
"字符串也有额外的 Scala 方法".reverse
// 使用 case 类,您可以轻松得到一些功能,像 getters:
george.phoneNumber // => "1234"
// 参见: scala.collection.immutable.StringOps
// 每个字段的相等性比较(无需覆盖 .equals
Person("George", "1234") == Person("Kate", "1236") // => false
println("ABCDEF".length)
println("ABCDEF".substring(2, 6))
println("ABCDEF".replace("C", "3"))
// 简单的拷贝方式
// otherGeorge == Person("george", "9876")
val otherGeorge = george.copy(phoneNumber = "9876")
val n = 45
println(s"We have $n apples")
val a = Array(11, 9, 6)
println(s"My second daughter is ${a(2-1)} years old")
// 一些字符需要被转义,举例来说,字符串中的双引号:
val a = "They stood outside the \"Rose and Crown\""
// 三个双引号使得字符串可以跨行并且可以包含引号(无需转义)
val html = """<form id="daform">
<p>Press belo', Joe</p>
| <input type="submit">
</form>"""
// 还有很多。case 类同时可以用于模式匹配,接下来会看到。
// 敬请期待 Traits
// 应用结果和组织
// import
/////////////////////////////////////////////////
// 6. 模式匹配
/////////////////////////////////////////////////
// 模式匹配是一个强大和常用的 Scala 特性。这是用模式匹配一个 case 类的例子。
// 附注:不像其他语言, Scala 的 case 不需要 break 其他语言中 switch 语句的
// fall-through 现象不会发生。
def matchPerson(person: Person): String = person match {
// Then you specify the patterns:
case Person("George", number) => "We found George! His number is " + number
case Person("Kate", number) => "We found Kate! Her number is " + number
case Person(name, number) => "We matched someone : " + name + ", phone : " + number
}
val email = "(.*)@(.*)".r // 定义下一个例子会用到的正则
// 模式匹配看起来和 C语言家族的 switch 语句相似,但更为强大。
// Scala 中您可以匹配很多东西:
def matchEverything(obj: Any): String = obj match {
// 匹配值:
case "Hello world" => "Got the string Hello world"
// 匹配类型:
case x: Double => "Got a Double: " + x
// 匹配时指定条件
case x: Int if x > 10000 => "Got a pretty big number!"
// 像之前一样匹配 case 类:
case Person(name, number) => s"Got contact info for $name!"
// 匹配正则表达式:
case email(name, domain) => s"Got email address $name@$domain"
// 匹配元组:
case (a: Int, b: Double, c: String) => s"Got a tuple: $a, $b, $c"
// 匹配数据结构:
case List(1, b, c) => s"Got a list with three elements and starts with 1: 1, $b, $c"
// 模式可以嵌套
case List(List((1, 2,"YAY"))) => "Got a list of list of tuple"
}
// 事实上,你可以对任何有 "unapply" 方法的对象进行模式匹配。
// 这个特性如此强大以致于 Scala 允许定义一个函数作为模式匹配:
val patternFunc: Person => String = {
case Person("George", number) => s"George's number: $number"
case Person(name, number) => s"Random person's number: $number"
}
/////////////////////////////////////////////////
// 7. 函数式编程
/////////////////////////////////////////////////
// Scala 允许方法和函数作为其他方法和函数的参数和返回值。
val add10: Int => Int = _ + 10 // 一个接受一个 Int 类型参数并返回一个 Int 类型值的函数
List(1, 2, 3) map add10 // List(11, 12, 13) - add10 被应用到每一个元素
// 匿名函数可以被使用来代替有命名的函数:
List(1, 2, 3) map (x => x + 10)
// 如果匿名函数只有一个参数可以用下划线作为变量
List(1, 2, 3) map (_ + 10)
// 如果您所应用的匿名块和匿名函数都接受一个参数,那么你甚至可以省略下划线
List("Dom", "Bob", "Natalia") foreach println
// 组合子
// 译注: val sq: Int => Int = x => x * x
s.map(sq)
val sSquared = s. map(sq)
sSquared.filter(_ < 10)
sSquared.reduce (_+_)
// filter 函数接受一个 predicate (函数根据条件 A 返回 Boolean并选择
// 所有满足 predicate 的元素
List(1, 2, 3) filter (_ > 2) // List(3)
case class Person(name:String, age:Int)
List(
Person(name = "Dom", age = 23),
Person(name = "Bob", age = 30)
).filter(_.age > 25) // List(Person("Bob", 30))
// Scala 的 foreach 方法定义在某些集合中,接受一个函数并返回 Unit void 方法)
// 另请参见:
// http://www.scala-lang.org/api/current/index.html#scala.collection.IterableLike@foreach(f:A=>Unit):Unit
val aListOfNumbers = List(1, 2, 3, 4, 10, 20, 100)
aListOfNumbers foreach (x => println(x))
aListOfNumbers foreach println
// For 推导式
for { n <- s } yield sq(n)
val nSquared2 = for { n <- s } yield sq(n)
for { n <- nSquared2 if n < 10 } yield n
for { n <- s; nSquared = n * n if nSquared < 10} yield nSquared
/* 注意,这些不是 for 循环for 循环的语义是‘重复’,然而 for 推导式定义
两个数据集合的关系。 */
/////////////////////////////////////////////////
// 8. 隐式转换
/////////////////////////////////////////////////
/* 警告 警告: 隐式转换是 Scala 中一套强大的特性,因此容易被滥用。
* Scala 初学者在理解它们的工作原理和最佳实践之前,应抵制使用它的诱惑。
* 我们加入这一章节仅因为它们在 Scala 的库中太过常见,导致没有用隐式转换的库
* 就不可能做有意义的事情。这章节主要让你理解和使用隐式转换,而不是自己声明。
*/
// 可以通过 "implicit" 声明任何值val, 函数,对象等)为隐式值,
// 请注意这些例子中我们用到第5部分的 Dog 类。
implicit val myImplicitInt = 100
implicit def myImplicitFunction(breed: String) = new Dog("Golden " + breed)
// implicit 关键字本身不改变值的行为,所以上面的值可以照常使用。
myImplicitInt + 2 // => 102
myImplicitFunction("Pitbull").breed // => "Golden Pitbull"
// 区别在于,当另一段代码“需要”隐式值时,这些值现在有资格作为隐式值。
// 一种情况是隐式函数参数。
def sendGreetings(toWhom: String)(implicit howMany: Int) =
s"Hello $toWhom, $howMany blessings to you and yours!"
// 如果提供值给 “howMany”函数正常运行
sendGreetings("John")(1000) // => "Hello John, 1000 blessings to you and yours!"
// 如果省略隐式参数,会传一个和参数类型相同的隐式值,
// 在这个例子中, 是 “myImplicitInt":
sendGreetings("Jane") // => "Hello Jane, 100 blessings to you and yours!"
// 隐式的函数参数使我们可以模拟其他函数式语言的 type 类type classes
// 它经常被用到所以有特定的简写。这两行代码是一样的:
def foo[T](implicit c: C[T]) = ...
def foo[T : C] = ...
// 编译器寻找隐式值另一种情况是你调用方法时
// obj.method(...)
// 但 "obj" 没有一个名为 "method" 的方法。这样的话,如果有一个参数类型为 A
// 返回值类型为 B 的隐式转换obj 的类型是 AB 有一个方法叫 "method" ,这样
// 转换就会被应用。所以作用域里有上面的 myImplicitFunction, 我们可以这样做:
"Retriever".breed // => "Golden Retriever"
"Sheperd".bark // => "Woof, woof!"
// 这里字符串先被上面的函数转换为 Dog 对象,然后调用相应的方法。
// 这是相当强大的特性,但再次提醒,请勿轻率使用。
// 事实上,当你定义上面的隐式函数时,编译器会作出警告,除非你真的了解
// 你正在做什么否则不要使用。
/////////////////////////////////////////////////
// 9. 杂项
/////////////////////////////////////////////////
// 导入类
import scala.collection.immutable.List
// Import 所有的子包
// 导入所有子包
import scala.collection.immutable._
// 在一条语句中 Import 多个类
// 一条语句导入多个类
import scala.collection.immutable.{List, Map}
// 使用 '=>' 来重命名一个 import
// 使用 => 对导入进行重命名
import scala.collection.immutable.{ List => ImmutableList }
// import 除了一些类的其它所有的类。下面的例子除去了 Map 类和 Set 类:
// 导入所有类,排除其中一些。下面的语句排除了 Map 和 Set
import scala.collection.immutable.{Map => _, Set => _, _}
// 在 scala 源文件中,你的程序入口点使用一个拥有单一方法 main 的对象来定义:
// 在 Scala 文件用 object 和单一的 main 方法定义程序入口:
object Application {
def main(args: Array[String]): Unit = {
// stuff goes here.
}
}
// 文件可以包含多个类和对象。由 scalac 来编译
// 文件可以包含多个 class 和 object用 scalac 编译源文件
// 输入和输出
// 一行一行读取文件
// 按行读文件
import scala.io.Source
for(line <- Source.fromPath("myfile.txt").getLines())
for(line <- Source.fromFile("myfile.txt").getLines())
println(line)
// 使用 Java 的 PrintWriter 来写文件
// 用 Java 的 PrintWriter 写文件
val writer = new PrintWriter("myfile.txt")
writer.write("Writing line for line" + util.Properties.lineSeparator)
writer.write("Another line here" + util.Properties.lineSeparator)
writer.close()
```

View File

@ -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")
// 使用多元数组返回多返回值的函数
// 函数参数前带 `#` 表示外部参数名和内部参数名使用同一个名称。
// 第二个参数表示外部参数名使用 `externalParamName` ,内部参数名使用 `localParamName`
func greet2(#requiredName: String, externalParamName localParamName: String) -> String {
return "Hello \(requiredName), the day is \(localParamName)"
}
greet2(requiredName:"John", externalParamName: "Sunday") // 调用时,使用命名参数来指定参数的值
// 函数可以通过元组 (tuple) 返回多个值
func getGasPrices() -> (Double, Double, Double) {
return (3.59, 3.69, 3.79)
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 setup(numbers: Int...) {}
// 传递、返回函数
// 函数变量以及函数作为返回值返回
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: 闭包
//
// 函数是特殊的闭包({})
// 闭包示例.
// `->` 分隔参数和返回类型
// `in` 分隔闭包头和闭包体
numbers.map({
(number: Int) -> Int in
let result = 3 * number
return result
})
// 当类型已知时,可以这样做:
var numbers = [1, 2, 6]
// 函数是闭包的一个特例
// 闭包实例
// `->` 分隔了闭包的参数和返回值
// `in` 分隔了闭包头 (包括参数及返回值) 和闭包体
// 下面例子中,`map` 的参数是一个函数类型,它的功能是把数组里的元素作为参数,逐个调用 `map` 参数传递进来的函数。
numbers.map({
(number: Int) -> Int in
let result = 3 * number
return result
})
// 当闭包的参数类型和返回值都是己知的情况下,且只有一个语句作为其返回值时,我们可以简化闭包的写法
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
struct NamesTable {
let names = [String]()
// 自定义下标运算符
subscript(index: Int) -> String {
return names[index]
}
set {
sideLength = newValue / 4
}
}
init(sideLength: Int) {
super.init()
self.sideLength = sideLength
}
func shrink() {
if sideLength > 0 {
--sideLength
}
}
override func getArea() -> Int {
return sideLength * sideLength
}
}
var mySquare = new Square(sideLength: 5)
print(mySquare.getArea()) // 25
// 结构体有一个自动生成的隐含的命名构造函数
let namesTable = NamesTable(names: ["Me", "Them"])
let name = namesTable[1]
println("Name is \(name)") // Name is Them
//
// MARK: 类
//
// 类和结构体的有三个访问控制级别,他们分别是 internal (默认), public, private
// internal: 模块内部可以访问
// public: 其他模块可以访问
// private: 只有定义这个类或结构体的源文件才能访问
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
}
}
// 类 `Square``Rect` 继承
class Square: Rect {
// 便捷构造函数 (convenience inits) 是调用自己的命名构造函数 (designated inits) 的构造函数
// Square 自动继承了父类的命名构造函数
convenience init() {
self.init(sideLength: 5)
}
// 关于构造函数的继承,有以下几个规则:
// 1. 如果你没有实现任何命名构造函数,那么你就继承了父类的所有命名构造函数
// 2. 如果你重载了父类的所有命名构造函数,那么你就自动继承了所有的父类快捷构造函数
// 3. 如果你没有实现任何构造函数,那么你继承了父类的所有构造函数,包括命名构造函数和便捷构造函数
}
var mySquare = Square()
println(mySquare.getArea()) // 25
mySquare.shrink()
print(mySquare.sideLength) // 4
println(mySquare.sideLength) // 4
// 如果你不需要自定义getter 和setter,
// 但仍希望在获取或设置一个属性之前或之后运行
// 一些代码,你可以使用`willSet` 和 `didSet`
// 类型转换
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
}
}
}
// 根据 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 类似
//
// 协议可以让遵循同一协议的类型实例拥有相同的属性,方法,类方法,操作符或下标运算符等
// 下面代码定义一个协议,这个协议包含一个名为 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: 其它
//
// `协议(protocol)`: 与Java 的接口(Interface) 类似.
// `扩展(extension)`: 为现有类型添加额外特性
// 泛型: 与Java 相似。使用`where` 关键字指定
// 泛型的要求.
// 扩展: 给一个已经存在的数据类型添加功能
// 给 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
```