mirror of
https://github.com/adambard/learnxinyminutes-docs.git
synced 2024-12-23 17:41:41 +00:00
Merge branch 'master' of github.com:adambard/learnxinyminutes-docs
Fixed down merge-conflict.
This commit is contained in:
commit
a9680e9c02
@ -51,7 +51,7 @@ 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 $.
|
||||
# its name without $. If you want to use the variable's value, you should use $.
|
||||
# Note that ' (single quote) won't expand the variables!
|
||||
|
||||
# String substitution in variables
|
||||
@ -70,11 +70,11 @@ echo ${Foo:-"DefaultValueIfFooIsMissingOrEmpty"}
|
||||
|
||||
# Builtin variables:
|
||||
# There are some useful builtin variables, like
|
||||
echo "Last program return value: $?"
|
||||
echo "Last program's return value: $?"
|
||||
echo "Script's PID: $$"
|
||||
echo "Number of arguments: $#"
|
||||
echo "Scripts arguments: $@"
|
||||
echo "Scripts arguments separated in different variables: $1 $2..."
|
||||
echo "Number of arguments passed to script: $#"
|
||||
echo "All arguments passed to script: $@"
|
||||
echo "Script's arguments separated into different variables: $1 $2..."
|
||||
|
||||
# Reading a value from input:
|
||||
echo "What's your name?"
|
||||
@ -108,8 +108,8 @@ fi
|
||||
# Expressions are denoted with the following format:
|
||||
echo $(( 10 + 5 ))
|
||||
|
||||
# Unlike other programming languages, bash is a shell — so it works in a context
|
||||
# of current directory. You can list files and directories in the current
|
||||
# Unlike other programming languages, bash is a shell so it works in the context
|
||||
# of a current directory. You can list files and directories in the current
|
||||
# directory with the ls command:
|
||||
ls
|
||||
|
||||
|
@ -5,6 +5,7 @@ contributors:
|
||||
- ["Steven Basart", "http://github.com/xksteven"]
|
||||
- ["Matt Kline", "https://github.com/mrkline"]
|
||||
- ["Geoff Liu", "http://geoffliu.me"]
|
||||
- ["Connor Waters", "http://github.com/connorwaters"]
|
||||
lang: en
|
||||
---
|
||||
|
||||
@ -53,11 +54,11 @@ int main(int argc, char** argv)
|
||||
|
||||
// However, C++ varies in some of the following ways:
|
||||
|
||||
// In C++, character literals are one byte.
|
||||
sizeof('c') == 1
|
||||
// In C++, character literals are chars
|
||||
sizeof('c') == sizeof(char) == 1
|
||||
|
||||
// In C, character literals are the same size as ints.
|
||||
sizeof('c') == sizeof(10)
|
||||
// In C, character literals are ints
|
||||
sizeof('c') == sizeof(int)
|
||||
|
||||
|
||||
// C++ has strict prototyping
|
||||
@ -159,9 +160,9 @@ void foo()
|
||||
|
||||
int main()
|
||||
{
|
||||
// Includes all symbols from `namesapce Second` into the current scope. Note
|
||||
// that simply `foo()` no longer works, since it is now ambiguous whether
|
||||
// we're calling the `foo` in `namespace Second` or the top level.
|
||||
// Includes all symbols from namespace Second into the current scope. Note
|
||||
// that simply foo() no longer works, since it is now ambiguous whether
|
||||
// we're calling the foo in namespace Second or the top level.
|
||||
using namespace Second;
|
||||
|
||||
Second::foo(); // prints "This is Second::foo"
|
||||
@ -244,7 +245,13 @@ cout << fooRef; // Prints "I am foo. Hi!"
|
||||
// Doesn't reassign "fooRef". This is the same as "foo = bar", and
|
||||
// foo == "I am bar"
|
||||
// after this line.
|
||||
cout << &fooRef << endl; //Prints the address of foo
|
||||
fooRef = bar;
|
||||
cout << &fooRef << endl; //Still prints the address of foo
|
||||
cout << fooRef; // Prints "I am bar"
|
||||
|
||||
//The address of fooRef remains the same, i.e. it is still referring to foo.
|
||||
|
||||
|
||||
const string& barRef = bar; // Create a const reference to bar.
|
||||
// Like C, const values (and pointers and references) cannot be modified.
|
||||
@ -256,7 +263,7 @@ string tempObjectFun() { ... }
|
||||
string retVal = tempObjectFun();
|
||||
|
||||
// What happens in the second line is actually:
|
||||
// - a string object is returned from `tempObjectFun`
|
||||
// - a string object is returned from tempObjectFun
|
||||
// - a new string is constructed with the returned object as arugment to the
|
||||
// constructor
|
||||
// - the returned object is destroyed
|
||||
@ -268,15 +275,15 @@ string retVal = tempObjectFun();
|
||||
// code:
|
||||
foo(bar(tempObjectFun()))
|
||||
|
||||
// assuming `foo` and `bar` exist, the object returned from `tempObjectFun` is
|
||||
// passed to `bar`, and it is destroyed before `foo` is called.
|
||||
// assuming foo and bar exist, the object returned from tempObjectFun is
|
||||
// passed to bar, and it is destroyed before foo is called.
|
||||
|
||||
// Now back to references. The exception to the "at the end of the enclosing
|
||||
// expression" rule is if a temporary object is bound to a const reference, in
|
||||
// which case its life gets extended to the current scope:
|
||||
|
||||
void constReferenceTempObjectFun() {
|
||||
// `constRef` gets the temporary object, and it is valid until the end of this
|
||||
// constRef gets the temporary object, and it is valid until the end of this
|
||||
// function.
|
||||
const string& constRef = tempObjectFun();
|
||||
...
|
||||
@ -301,7 +308,7 @@ basic_string(basic_string&& other);
|
||||
// Idea being if we are constructing a new string from a temporary object (which
|
||||
// is going to be destroyed soon anyway), we can have a more efficient
|
||||
// constructor that "salvages" parts of that temporary string. You will see this
|
||||
// concept referred to as the move semantic.
|
||||
// concept referred to as "move semantics".
|
||||
|
||||
//////////////////////////////////////////
|
||||
// Classes and object-oriented programming
|
||||
@ -349,7 +356,10 @@ public:
|
||||
// These are called when an object is deleted or falls out of scope.
|
||||
// This enables powerful paradigms such as RAII
|
||||
// (see below)
|
||||
// Destructors must be virtual to allow classes to be derived from this one.
|
||||
// The destructor should be virtual if a class is to be derived from;
|
||||
// if it is not virtual, then the derived class' destructor will
|
||||
// not be called if the object is destroyed through a base-class reference
|
||||
// or pointer.
|
||||
virtual ~Dog();
|
||||
|
||||
}; // A semicolon must follow the class definition.
|
||||
@ -492,9 +502,10 @@ int main () {
|
||||
/////////////////////
|
||||
|
||||
// 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.
|
||||
// much more powerful than generic constructs in other languages. They also
|
||||
// support explicit and partial specialization and functional-style type
|
||||
// classes; in fact, they are a Turing-complete functional language embedded
|
||||
// in C++!
|
||||
|
||||
// We start with the kind of generic programming you might be familiar with. To
|
||||
// define a class or function that takes a type parameter:
|
||||
@ -506,7 +517,7 @@ public:
|
||||
};
|
||||
|
||||
// During compilation, the compiler actually generates copies of each template
|
||||
// with parameters substituted, and so the full definition of the class must be
|
||||
// with parameters substituted, 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.
|
||||
|
||||
@ -520,13 +531,13 @@ intBox.insert(123);
|
||||
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.
|
||||
// Until C++11, you had to place a space between the two '>'s, otherwise '>>'
|
||||
// would 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
|
||||
// instead. The 'class' keyword and 'typename' keywords are _mostly_
|
||||
// interchangeable in this case. For the full explanation, see
|
||||
// http://en.wikipedia.org/wiki/Typename
|
||||
// (yes, that keyword has its own Wikipedia page).
|
||||
|
||||
@ -582,12 +593,15 @@ try {
|
||||
// Do not allocate exceptions on the heap using _new_.
|
||||
throw std::runtime_error("A problem occurred");
|
||||
}
|
||||
|
||||
// Catch exceptions by const reference if they are objects
|
||||
catch (const std::exception& ex)
|
||||
{
|
||||
std::cout << ex.what();
|
||||
}
|
||||
|
||||
// Catches any exception not caught by previous _catch_ blocks
|
||||
} catch (...)
|
||||
catch (...)
|
||||
{
|
||||
std::cout << "Unknown exception caught";
|
||||
throw; // Re-throws the exception
|
||||
@ -597,8 +611,8 @@ catch (const std::exception& ex)
|
||||
// RAII
|
||||
///////
|
||||
|
||||
// RAII stands for Resource Allocation Is Initialization.
|
||||
// It is often considered the most powerful paradigm in C++,
|
||||
// RAII stands for "Resource Acquisition Is Initialization".
|
||||
// It is often considered the most powerful paradigm in C++
|
||||
// and is the simple concept that a constructor for an object
|
||||
// acquires that object's resources and the destructor releases them.
|
||||
|
||||
@ -749,7 +763,9 @@ 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).
|
||||
// There is an exception made for bools.
|
||||
// This is to allow you to test for null pointers with if(!ptr),
|
||||
// but as a consequence you can assign nullptr to a bool directly!
|
||||
*pt = nullptr; // This still compiles, even though '*pt' is a bool!
|
||||
|
||||
|
||||
@ -776,12 +792,12 @@ vector<Foo> v;
|
||||
for (int i = 0; i < 10; ++i)
|
||||
v.push_back(Foo());
|
||||
|
||||
// Following line sets size of v to 0, but destructors don't get called,
|
||||
// Following line sets size of v to 0, but destructors don't get called
|
||||
// and resources aren't released!
|
||||
v.empty();
|
||||
v.push_back(Foo()); // New value is copied into the first Foo we inserted in the loop.
|
||||
v.push_back(Foo()); // New value is copied into the first Foo we inserted
|
||||
|
||||
// Truly destroys all values in v. See section about temporary object for
|
||||
// Truly destroys all values in v. See section about temporary objects for
|
||||
// explanation of why this works.
|
||||
v.swap(vector<Foo>());
|
||||
|
||||
|
@ -130,7 +130,9 @@ int main(void) {
|
||||
// can be declared as well. The size of such an array need not be a compile
|
||||
// time constant:
|
||||
printf("Enter the array size: "); // ask the user for an array size
|
||||
char buf[0x100];
|
||||
int size;
|
||||
fscanf(stdin, "%d", &size);
|
||||
char buf[size];
|
||||
fgets(buf, sizeof buf, stdin);
|
||||
|
||||
// strtoul parses a string to an unsigned integer
|
||||
|
@ -1074,14 +1074,14 @@ Installing the Compiler
|
||||
|
||||
Chapel can be built and installed on your average 'nix machine (and cygwin).
|
||||
[Download the latest release version](https://github.com/chapel-lang/chapel/releases/)
|
||||
and its as easy as
|
||||
and it's as easy as
|
||||
|
||||
1. `tar -xvf chapel-1.12.0.tar.gz`
|
||||
2. `cd chapel-1.12.0`
|
||||
3. `make`
|
||||
4. `source util/setchplenv.bash # or .sh or .csh or .fish`
|
||||
|
||||
You will need to `source util/setchplenv.EXT` from within the Chapel directory (`$CHPL_HOME`) every time your terminal starts so its suggested that you drop that command in a script that will get executed on startup (like .bashrc).
|
||||
You will need to `source util/setchplenv.EXT` from within the Chapel directory (`$CHPL_HOME`) every time your terminal starts so it's suggested that you drop that command in a script that will get executed on startup (like .bashrc).
|
||||
|
||||
Chapel is easily installed with Brew for OS X
|
||||
|
||||
|
@ -175,7 +175,8 @@ nil ; for false - and the empty list
|
||||
:age 5))
|
||||
*rover* ; => #S(DOG :NAME "rover" :BREED "collie" :AGE 5)
|
||||
|
||||
(dog-p *rover*) ; => t ;; ewww)
|
||||
(dog-p *rover*) ; => true #| -p signifies "predicate". It's used to
|
||||
check if *rover* is an instance of dog. |#
|
||||
(dog-name *rover*) ; => "rover"
|
||||
|
||||
;; Dog-p, make-dog, and dog-name are all created by defstruct!
|
||||
|
@ -236,7 +236,8 @@ on a new line! ""Wow!"", the masses cried";
|
||||
// Ternary operators
|
||||
// A simple if/else can be written as follows
|
||||
// <condition> ? <true> : <false>
|
||||
string isTrue = (true) ? "True" : "False";
|
||||
int toCompare = 17;
|
||||
string isTrue = toCompare == 17 ? "True" : "False";
|
||||
|
||||
// While loop
|
||||
int fooWhile = 0;
|
||||
|
@ -248,7 +248,8 @@ zur nächsten Zeile, ""Wahnsinn!"", die Massen waren kaum zu bändigen";
|
||||
// Ternärer Operator
|
||||
// Anstatt eines einfachen if/else lässt sich auch folgendes schreiben:
|
||||
// <condition> ? <true> : <false>
|
||||
string isTrue = true ? "Ja" : "Nein";
|
||||
int zumVergleich = 17;
|
||||
string isTrue = zumVergleich == 17 ? "Ja" : "Nein";
|
||||
|
||||
// while-Schleife
|
||||
int fooWhile = 0;
|
||||
|
@ -48,7 +48,7 @@ Ein Repository besteht in Git aus dem .git-Verzeichnis und dem Arbeitsverzeichni
|
||||
|
||||
### .git-Verzeichnis (Teil des Repositorys)
|
||||
|
||||
Das .git-Verzeichnis enth? alle Einstellung, Logs, Branches, den HEAD und mehr.
|
||||
Das .git-Verzeichnis enthält alle Einstellung, Logs, Branches, den HEAD und mehr.
|
||||
[Ausführliche Übersicht](http://gitready.com/advanced/2009/03/23/whats-inside-your-git-directory.html)
|
||||
|
||||
### Arbeitsverzeichnis (Teil des Repositorys)
|
||||
|
@ -312,7 +312,7 @@ Dokumentation lesen.
|
||||
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
|
||||
Gut dokumentiert, demonstriert sie leicht zu verstehendes und im idiomatischen Stil
|
||||
verfasstes Go. Erreichbar ist der Quelltext auch durch das Klicken der Funktionsnamen
|
||||
in der [offiziellen Dokumentation von Go](http://golang.org/pkg/).
|
||||
|
||||
|
@ -25,6 +25,7 @@ filename: learnerlang.erl
|
||||
%% 1. Variables and pattern matching.
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
% In Erlang new variables are bound with an `=` statement.
|
||||
Num = 42. % All variable names must start with an uppercase letter.
|
||||
|
||||
% Erlang has single-assignment variables; if you try to assign a different
|
||||
@ -32,9 +33,11 @@ Num = 42. % All variable names must start with an uppercase letter.
|
||||
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. When an empty variable is used on the
|
||||
% left hand side of the `=` operator to is bound (assigned), but when a bound
|
||||
% varaible is used on the left hand side the following behaviour is observed.
|
||||
% `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.
|
||||
@ -299,6 +302,39 @@ CalculateArea ! {circle, 2}. % 12.56000000000000049738
|
||||
% The shell is also a process; you can use `self` to get the current pid.
|
||||
self(). % <0.41.0>
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%% 5. Testing with EUnit
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
% Unit tests can be written using EUnits's test generators and assert macros
|
||||
-module(fib).
|
||||
-export([fib/1]).
|
||||
-include_lib("eunit/include/eunit.hrl").
|
||||
|
||||
fib(0) -> 1;
|
||||
fib(1) -> 1;
|
||||
fib(N) when N > 1 -> fib(N-1) + fib(N-2).
|
||||
|
||||
fib_test_() ->
|
||||
[?_assert(fib(0) =:= 1),
|
||||
?_assert(fib(1) =:= 1),
|
||||
?_assert(fib(2) =:= 2),
|
||||
?_assert(fib(3) =:= 3),
|
||||
?_assert(fib(4) =:= 5),
|
||||
?_assert(fib(5) =:= 8),
|
||||
?_assertException(error, function_clause, fib(-1)),
|
||||
?_assert(fib(31) =:= 2178309)
|
||||
].
|
||||
|
||||
% EUnit will automatically export to a test() function to allow running the tests
|
||||
% in the erlang shell
|
||||
fib:test()
|
||||
|
||||
% The popular erlang build tool Rebar is also compatible with EUnit
|
||||
% ```
|
||||
% rebar eunit
|
||||
% ```
|
||||
|
||||
```
|
||||
|
||||
## References
|
||||
|
829
es-es/c++-es.html.markdown
Normal file
829
es-es/c++-es.html.markdown
Normal file
@ -0,0 +1,829 @@
|
||||
---
|
||||
language: c++
|
||||
filename: learncpp.cpp
|
||||
contributors:
|
||||
- ["Steven Basart", "http://github.com/xksteven"]
|
||||
- ["Matt Kline", "https://github.com/mrkline"]
|
||||
- ["Geoff Liu", "http://geoffliu.me"]
|
||||
- ["Connor Waters", "http://github.com/connorwaters"]
|
||||
translators:
|
||||
- ["Gerson Lázaro", "https://gersonlazaro.com"]
|
||||
lang: es-es
|
||||
---
|
||||
|
||||
C++ es un lenguaje de programación de sistemas que,
|
||||
[de acuerdo a su inventor Bjarne Stroustrup](http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2014/Keynote),
|
||||
fue diseñado para
|
||||
|
||||
- ser un "mejor C"
|
||||
- soportar abstracción de datos
|
||||
- soportar programación orientada a objetos
|
||||
- soportar programación genérica
|
||||
|
||||
Aunque su sintaxis puede ser más difícil o compleja que los nuevos lenguajes,
|
||||
es ampliamente utilizado, ya que compila instrucciones nativas que pueden ser
|
||||
directamente ejecutadas por el procesador y ofrece un estricto control sobre
|
||||
el hardware (como C), mientras ofrece características de alto nivel como
|
||||
genericidad, excepciones, y clases. Esta combinación de velocidad y
|
||||
funcionalidad hace de C ++ uno de los lenguajes de programación más utilizados.
|
||||
|
||||
```c++
|
||||
////////////////////
|
||||
// Comparación con C
|
||||
////////////////////
|
||||
|
||||
// C ++ es _casi_ un superconjunto de C y comparte su sintaxis básica para las
|
||||
// declaraciones de variables, tipos primitivos y funciones.
|
||||
|
||||
// Al igual que en C, el punto de entrada de tu programa es una función llamada
|
||||
// main con un retorno de tipo entero.
|
||||
// Este valor sirve como código de salida del programa.
|
||||
// Mira http://en.wikipedia.org/wiki/Exit_status para mayor información.
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
// Los argumentos de la línea de comandos se pasan por argc y argv de la
|
||||
// misma manera que en C.
|
||||
// argc indica el número de argumentos,
|
||||
// y argv es un arreglo de strings de estilo C (char*)
|
||||
// representando los argumentos.
|
||||
// El primer argumento es el nombre con el que el programa es llamado.
|
||||
// argc y argv pueden omitirse si no te preocupan los argumentos,
|
||||
// dejando la definición de la función como int main ()
|
||||
|
||||
// Un estado de salida 0 indica éxito.
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Sin embargo, C ++ varía en algunas de las siguientes maneras:
|
||||
|
||||
// En C++, los caracteres literales son caracteres
|
||||
sizeof('c') == sizeof(char) == 1
|
||||
|
||||
// En C, los caracteres literales son enteros
|
||||
sizeof('c') == sizeof(int)
|
||||
|
||||
|
||||
// C++ tiene prototipado estricto
|
||||
void func(); // función que no acepta argumentos
|
||||
|
||||
// En C
|
||||
void func(); // función que puede aceptar cualquier número de argumentos
|
||||
|
||||
// Use nullptr en lugar de NULL en C++
|
||||
int* ip = nullptr;
|
||||
|
||||
// Las cabeceras (headers) estándar de C están disponibles en C ++,
|
||||
// pero tienen el prefijo "c" y no tienen sufijo .h.
|
||||
#include <cstdio>
|
||||
|
||||
int main()
|
||||
{
|
||||
printf("Hola mundo!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
//////////////////////////
|
||||
// Sobrecarga de funciones
|
||||
//////////////////////////
|
||||
|
||||
// C++ soporta sobrecarga de funciones
|
||||
// siempre que cada función tenga diferentes parámetros.
|
||||
|
||||
void print(char const* myString)
|
||||
{
|
||||
printf("String %s\n", myString);
|
||||
}
|
||||
|
||||
void print(int myInt)
|
||||
{
|
||||
printf("Mi entero es %d", myInt);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
print("Hello"); // Resolves to void print(const char*)
|
||||
print(15); // Resolves to void print(int)
|
||||
}
|
||||
|
||||
////////////////////////////////////
|
||||
// Argumentos de función por defecto
|
||||
////////////////////////////////////
|
||||
|
||||
// Puedes proporcionar argumentos por defecto para una función si no son
|
||||
// proporcionados por quien la llama.
|
||||
|
||||
void doSomethingWithInts(int a = 1, int b = 4)
|
||||
{
|
||||
// Hacer algo con los enteros aqui
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
doSomethingWithInts(); // a = 1, b = 4
|
||||
doSomethingWithInts(20); // a = 20, b = 4
|
||||
doSomethingWithInts(20, 5); // a = 20, b = 5
|
||||
}
|
||||
|
||||
// Los argumentos predeterminados deben estar al final de la lista de argumentos.
|
||||
|
||||
void invalidDeclaration(int a = 1, int b) // Error!
|
||||
{
|
||||
}
|
||||
|
||||
/////////////////////
|
||||
// Espacios de nombre
|
||||
/////////////////////
|
||||
|
||||
// Espacios de nombres proporcionan ámbitos separados para variable, función y
|
||||
// otras declaraciones.
|
||||
// Los espacios de nombres se pueden anidar.
|
||||
|
||||
namespace First {
|
||||
namespace Nested {
|
||||
void foo()
|
||||
{
|
||||
printf("Esto es First::Nested::foo\n");
|
||||
}
|
||||
} // fin del nombre de espacio Nested
|
||||
} // fin del nombre de espacio First
|
||||
|
||||
namespace Second {
|
||||
void foo()
|
||||
{
|
||||
printf("Esto es Second::foo\n")
|
||||
}
|
||||
}
|
||||
|
||||
void foo()
|
||||
{
|
||||
printf("Este es global: foo\n");
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
// Incluye todos los símbolos del espacio de nombre Second en el ámbito
|
||||
// actual. Tenga en cuenta que simplemente foo() no funciona, ya que ahora
|
||||
// es ambigua si estamos llamando a foo en espacio de nombres Second o en
|
||||
// el nivel superior.
|
||||
using namespace Second;
|
||||
|
||||
Second::foo(); // imprime "Esto es Second::foo"
|
||||
First::Nested::foo(); // imprime "Esto es First::Nested::foo"
|
||||
::foo(); // imprime "Este es global: foo"
|
||||
}
|
||||
|
||||
/////////////////
|
||||
// Entrada/Salida
|
||||
/////////////////
|
||||
|
||||
// La entrada y salida de C++ utiliza flujos (streams)
|
||||
// cin, cout, y cerr representan a stdin, stdout, y stderr.
|
||||
// << es el operador de inserción >> es el operador de extracción.
|
||||
|
||||
|
||||
#include <iostream> // Incluir para el flujo de entrada/salida
|
||||
|
||||
using namespace std; // Los streams estan en std namespace (libreria estandar)
|
||||
|
||||
int main()
|
||||
{
|
||||
int myInt;
|
||||
|
||||
// Imprime a la stdout (o terminal/pantalla)
|
||||
cout << "Ingresa tu número favorito:\n";
|
||||
// Toma una entrada
|
||||
cin >> myInt;
|
||||
|
||||
// cout puede también ser formateado
|
||||
cout << "Tu número favorito es " << myInt << "\n";
|
||||
// imprime "Tu número favorito es <myInt>"
|
||||
|
||||
cerr << "Usado para mensajes de error";
|
||||
}
|
||||
////////////////////
|
||||
// Cadenas (Strings)
|
||||
////////////////////
|
||||
|
||||
// Las cadenas en C++ son objetos y tienen muchas funciones
|
||||
#include <string>
|
||||
|
||||
using namespace std; // Strings también estan en namespace std
|
||||
|
||||
string myString = "Hola";
|
||||
string myOtherString = " Mundo";
|
||||
|
||||
// + es usado para concatenar.
|
||||
cout << myString + myOtherString; // "Hola Mundo"
|
||||
|
||||
cout << myString + " Tu"; // "Hola Tu"
|
||||
|
||||
// Las cadenas en C++ son mutables y tienen valor semántico.
|
||||
myString.append(" Perro");
|
||||
cout << myString; // "Hola Perro"
|
||||
|
||||
|
||||
//////////////
|
||||
// Referencias
|
||||
//////////////
|
||||
|
||||
// Además de punteros como los de C,
|
||||
// C++ tiene _references_.
|
||||
// Estos tipos de puntero no pueden ser reasignados una vez establecidos
|
||||
// Y no pueden ser nulos.
|
||||
// También tienen la misma sintaxis que la propia variable:
|
||||
// No es necesaria * para eliminar la referencia y
|
||||
// & (dirección) no se utiliza para la asignación.
|
||||
|
||||
using namespace std;
|
||||
|
||||
string foo = "Yo soy foo";
|
||||
string bar = "Yo soy bar";
|
||||
|
||||
string& fooRef = foo; // Crea una referencia a foo.
|
||||
fooRef += ". Hola!"; // Modifica foo través de la referencia
|
||||
cout << fooRef; // Imprime "Yo soy foo. Hola!"
|
||||
|
||||
// No trate de reasignar "fooRef". Esto es lo mismo que "foo = bar", y
|
||||
// foo == "Yo soy bar"
|
||||
// después de esta linea.
|
||||
fooRef = bar;
|
||||
|
||||
const string& barRef = bar; // Crea una referencia constante a bar.
|
||||
// Como en C, los valores constantes (y punteros y referencias) no pueden ser
|
||||
// modificados.
|
||||
barRef += ". Hola!"; // Error, referencia constante no puede ser modificada.
|
||||
|
||||
// Sidetrack: Antes de hablar más sobre referencias, hay que introducir un
|
||||
// concepto llamado objeto temporal. Supongamos que tenemos el siguiente código:
|
||||
string tempObjectFun() { ... }
|
||||
string retVal = tempObjectFun();
|
||||
|
||||
// Lo que pasa en la segunda línea es en realidad:
|
||||
// - Un objeto de cadena es retornado desde tempObjectFun
|
||||
// - Una nueva cadena se construye con el objeto devuelto como argumento al
|
||||
// constructor
|
||||
// - El objeto devuelto es destruido
|
||||
// El objeto devuelto se llama objeto temporal. Objetos temporales son
|
||||
// creados cada vez que una función devuelve un objeto, y es destruido en el
|
||||
// fin de la evaluación de la expresión que encierra (Bueno, esto es lo que la
|
||||
// norma dice, pero los compiladores están autorizados a cambiar este
|
||||
// comportamiento. Busca "return value optimization" para ver mas detalles).
|
||||
// Así que en este código:
|
||||
foo(bar(tempObjectFun()))
|
||||
|
||||
// Suponiendo que foo y bar existen, el objeto retornado de tempObjectFun es
|
||||
// pasado al bar, y se destruye antes de llamar foo.
|
||||
|
||||
// Ahora, de vuelta a las referencias. La excepción a la regla "en el extremo
|
||||
// de la expresión encerrada" es si un objeto temporal se une a una
|
||||
// referencia constante, en cuyo caso su vida se extiende al ámbito actual:
|
||||
|
||||
void constReferenceTempObjectFun() {
|
||||
// ConstRef obtiene el objeto temporal, y es válido hasta el final de esta
|
||||
// función.
|
||||
const string& constRef = tempObjectFun();
|
||||
...
|
||||
}
|
||||
|
||||
// Otro tipo de referencia introducida en C ++ 11 es específicamente para
|
||||
// objetos temporales. No se puede tener una variable de este tipo, pero tiene
|
||||
// prioridad en resolución de sobrecarga:
|
||||
|
||||
void someFun(string& s) { ... } // Referencia regular
|
||||
void someFun(string&& s) { ... } // Referencia a objeto temporal
|
||||
|
||||
string foo;
|
||||
someFun(foo); // Llama la función con referencia regular
|
||||
someFun(tempObjectFun()); // Llama la versión con referencia temporal
|
||||
|
||||
// Por ejemplo, puedes ver estas dos versiones de constructores para
|
||||
// std::basic_string:
|
||||
basic_string(const basic_string& other);
|
||||
basic_string(basic_string&& other);
|
||||
|
||||
// La idea es que si estamos construyendo una nueva cadena de un objeto temporal
|
||||
// (que va a ser destruido pronto de todos modos), podemos tener un constructor
|
||||
// mas eficiente que "rescata" partes de esa cadena temporal. Usted verá este
|
||||
// Concepto denominado "movimiento semántico".
|
||||
|
||||
////////////////////////////////////////////
|
||||
// Clases y programación orientada a objetos
|
||||
////////////////////////////////////////////
|
||||
|
||||
// Primer ejemplo de clases
|
||||
#include <iostream>
|
||||
|
||||
// Declara una clase.
|
||||
// Las clases son usualmente declaradas en archivos de cabeceras (.h o .hpp)
|
||||
class Dog {
|
||||
// Variables y funciones de la clase son privados por defecto.
|
||||
std::string name;
|
||||
int weight;
|
||||
|
||||
// Todos los miembros siguientes de este son públicos
|
||||
// Hasta que se encuentre "private" o "protected".
|
||||
// All members following this are public
|
||||
// until "private:" or "protected:" is found.
|
||||
public:
|
||||
|
||||
// Constructor por defecto
|
||||
Dog();
|
||||
|
||||
// Declaraciones de funciones de la clase (implementaciones a seguir)
|
||||
// Nota que usamos std::string aquí en lugar de colocar
|
||||
// using namespace std;
|
||||
// arriba.
|
||||
// Nunca ponga una declaración "using namespace" en un encabezado.
|
||||
void setName(const std::string& dogsName);
|
||||
|
||||
void setWeight(int dogsWeight);
|
||||
// Funciones que no modifican el estado del objeto
|
||||
// Deben marcarse como const.
|
||||
// Esto le permite llamarlas si se envia una referencia constante al objeto.
|
||||
// También tenga en cuenta que las funciones deben ser declaradas
|
||||
// explícitamente como _virtual_ para que sea reemplazada en las clases
|
||||
// derivadas.
|
||||
// Las funciones no son virtuales por defecto por razones de rendimiento.
|
||||
virtual void print() const;
|
||||
|
||||
// Las funciones también se pueden definir en el interior
|
||||
// del cuerpo de la clase.
|
||||
// Funciones definidas como tales están entre líneas automáticamente.
|
||||
void bark() const { std::cout << name << " barks!\n"; }
|
||||
|
||||
// Junto a los constructores, C++ proporciona destructores.
|
||||
// Estos son llamados cuando un objeto se elimina o está fuera del ámbito.
|
||||
// Esto permite paradigmas potentes como RAII
|
||||
// (mira abajo)
|
||||
// El destructor debe ser virtual si una clase es dervada desde el;
|
||||
// Si no es virtual, entonces la clase derivada destructor
|
||||
// No será llamada si el objeto se destruye a través de una referencia de
|
||||
// la clase base o puntero.
|
||||
virtual ~Dog();
|
||||
|
||||
|
||||
|
||||
}; // Un punto y coma debe seguir la definición de clase.
|
||||
|
||||
// Las funciones de una clase son normalmente implementados en archivos .cpp.
|
||||
Dog::Dog()
|
||||
{
|
||||
std::cout << "Un perro ha sido construido\n";
|
||||
}
|
||||
|
||||
// Objetos (tales como cadenas) deben ser pasados por referencia
|
||||
// Si los estas modificando o referencia constante en caso contrario.
|
||||
void Dog::setName(const std::string& dogsName)
|
||||
{
|
||||
name = dogsName;
|
||||
}
|
||||
|
||||
void Dog::setWeight(int dogsWeight)
|
||||
{
|
||||
weight = dogsWeight;
|
||||
}
|
||||
|
||||
// Nota que "virtual" sólo se necesita en la declaración, no en la definición.
|
||||
void Dog::print() const
|
||||
{
|
||||
std::cout << "El perro es " << name << " y pesa " << weight << "kg\n";
|
||||
}
|
||||
|
||||
Dog::~Dog()
|
||||
{
|
||||
cout << "Adiós " << name << "\n";
|
||||
}
|
||||
|
||||
int main() {
|
||||
Dog myDog; // imprime "Un perro ha sido construido"
|
||||
myDog.setName("Barkley");
|
||||
myDog.setWeight(10);
|
||||
myDog.print(); // imprime "El perro es Barkley y pesa 10 kg"
|
||||
return 0;
|
||||
} // imprime "Adiós Barkley"
|
||||
|
||||
// Herencia:
|
||||
|
||||
// Esta clase hereda todo lo público y protegido de la clase Dog
|
||||
class OwnedDog : public Dog {
|
||||
|
||||
void setOwner(const std::string& dogsOwner);
|
||||
|
||||
// Reemplaza el comportamiento de la función de impresión
|
||||
// de todos los OwnedDogs. Mira
|
||||
// http://en.wikipedia.org/wiki/Polymorphism_(computer_science)#Subtyping
|
||||
// Para una introducción más general si no está familiarizado con el
|
||||
// polimorfismo de subtipo.
|
||||
// La palabra clave override es opcional, pero asegura que estás
|
||||
// reemplazando el método de una clase base.
|
||||
void print() const override;
|
||||
|
||||
private:
|
||||
std::string owner;
|
||||
};
|
||||
|
||||
// Mientras tanto, en el archivo .cpp correspondiente:
|
||||
|
||||
void OwnedDog::setOwner(const std::string& dogsOwner)
|
||||
{
|
||||
owner = dogsOwner;
|
||||
}
|
||||
|
||||
void OwnedDog::print() const
|
||||
{
|
||||
Dog::print(); // Llama a la función de impresión en la clase base Dog
|
||||
std::cout << "El perro es de " << owner << "\n";
|
||||
// Imprime "El perro es <name> y pesa <weight>"
|
||||
// "El perro es de <owner>"
|
||||
}
|
||||
|
||||
////////////////////////////////////////////
|
||||
// Inicialización y sobrecarga de operadores
|
||||
////////////////////////////////////////////
|
||||
|
||||
// En C ++ se puede sobrecargar el comportamiento
|
||||
// de los operadores como +, -, *, /, etc.
|
||||
// Esto se hace mediante la definición de una función que es llamada
|
||||
// cada vez que se utiliza el operador.
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
class Point {
|
||||
public:
|
||||
// Las variables de la clase pueden dar valores por defecto de esta manera.
|
||||
double x = 0;
|
||||
double y = 0;
|
||||
|
||||
// Define un constructor por defecto que no hace nada
|
||||
// pero inicializa el punto al valor por defecto (0, 0)
|
||||
Point() { };
|
||||
|
||||
// The following syntax is known as an initialization list
|
||||
// and is the proper way to initialize class member values
|
||||
Point (double a, double b) :
|
||||
x(a),
|
||||
y(b)
|
||||
{ /* No hace nada excepto inicializar los valores */ }
|
||||
|
||||
// Sobrecarga el operador +
|
||||
Point operator+(const Point& rhs) const;
|
||||
|
||||
// Sobrecarga el operador +=
|
||||
Point& operator+=(const Point& rhs);
|
||||
|
||||
// También tendría sentido añadir los operadores - y -=,
|
||||
// Pero vamos a omitirlos por razones de brevedad.
|
||||
};
|
||||
|
||||
Point Point::operator+(const Point& rhs) const
|
||||
{
|
||||
// Crea un nuevo punto que es la suma de este y 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);
|
||||
// Llama al operador + de Point
|
||||
// Point llama la función + con right como parámetro
|
||||
Point result = up + right;
|
||||
// Prints "Result is upright (1,1)"
|
||||
cout << "Result is upright (" << result.x << ',' << result.y << ")\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
/////////////////////////
|
||||
// Plantillas (Templates)
|
||||
/////////////////////////
|
||||
|
||||
// Las plantillas en C++ se utilizan sobre todo en la programación genérica,
|
||||
// a pesar de que son mucho más poderoso que los constructores genéricos
|
||||
// en otros lenguajes. Ellos también soportan especialización explícita y
|
||||
// parcial y clases de tipo estilo funcional; de hecho, son un lenguaje
|
||||
// funcional Turing-completo incrustado en C ++!
|
||||
|
||||
// Empezamos con el tipo de programación genérica que podría estar
|
||||
// familiarizado.
|
||||
// Para definir una clase o función que toma un parámetro de tipo:
|
||||
template<class T>
|
||||
class Box {
|
||||
public:
|
||||
// En este caso, T puede ser usado como cualquier otro tipo.
|
||||
void insert(const T&) { ... }
|
||||
};
|
||||
|
||||
// Durante la compilación, el compilador realmente genera copias de cada
|
||||
// plantilla con parámetros sustituidos, por lo que la definición completa
|
||||
// de la clase debe estar presente en cada invocación.
|
||||
// Es por esto que usted verá clases de plantilla definidas
|
||||
// Enteramente en archivos de cabecera.
|
||||
|
||||
//Para crear una instancia de una clase de plantilla en la pila:
|
||||
Box<int> intBox;
|
||||
|
||||
y puedes utilizarlo como era de esperar:
|
||||
intBox.insert(123);
|
||||
|
||||
// Puedes, por supuesto, anidar plantillas:
|
||||
Box<Box<int> > boxOfBox;
|
||||
boxOfBox.insert(intBox);
|
||||
|
||||
// Hasta C++11, había que colocar un espacio entre los dos '>'s,
|
||||
// de lo contrario '>>' serían analizados como el operador de desplazamiento
|
||||
// a la derecha.
|
||||
|
||||
|
||||
// A veces verás
|
||||
// template<typename T>
|
||||
// en su lugar. La palabra clave "class" y las palabras clave "typename" son
|
||||
// mayormente intercambiables en este caso. Para la explicación completa, mira
|
||||
// http://en.wikipedia.org/wiki/Typename
|
||||
// (sí, esa palabra clave tiene su propia página de Wikipedia).
|
||||
|
||||
// Del mismo modo, una plantilla de función:
|
||||
template<class T>
|
||||
void barkThreeTimes(const T& input)
|
||||
{
|
||||
input.bark();
|
||||
input.bark();
|
||||
input.bark();
|
||||
}
|
||||
|
||||
// Observe que no se especifica nada acerca de los tipos de parámetros aquí.
|
||||
// El compilador generará y comprobará cada invocación de la plantilla,
|
||||
// por lo que la función anterior funciona con cualquier tipo "T"
|
||||
// que tenga un método 'bark' constante!
|
||||
|
||||
|
||||
Dog fluffy;
|
||||
fluffy.setName("Fluffy")
|
||||
barkThreeTimes(fluffy); // Imprime "Fluffy barks" 3 veces.
|
||||
|
||||
Los parámetros de la plantilla no tienen que ser las clases:
|
||||
template<int Y>
|
||||
void printMessage() {
|
||||
cout << "Aprende C++ en " << Y << " minutos!" << endl;
|
||||
}
|
||||
|
||||
// Y usted puede especializar explícitamente plantillas
|
||||
// para código más eficiente.
|
||||
// Por supuesto, la mayor parte del mundo real que utiliza una especialización
|
||||
// no son tan triviales como esta.
|
||||
// Tenga en cuenta que usted todavía tiene que declarar la función (o clase)
|
||||
// como plantilla incluso si ha especificado de forma explícita todos
|
||||
// los parámetros.
|
||||
|
||||
template<>
|
||||
void printMessage<10>() {
|
||||
cout << "Aprende C++ rapido en solo 10 minutos!" << endl;
|
||||
}
|
||||
|
||||
printMessage<20>(); // Prints "Aprende C++ en 20 minutos!"
|
||||
printMessage<10>(); // Prints "Aprende C++ rapido en solo 10 minutos!"
|
||||
|
||||
|
||||
/////////////////////
|
||||
// Manejador de excepciones
|
||||
/////////////////////
|
||||
|
||||
// La biblioteca estándar proporciona algunos tipos de excepción
|
||||
// (mira http://en.cppreference.com/w/cpp/error/exception)
|
||||
// pero cualquier tipo puede ser lanzado como una excepción
|
||||
#include <exception>
|
||||
#include <stdexcept>
|
||||
|
||||
//Todas las excepciones lanzadas dentro del bloque _try_ pueden ser
|
||||
// capturados por los siguientes manejadores _catch_.
|
||||
try {
|
||||
// No asignar excepciones en el heap usando _new_.
|
||||
throw std::runtime_error("Ocurrió un problema");
|
||||
}
|
||||
|
||||
// Captura excepciones por referencia const si son objetos
|
||||
catch (const std::exception& ex)
|
||||
{
|
||||
std::cout << ex.what();
|
||||
}
|
||||
********************************************************************************
|
||||
// Captura cualquier excepción no capturada por bloques _catch_ anteriores
|
||||
catch (...)
|
||||
{
|
||||
std::cout << "Excepción desconocida capturada";
|
||||
throw; // Re-lanza la excepción
|
||||
}
|
||||
|
||||
///////
|
||||
// RAII
|
||||
///////
|
||||
|
||||
// RAII significa "Resource Acquisition Is Initialization"
|
||||
// (Adquisición de recursos es inicialización).
|
||||
// A menudo se considera el paradigma más poderoso en C++
|
||||
// Y el concepto es simple: un constructor de un objeto
|
||||
// Adquiere recursos de ese objeto y el destructor les libera.
|
||||
|
||||
// Para entender cómo esto es útil,
|
||||
// Considere una función que utiliza un identificador de archivo C:
|
||||
void doSomethingWithAFile(const char* filename)
|
||||
{
|
||||
// Para empezar, asuma que nada puede fallar.
|
||||
|
||||
FILE* fh = fopen(filename, "r"); // Abre el archivo en modo lectura
|
||||
|
||||
doSomethingWithTheFile(fh);
|
||||
doSomethingElseWithIt(fh);
|
||||
|
||||
fclose(fh); // Cierra el manejador de archivos
|
||||
}
|
||||
|
||||
// Por desgracia, las cosas se complican rápidamente por el control de errores.
|
||||
// Supongamos que fopen puede fallar, y que doSomethingWithTheFile y
|
||||
// DoSomethingElseWithIt retornan códigos de error si fallan.
|
||||
// (Excepciones son la mejor forma de manejar los fallos,
|
||||
// pero algunos programadores, especialmente los que tienen un fondo C,
|
||||
// estan en desacuerdo sobre la utilidad de las excepciones).
|
||||
// Ahora tenemos que comprobar cada llamado por fallos y cerrar el manejador
|
||||
// del archivo si se ha producido un problema.
|
||||
bool doSomethingWithAFile(const char* filename)
|
||||
{
|
||||
FILE* fh = fopen(filename, "r"); // Abre el archivo en modo lectura
|
||||
if (fh == nullptr) // El puntero retornado es nulo o falla.
|
||||
return false; // Reporta el fallo a quien hizo el llamado.
|
||||
|
||||
// Asume que cada función retorna falso si falla
|
||||
if (!doSomethingWithTheFile(fh)) {
|
||||
fclose(fh); // Cierre el manejador de archivo para que no se filtre.
|
||||
return false; // Propaga el error.
|
||||
}
|
||||
if (!doSomethingElseWithIt(fh)) {
|
||||
fclose(fh); // Cierre el manejador de archivo para que no se filtre.
|
||||
return false; // Propaga el error.
|
||||
}
|
||||
|
||||
fclose(fh); // Cierre el archivo.
|
||||
return true; // Indica que todo funcionó correctamente.
|
||||
}
|
||||
|
||||
// Programadores C suelen limpiar esto un poco usando 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); // Cierre el archivo.
|
||||
return true; // Indica que todo funcionó correctamente.
|
||||
|
||||
failure:
|
||||
fclose(fh);
|
||||
return false; // Propagate el error
|
||||
}
|
||||
|
||||
// Si las funciones indican errores mediante excepciones,
|
||||
// Las cosas son un poco más claras, pero pueden optimizarse mas.
|
||||
void doSomethingWithAFile(const char* filename)
|
||||
{
|
||||
FILE* fh = fopen(filename, "r"); // Abrir el archivo en modo lectura
|
||||
if (fh == nullptr)
|
||||
throw std::runtime_error("No puede abrirse el archivo.");
|
||||
|
||||
try {
|
||||
doSomethingWithTheFile(fh);
|
||||
doSomethingElseWithIt(fh);
|
||||
}
|
||||
catch (...) {
|
||||
fclose(fh); // Asegúrese de cerrar el archivo si se produce un error.
|
||||
throw; // Luego vuelve a lanzar la excepción.
|
||||
}
|
||||
|
||||
fclose(fh); // Cierra el archivo
|
||||
}
|
||||
|
||||
// Compare esto con el uso de la clase de flujo de archivos de C++ (fstream)
|
||||
// fstream utiliza su destructor para cerrar el archivo.
|
||||
// Los destructores son llamados automáticamente
|
||||
// cuando un objeto queda fuera del ámbito.
|
||||
void doSomethingWithAFile(const std::string& filename)
|
||||
{
|
||||
// ifstream es la abreviatura de el input file stream
|
||||
std::ifstream fh(filename); // Abre el archivo
|
||||
|
||||
// Hacer algo con el archivo
|
||||
doSomethingWithTheFile(fh);
|
||||
doSomethingElseWithIt(fh);
|
||||
|
||||
} // El archivo se cierra automáticamente aquí por el destructor
|
||||
|
||||
|
||||
// Esto tiene ventajas _enormes_:
|
||||
// 1. No importa lo que pase,
|
||||
// El recurso (en este caso el manejador de archivo) será limpiado.
|
||||
// Una vez que escribes el destructor correctamente,
|
||||
// Es _imposible_ olvidar cerrar el identificador y permitir
|
||||
// fugas del recurso.
|
||||
// 2. Tenga en cuenta que el código es mucho más limpio.
|
||||
// El destructor se encarga de cerrar el archivo detrás de cámaras
|
||||
// Sin que tenga que preocuparse por ello.
|
||||
// 3. El código es seguro.
|
||||
// Una excepción puede ser lanzado en cualquier lugar de la función
|
||||
// y la limpieza ocurrirá.
|
||||
|
||||
// Todo el código idiomático C++ utiliza RAII ampliamente para todos los
|
||||
// recursos.
|
||||
// Otros ejemplos incluyen
|
||||
// - Memoria usando unique_ptr y shared_ptr
|
||||
// - Contenedores (Containers) - la biblioteca estándar linked list,
|
||||
// vector (es decir, array con auto-cambio de tamaño), hash maps, etc.
|
||||
// Destruimos todos sus contenidos de forma automática
|
||||
// cuando quedan fuera del ámbito.
|
||||
// - Mutex utilizando lock_guard y unique_lock
|
||||
|
||||
|
||||
/////////////////////
|
||||
// Cosas divertidas
|
||||
/////////////////////
|
||||
|
||||
// Aspectos de C ++ que pueden sorprender a los recién llegados
|
||||
// (e incluso algunos veteranos).
|
||||
// Esta sección es, por desgracia, salvajemente incompleta;
|
||||
// C++ es uno de los lenguajes con los que mas facil te disparas en el pie.
|
||||
|
||||
// Tu puedes sobreescribir métodos privados!
|
||||
class Foo {
|
||||
virtual void bar();
|
||||
};
|
||||
class FooSub : public Foo {
|
||||
virtual void bar(); // Sobreescribe Foo::bar!
|
||||
};
|
||||
|
||||
|
||||
// 0 == false == NULL (La mayoria de las veces)!
|
||||
bool* pt = new bool;
|
||||
*pt = 0; // Establece los puntos de valor de 'pt' en falso.
|
||||
pt = 0; // Establece 'pt' al apuntador nulo. Ambas lineas compilan sin error.
|
||||
|
||||
// nullptr se supone que arregla un poco de ese tema:
|
||||
int* pt2 = new int;
|
||||
*pt2 = nullptr; // No compila
|
||||
pt2 = nullptr; // Establece pt2 como null.
|
||||
|
||||
// Hay una excepción para los valores bool.
|
||||
// Esto es para permitir poner a prueba punteros nulos con if (!ptr),
|
||||
// pero como consecuencia se puede asignar nullptr a un bool directamente!
|
||||
*pt = nullptr; // Esto todavía compila, a pesar de que '*pt' es un bool!
|
||||
|
||||
// '=' != '=' != '='!
|
||||
// Llama Foo::Foo(const Foo&) o alguna variante (mira movimientos semanticos)
|
||||
// copia del constructor.
|
||||
Foo f2;
|
||||
Foo f1 = f2;
|
||||
|
||||
// Llama Foo::Foo(const Foo&) o variante, pero solo copia el 'Foo' parte de
|
||||
// 'fooSub'. Cualquier miembro extra de 'fooSub' se descarta. Este
|
||||
// comportamiento horrible se llama "Corte de objetos."
|
||||
FooSub fooSub;
|
||||
Foo f1 = fooSub;
|
||||
|
||||
// Llama a Foo::operator=(Foo&) o variantes.
|
||||
Foo f1;
|
||||
f1 = f2;
|
||||
|
||||
|
||||
// Cómo borrar realmente un contenedor:
|
||||
class Foo { ... };
|
||||
vector<Foo> v;
|
||||
for (int i = 0; i < 10; ++i)
|
||||
v.push_back(Foo());
|
||||
// La siguiente línea establece el tamaño de v en 0,
|
||||
// pero los destructores no son llamados y los recursos no se liberan!
|
||||
|
||||
v.empty();
|
||||
v.push_back(Foo()); // Nuevo valor se copia en el primer Foo que insertamos
|
||||
|
||||
// En verdad destruye todos los valores en v.
|
||||
// Consulta la sección acerca de los objetos temporales para la
|
||||
// explicación de por qué esto funciona.
|
||||
v.swap(vector<Foo>());
|
||||
|
||||
```
|
||||
Otras lecturas:
|
||||
|
||||
Una referencia del lenguaje hasta a la fecha se puede encontrar en
|
||||
<http://cppreference.com/w/cpp>
|
||||
|
||||
Recursos adicionales se pueden encontrar en <http://cplusplus.com>
|
@ -11,15 +11,15 @@ lang: es-es
|
||||
---
|
||||
|
||||
Git es un sistema de control de versiones distribuido diseñado para manejar
|
||||
cualquier tipo de proyecto ya sea largos o pequeños, con velocidad y eficiencia.
|
||||
cualquier tipo de proyecto, ya sea largo o pequeño, con velocidad y eficiencia.
|
||||
|
||||
Git realiza esto haciendo "snapshots" del proyecto, con ello permite
|
||||
versionar y administrar nuestro código fuente.
|
||||
|
||||
## Versionamiento, conceptos.
|
||||
|
||||
### Que es el control de versiones?
|
||||
El control de versiones es un sistema que guarda todos los cambios realizados a
|
||||
### Qué es el control de versiones?
|
||||
El control de versiones es un sistema que guarda todos los cambios realizados en
|
||||
uno o varios archivos, a lo largo del tiempo.
|
||||
|
||||
### Versionamiento centralizado vs Versionamiento Distribuido.
|
||||
@ -31,15 +31,15 @@ uno o varios archivos, a lo largo del tiempo.
|
||||
+ El versionamiento distribuido no tiene una estructura definida, incluso se
|
||||
puede mantener el estilo de los repositorios SVN con git.
|
||||
|
||||
[Informacion adicional](http://git-scm.com/book/es/Empezando-Acerca-del-control-de-versiones)
|
||||
[Información adicional](http://git-scm.com/book/es/Empezando-Acerca-del-control-de-versiones)
|
||||
|
||||
### Por que usar Git?
|
||||
### Por qué usar Git?
|
||||
|
||||
* Se puede trabajar sin conexion.
|
||||
* Colaborar con otros es sencillo!.
|
||||
* Derivar, Crear ramas del proyecto (aka: Branching) es facil!.
|
||||
* Derivar, Crear ramas del proyecto (aka: Branching) es fácil!.
|
||||
* Combinar (aka: Merging)
|
||||
* Git es rapido.
|
||||
* Git es rápido.
|
||||
* Git es flexible.
|
||||
|
||||
## Arquitectura de Git.
|
||||
@ -48,10 +48,10 @@ uno o varios archivos, a lo largo del tiempo.
|
||||
|
||||
Un repositorio es un conjunto de archivos, directorios, registros, cambios (aka:
|
||||
comits), y encabezados (aka: heads). Imagina que un repositorio es una clase,
|
||||
y que sus atributos otorgan acceso al historial del elemento, ademas de otras
|
||||
y que sus atributos otorgan acceso al historial del elemento, además de otras
|
||||
cosas.
|
||||
|
||||
Un repositorio esta compuesto por la carpeta .git y un "arbol de trabajo".
|
||||
Un repositorio esta compuesto por la carpeta .git y un "árbol de trabajo".
|
||||
|
||||
### Directorio .git (componentes del repositorio)
|
||||
|
||||
@ -62,38 +62,38 @@ y mas.
|
||||
|
||||
### Directorio de trabajo (componentes del repositorio)
|
||||
|
||||
Es basicamente los directorios y archivos dentro del repositorio. La mayorioa de
|
||||
Es basicamente los directorios y archivos dentro del repositorio. La mayoría de
|
||||
las veces se le llama "directorio de trabajo".
|
||||
|
||||
### Inidice (componentes del directorio .git)
|
||||
### Índice (componentes del directorio .git)
|
||||
|
||||
El inidice es la area de inicio en git. Es basicamente la capa que separa el
|
||||
El índice es el área de inicio en git. Es basicamente la capa que separa el
|
||||
directorio de trabajo, del repositorio en git. Esto otorga a los desarrolladores
|
||||
mas poder sobre lo que envia y recibe en el repositorio.
|
||||
mas poder sobre lo que envía y recibe en el repositorio.
|
||||
|
||||
### Commit (aka: cambios)
|
||||
|
||||
Un commit es una captura de un conjunto de cambios, o modificaciones hechas en
|
||||
el directorio de trabajo. Por ejemplo, si se añaden 5 archivos, se remueven 2,
|
||||
estos cambios se almacenaran en un commit (aka: captura). Este commit puede ser o
|
||||
estos cambios se almacenarán en un commit (aka: captura). Este commit puede ser o
|
||||
no ser enviado (aka: "pusheado") hacia un repositorio.
|
||||
|
||||
### Branch (rama)
|
||||
|
||||
Un "branch", es escencialmente un apuntador hacia el ultimo commit (cambio
|
||||
registrado) que se ha realizado. A medida que se realizan mas commits, este
|
||||
apuntador se actualizara automaticamente hacia el ultimo commit.
|
||||
Un "branch", es escencialmente un apuntador hacia el último commit (cambio
|
||||
registrado) que se ha realizado. A medida que se realizan más commits, este
|
||||
apuntador se actualizará automaticamente hacia el ultimo commit.
|
||||
|
||||
### "HEAD" y "head" (component of .git dir)
|
||||
|
||||
"HEAD" es un apuntador hacia la rama (branch) que se esta utilizando. Un
|
||||
repositorio solo puede tener un HEAD activo. En cambio "head", es un apuntador a
|
||||
cualquier commit realizado, un repositorio puede tener cualquier numero de
|
||||
cualquier commit realizado, un repositorio puede tener cualquier número de
|
||||
"heads".
|
||||
|
||||
### conceptos - recursos.
|
||||
|
||||
* [Git para informaticos](http://eagain.net/articles/git-for-computer-scientists/)
|
||||
* [Git para informáticos](http://eagain.net/articles/git-for-computer-scientists/)
|
||||
* [Git para diseñadores](http://hoth.entp.com/output/git_for_designers.html)
|
||||
|
||||
|
||||
@ -102,8 +102,8 @@ cualquier commit realizado, un repositorio puede tener cualquier numero de
|
||||
|
||||
### init
|
||||
|
||||
Crear un repositorio de git vacio. Las configuraciones, informacion almacenada y
|
||||
demas son almacenadas en el directorio ".git".
|
||||
Crear un repositorio de git vacio. Las configuraciones, información almacenada y
|
||||
demás son almacenadas en el directorio ".git".
|
||||
|
||||
```bash
|
||||
$ git init
|
||||
@ -127,7 +127,7 @@ $ git config --global user.name "nombre"
|
||||
|
||||
### help
|
||||
|
||||
Otorga un accceso rapido a una guia extremadamente detallada de cada comando en
|
||||
Otorga un accceso rápido a una guía extremadamente detallada de cada comando en
|
||||
git. O puede ser usada simplemente como un recordatorio de estos.
|
||||
|
||||
```bash
|
||||
@ -146,7 +146,7 @@ $ git help init
|
||||
|
||||
### status
|
||||
|
||||
Muestra las diferencias entre el archivo indice y el commit al cual apunta el
|
||||
Muestra las diferencias entre el archivo índice y el commit al cual apunta el
|
||||
HEAD actualmente.
|
||||
|
||||
|
||||
@ -163,7 +163,7 @@ $ git help status
|
||||
|
||||
Para añadir archivos al arbol (directorio, repositorio) de trabajo. Si no se
|
||||
utiliza `git add`, los nuevos archivos no se añadiran al arbol de trabajo, por
|
||||
lo que no se incluiran en los commits (cambios).
|
||||
lo que no se incluirán en los commits (cambios).
|
||||
|
||||
```bash
|
||||
# Añade un archivo en el directorio de trabajo actual.
|
||||
@ -202,7 +202,7 @@ $ git branch master --edit-description
|
||||
### checkout
|
||||
|
||||
Actualiza todos los archivos en el directorio de trabajo para que sean igual que
|
||||
las versiones almacenadas en el indice, o en un arbol de trabajo especificado.
|
||||
las versiones almacenadas en el índice, o en un árbol de trabajo especificado.
|
||||
|
||||
```bash
|
||||
# Despachar un repositorio. - Por defecto la master branch. (la rama principal llamada 'master')
|
||||
@ -215,8 +215,8 @@ $ git checkout -b jdei
|
||||
|
||||
### clone
|
||||
|
||||
Clona, o copia, una repo existente en un nuevo directorio. Tambien añada el
|
||||
seguimiento hacia las ramas existentes del repo que ha sido clonada, lo que
|
||||
Clona, o copia, un repositorio existente en un nuevo directorio. También añade el
|
||||
seguimiento hacia las ramas existentes del repositorio que ha sido clonado, lo que
|
||||
permite subir (push) los archivos hacia una rama remota.
|
||||
|
||||
```bash
|
||||
@ -226,8 +226,8 @@ $ git clone https://github.com/jquery/jquery.git
|
||||
|
||||
### commit
|
||||
|
||||
Almacena los cambios que almacenados en el indice en un nuevo "commit". Este
|
||||
commit contiene los cambios hechos mas un resumen hecho por el desarrollador.
|
||||
Almacena el contenido actual del índice en un nuevo "commit". Este
|
||||
commit contiene los cambios hechos más un resumen proporcionado por el desarrollador.
|
||||
|
||||
```bash
|
||||
# commit with a message
|
||||
@ -237,8 +237,8 @@ $ git commit -m "jedi anakin wil be - jedis.list"
|
||||
|
||||
### diff
|
||||
|
||||
Muestra las diferencias entre un archivo en el directorio de trabajo, el indice
|
||||
y commits.
|
||||
Muestra las diferencias entre un archivo en el directorio de trabajo, el índice
|
||||
y los commits.
|
||||
|
||||
```bash
|
||||
# Muestra la diferencia entre un directorio de trabajo y el indice.
|
||||
@ -253,7 +253,7 @@ $ git diff HEAD
|
||||
|
||||
### grep
|
||||
|
||||
Permite realizar una busqueda rapida en un repositorio.
|
||||
Permite realizar una busqueda rápida en un repositorio.
|
||||
|
||||
Configuracion opcionales:
|
||||
|
||||
|
@ -45,7 +45,7 @@ Esto se basa en la versión `0.3.11`.
|
||||
# Los comentarios de una línea comienzan con una almohadilla (o signo de gato).
|
||||
|
||||
#=
|
||||
Los commentarios multilínea pueden escribirse
|
||||
Los comentarios multilínea pueden escribirse
|
||||
usando '#=' antes de el texto y '=#'
|
||||
después del texto. También se pueden anidar.
|
||||
=#
|
||||
@ -174,7 +174,7 @@ otraVariable_123! = 6 # => 6
|
||||
otra_variable
|
||||
|
||||
* Los nombres de los tipos comienzan con una letra mayúscula y separación de
|
||||
palabras se muestra con CamelCase en vez de guion bajo:
|
||||
palabras se muestra con CamelCase en vez de guión bajo:
|
||||
|
||||
OtroTipo
|
||||
|
||||
@ -214,7 +214,7 @@ matrix = [1 2; 3 4]
|
||||
3 4
|
||||
=#
|
||||
|
||||
# Añadir cosas a la final de un arreglo con push! y append!.
|
||||
# Añadir cosas al final de un arreglo con push! y append!.
|
||||
push!(a, 1) # => [1]
|
||||
push!(a, 2) # => [1,2]
|
||||
push!(a, 4) # => [1,2,4]
|
||||
@ -237,7 +237,7 @@ a[end] # => 6
|
||||
shift!(a) # => 1 y a es ahora: [2,4,3,4,5,6]
|
||||
unshift!(a, 7) # => [7,2,4,3,4,5,6]
|
||||
|
||||
# Los nombres de funciónes que terminan en exclamaciones indican que modifican
|
||||
# Los nombres de funciones que terminan en exclamaciones indican que modifican
|
||||
# su o sus argumentos de entrada.
|
||||
arr = [5, 4, 6] # => 3-element Array{Int64,1}: [5,4,6]
|
||||
sort(arr) # => [4,5,6] y arr es todavía: [5,4,6]
|
||||
@ -710,7 +710,7 @@ end
|
||||
# Sólo define una función del mismo nombre que el tipo y llama al constructor
|
||||
# existente para obtener un valor del tipo correcto.
|
||||
|
||||
# Este es un constructor externo porque es fuera de la definición del tipo.
|
||||
# Este es un constructor externo porque está fuera de la definición del tipo.
|
||||
Leon(rugido::String) = Leon("verde", rugido)
|
||||
|
||||
type Pantera <: Gato # Pantera también es un a subtipo de Gato
|
||||
@ -730,10 +730,10 @@ end
|
||||
########################
|
||||
|
||||
# En Julia, todas las funciones nombradas son funciones genéricas.
|
||||
# Esto significa que se construyen a partir de muchos métodosmás pequeños.
|
||||
# Esto significa que se construyen a partir de muchos métodos más pequeños.
|
||||
# Cada constructor de Leon es un método de la función genérica Leon.
|
||||
|
||||
# Por ejemplo, vamos a hacer métodos para para Leon, Pantera, y Tigre de una
|
||||
# Por ejemplo, vamos a hacer métodos para Leon, Pantera, y Tigre de una
|
||||
# función genérica maullar:
|
||||
|
||||
# acceso utilizando notación de puntos
|
||||
|
@ -239,7 +239,8 @@ sur une nouvelle ligne! ""Wow!"", quel style";
|
||||
// Opérateur ternaire
|
||||
// Un simple if/else peut s'écrire :
|
||||
// <condition> ? <valeur si true> : <valeur si false>
|
||||
string isTrue = (true) ? "True" : "False";
|
||||
int toCompare = 17;
|
||||
string isTrue = toCompare == 17 ? "True" : "False";
|
||||
|
||||
// Boucle while
|
||||
int fooWhile = 0;
|
||||
|
@ -15,7 +15,7 @@ Je suis tombé amoureux de Python de par la clarté de sa syntaxe. C'est pratiqu
|
||||
Vos retours sont grandement appréciés. Vous pouvez me contacter sur Twitter [@louiedinh](http://twitter.com/louiedinh) ou par e-mail: louiedinh [at] [google's email service]
|
||||
|
||||
NB: Cet artice s'applique spécifiquement à Python 2.7, mais devrait s'appliquer pour toute version Python 2.x
|
||||
Vous pourrez bientôt trouver un article pour Python 3!
|
||||
Vous pourrez bientôt trouver un article pour Python 3 en Français. Pour le moment vous pouvez jettez un coup d'oeil à l'article [Python 3 en Anglais](http://learnxinyminutes.com/docs/python3/).
|
||||
|
||||
```python
|
||||
# Une ligne simple de commentaire commence par un dièse
|
||||
|
@ -2,6 +2,7 @@
|
||||
language: Hack
|
||||
contributors:
|
||||
- ["Stephen Holdaway", "https://github.com/stecman"]
|
||||
- ["David Lima", "https://github.com/davelima"]
|
||||
filename: learnhack.hh
|
||||
---
|
||||
|
||||
@ -152,7 +153,7 @@ class ArgumentPromotion
|
||||
private bool $isAwesome) {}
|
||||
}
|
||||
|
||||
class WithoutArugmentPromotion
|
||||
class WithoutArgumentPromotion
|
||||
{
|
||||
public string $name;
|
||||
|
||||
@ -169,9 +170,9 @@ class WithoutArugmentPromotion
|
||||
}
|
||||
|
||||
|
||||
// Co-oprerative multi-tasking
|
||||
// Co-operative multi-tasking
|
||||
//
|
||||
// Two new keywords "async" and "await" can be used to perform mutli-tasking
|
||||
// Two new keywords "async" and "await" can be used to perform multi-tasking
|
||||
// Note that this does not involve threads - it just allows transfer of control
|
||||
async function cooperativePrint(int $start, int $end) : Awaitable<void>
|
||||
{
|
||||
|
@ -5,6 +5,7 @@ contributors:
|
||||
- ["João Farias", "https://github.com/JoaoGFarias"]
|
||||
translators:
|
||||
- ["Rizky Luthfianto", "https://github.com/rilut"]
|
||||
lang: id-id
|
||||
---
|
||||
|
||||
XML adalah bahasa markup yang dirancang untuk menyimpan dan mengirim data.
|
||||
|
@ -47,10 +47,30 @@ public class LearnJava {
|
||||
|
||||
|
||||
///////////////////////////////////////
|
||||
// Types & Variables
|
||||
// Variables
|
||||
///////////////////////////////////////
|
||||
|
||||
/*
|
||||
* Variable Declaration
|
||||
*/
|
||||
// Declare a variable using <type> <name>
|
||||
int fooInt;
|
||||
// Declare multiple variables of the same type <type> <name1>, <name2>, <name3>
|
||||
int fooInt1, fooInt2, fooInt3;
|
||||
|
||||
/*
|
||||
* Variable Initialization
|
||||
*/
|
||||
|
||||
// Initialize a variable using <type> <name> = <val>
|
||||
int fooInt = 1;
|
||||
// Initialize multiple variables of same type with same value <type> <name1>, <name2>, <name3> = <val>
|
||||
int fooInt1, fooInt2, fooInt3;
|
||||
fooInt1 = fooInt2 = fooInt3 = 1;
|
||||
|
||||
/*
|
||||
* Variable types
|
||||
*/
|
||||
// Byte - 8-bit signed two's complement integer
|
||||
// (-128 <= byte <= 127)
|
||||
byte fooByte = 100;
|
||||
@ -451,6 +471,74 @@ public class ExampleClass extends ExampleClassParent implements InterfaceOne,
|
||||
public void InterfaceTwoMethod() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Abstract Classes
|
||||
// Abstract Class declaration syntax
|
||||
// <access-level> abstract <abstract-class-name> extends <super-abstract-classes> {
|
||||
// // Constants and variables
|
||||
// // Method declarations
|
||||
// }
|
||||
|
||||
// Methods can't have bodies in an interface, unless the method is
|
||||
// static. Also variables are NOT final by default, unlike an interface.
|
||||
// Also abstract classes CAN have the "main" method.
|
||||
// Abstract classes solve these problems.
|
||||
|
||||
public abstract class Animal
|
||||
{
|
||||
public abstract void makeSound();
|
||||
|
||||
// Method can have a body
|
||||
public void eat()
|
||||
{
|
||||
System.out.println("I am an animal and I am Eating.");
|
||||
// Note: We can access private variable here.
|
||||
age = 30;
|
||||
}
|
||||
|
||||
// No need to initialize, however in an interface
|
||||
// a variable is implicitly final and hence has
|
||||
// to be initialized.
|
||||
private int age;
|
||||
|
||||
public void printAge()
|
||||
{
|
||||
System.out.println(age);
|
||||
}
|
||||
|
||||
// Abstract classes can have main function.
|
||||
public static void main(String[] args)
|
||||
{
|
||||
System.out.println("I am abstract");
|
||||
}
|
||||
}
|
||||
|
||||
class Dog extends Animal
|
||||
{
|
||||
// Note still have to override the abstract methods in the
|
||||
// abstract class.
|
||||
@Override
|
||||
public void makeSound()
|
||||
{
|
||||
System.out.println("Bark");
|
||||
// age = 30; ==> ERROR! age is private to Animal
|
||||
}
|
||||
|
||||
// NOTE: You will get an error if you used the
|
||||
// @Override annotation here, since java doesn't allow
|
||||
// overriding of static methods.
|
||||
// What is happening here is called METHOD HIDING.
|
||||
// Check out this awesome SO post: http://stackoverflow.com/questions/16313649/
|
||||
public static void main(String[] args)
|
||||
{
|
||||
Dog pluto = new Dog();
|
||||
pluto.makeSound();
|
||||
pluto.eat();
|
||||
pluto.printAge();
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Further Reading
|
||||
|
@ -49,7 +49,7 @@ going to be 100% valid JSON. Luckily, it kind of speaks for itself.
|
||||
|
||||
"alternative style": {
|
||||
"comment": "check this out!"
|
||||
, "comma position": "doesn't matter - as long as its before the value, then its valid"
|
||||
, "comma position": "doesn't matter - as long as it's before the value, then it's valid"
|
||||
, "another comment": "how nice"
|
||||
},
|
||||
|
||||
|
@ -160,7 +160,7 @@ def foobar
|
||||
end
|
||||
\`\`\` <!-- here too, no backslashes, just ``` -->
|
||||
|
||||
<-- The above text doesn't require indenting, plus Github will use syntax
|
||||
<!-- The above text doesn't require indenting, plus Github will use syntax
|
||||
highlighting of the language you specify after the ``` -->
|
||||
|
||||
<!-- Horizontal rule (<hr />) -->
|
||||
|
@ -215,6 +215,14 @@ assert($a !== $d);
|
||||
assert(1 === '1');
|
||||
assert(1 !== '1');
|
||||
|
||||
// spaceship operator since PHP 7
|
||||
$a = 100;
|
||||
$b = 1000;
|
||||
|
||||
echo $a <=> $a; // 0 since they are equal
|
||||
echo $a <=> $b; // -1 since $a < $b
|
||||
echo $b <=> $a; // 1 since $b > $a
|
||||
|
||||
// Variables can be converted between types, depending on their usage.
|
||||
|
||||
$integer = 1;
|
||||
@ -264,6 +272,18 @@ if (false) {
|
||||
// ternary operator
|
||||
print (false ? 'Does not get printed' : 'Does');
|
||||
|
||||
// ternary shortcut operator since PHP 5.3
|
||||
// equivalent of "$x ? $x : 'Does'""
|
||||
$x = false;
|
||||
print($x ?: 'Does');
|
||||
|
||||
// null coalesce operator since php 7
|
||||
$a = null;
|
||||
$b = 'Does print';
|
||||
echo $a ?? 'a is not set'; // prints 'a is not set'
|
||||
echo $b ?? 'b is not set'; // prints 'Does print'
|
||||
|
||||
|
||||
$x = 0;
|
||||
if ($x === '0') {
|
||||
print 'Does not print';
|
||||
|
316
pt-br/hack-pt.html.markdown
Normal file
316
pt-br/hack-pt.html.markdown
Normal file
@ -0,0 +1,316 @@
|
||||
---
|
||||
language: Hack
|
||||
contributors:
|
||||
- ["Stephen Holdaway", "https://github.com/stecman"]
|
||||
- ["David Lima", "https://github.com/davelima"]
|
||||
translators:
|
||||
- ["David Lima", "https://github.com/davelima"]
|
||||
lang: pt-br
|
||||
filename: learnhack-pt.hh
|
||||
---
|
||||
|
||||
Hack é uma linguagem baseada no PHP e roda numa máquina virtual chamada HHVM.
|
||||
Hack é quase completamente interoperável com códigos PHP existentes e adiciona
|
||||
alguns recursos úteis de linguagens estaticamente tipadas.
|
||||
|
||||
Somente recursos específicos da linguagem Hack serão abordados aqui. Detalhes
|
||||
sobre a sintaxe do PHP estão disponíveis no
|
||||
[artigo PHP](http://learnxinyminutes.com/docs/php/) neste site.
|
||||
|
||||
```php
|
||||
<?hh
|
||||
|
||||
// A sintaxe do Hack é ativada apenas em arquivos que comecem com <?hh
|
||||
// Marcadores <?hh não podem ser incluídos em páginas HTML, diferente de <?php.
|
||||
// Usar o marcador "<?hh //strict" coloca o verificador de tipo no modo estrito.
|
||||
|
||||
|
||||
// Indução de tipo de parâmetros escalares
|
||||
function repeat(string $palavra, int $contagem)
|
||||
{
|
||||
$palavra = trim($palavra);
|
||||
return str_repeat($palavra . ' ', $contagem);
|
||||
}
|
||||
|
||||
// Indução de tipo para valores de retorno
|
||||
function add(...$numeros) : int
|
||||
{
|
||||
return array_sum($numeros);
|
||||
}
|
||||
|
||||
// Funções que não retornam nada são induzidas com "void"
|
||||
function truncate(resource $recurso) : void
|
||||
{
|
||||
// ...
|
||||
}
|
||||
|
||||
// Induções de tipo devem permitir nulos de forma explícita
|
||||
function identity(?string $stringOuNulo) : ?string
|
||||
{
|
||||
return $stringOuNulo;
|
||||
}
|
||||
|
||||
// Induções de tipo podem ser especificadas em propriedades de classes
|
||||
class PropriedadesComTipos
|
||||
{
|
||||
public ?string $nome;
|
||||
|
||||
protected int $id;
|
||||
|
||||
private float $pontuacao = 100.0;
|
||||
|
||||
// O verificador de tipos do Hack reforça que propriedades tipadas devem
|
||||
// ter um valor padrão ou devem ser definidos no construtor
|
||||
public function __construct(int $id)
|
||||
{
|
||||
$this->id = $id;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Funções anônimas (lambdas)
|
||||
$multiplicador = 5;
|
||||
array_map($y ==> $y * $multiplicador, [1, 2, 3]);
|
||||
|
||||
|
||||
// Genéricos
|
||||
class Caixa<T>
|
||||
{
|
||||
protected T $dados;
|
||||
|
||||
public function __construct(T $dados) {
|
||||
$this->dados = $dados;
|
||||
}
|
||||
|
||||
public function pegaDados(): T {
|
||||
return $this->dados;
|
||||
}
|
||||
}
|
||||
|
||||
function abreCaixa(Caixa<int> $caixa) : int
|
||||
{
|
||||
return $caixa->pegaDados();
|
||||
}
|
||||
|
||||
|
||||
// Formas
|
||||
//
|
||||
// Hack adiciona o conceito de formas para definir arrays com uma estrutura
|
||||
// e tipos de dados garantidos
|
||||
type Point2D = shape('x' => int, 'y' => int);
|
||||
|
||||
function distancia(Point2D $a, Point2D $b) : float
|
||||
{
|
||||
return sqrt(pow($b['x'] - $a['x'], 2) + pow($b['y'] - $a['y'], 2));
|
||||
}
|
||||
|
||||
distancia(
|
||||
shape('x' => -1, 'y' => 5),
|
||||
shape('x' => 2, 'y' => 50)
|
||||
);
|
||||
|
||||
|
||||
// Pseudônimos de tipos
|
||||
//
|
||||
// Hack adiciona vários recursos para criação de pseudônimos, tornando tipos complexos
|
||||
// mais fáceis de entender
|
||||
newtype VectorArray = array<int, Vector<int>>;
|
||||
|
||||
// Um tuple contendo dois inteiros
|
||||
newtype Point = (int, int);
|
||||
|
||||
function adicionaPontos(Point $p1, Point $p2) : Point
|
||||
{
|
||||
return tuple($p1[0] + $p2[0], $p1[1] + $p2[1]);
|
||||
}
|
||||
|
||||
adicionaPontos(
|
||||
tuple(1, 2),
|
||||
tuple(5, 6)
|
||||
);
|
||||
|
||||
|
||||
// enums em classes
|
||||
enum TipoDePista : int
|
||||
{
|
||||
Estrada = 0;
|
||||
Rua = 1;
|
||||
Alameda = 2;
|
||||
Avenida = 3;
|
||||
}
|
||||
|
||||
function getTipoDePista() : TipoDePista
|
||||
{
|
||||
return TipoDePista::Alameda;
|
||||
}
|
||||
|
||||
|
||||
// Especificação de argumentos no construtor (Argument Promotion)
|
||||
//
|
||||
// Para evitar que propriedades sejam definidas em mais de um lugar, e
|
||||
// construtores que só definem propriedades, o Hack adiciona uma sintaxe para
|
||||
// definir as propriedades e o construtor ao mesmo tempo.
|
||||
class ArgumentPromotion
|
||||
{
|
||||
public function __construct(public string $nome,
|
||||
protected int $idade,
|
||||
private bool $legal) {}
|
||||
}
|
||||
|
||||
class SemArgumentPromotion
|
||||
{
|
||||
public string $nome;
|
||||
|
||||
protected int $idade;
|
||||
|
||||
private bool $legal;
|
||||
|
||||
public function __construct(string $nome, int $idade, bool $legal)
|
||||
{
|
||||
$this->nome = $nome;
|
||||
$this->idade = $idade;
|
||||
$this->legal = $legal;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Multi-tarefas cooperativo
|
||||
//
|
||||
// Duas novas palavras-chave ("async" e "await") podem ser usadas para
|
||||
// trabalhar com multi-tarefas.
|
||||
// Obs. Isto não envolve threads - apenas permite a transferência de controle
|
||||
async function printCooperativo(int $inicio, int $fim) : Awaitable<void>
|
||||
{
|
||||
for ($i = $inicio; $i <= $fim; $i++) {
|
||||
echo "$i ";
|
||||
|
||||
// Permite que outras tarefas façam algo
|
||||
await RescheduleWaitHandle::create(RescheduleWaitHandle::QUEUE_DEFAULT, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Imprime "1 4 7 2 5 8 3 6 9"
|
||||
AwaitAllWaitHandle::fromArray([
|
||||
printCooperativo(1, 3),
|
||||
printCooperativo(4, 6),
|
||||
printCooperativo(7, 9)
|
||||
])->getWaitHandle()->join();
|
||||
|
||||
|
||||
// Atributos
|
||||
//
|
||||
// Atributos são uma forma de definir metadados para funções.
|
||||
// Hack tem alguns atributos especiais que possuem comportamentos úteis.
|
||||
|
||||
// O atributo especial __Memoize faz com que o resultado da função fique em cache
|
||||
<<__Memoize>>
|
||||
function tarefaDemorada() : ?string
|
||||
{
|
||||
return file_get_contents('http://exemplo.com');
|
||||
}
|
||||
|
||||
// O corpo da função só é executado uma vez aqui:
|
||||
tarefaDemorada();
|
||||
tarefaDemorada();
|
||||
|
||||
|
||||
// O atributo especial __ConsistentConstruct faz com que o Hack certifique-se
|
||||
// de que a assinatura do construtor seja a mesma em todas as subclasses
|
||||
<<__ConsistentConstruct>>
|
||||
class FooConsistente
|
||||
{
|
||||
public function __construct(int $x, float $y)
|
||||
{
|
||||
// ...
|
||||
}
|
||||
|
||||
public function algumMetodo()
|
||||
{
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
class BarConsistente extends FooConsistente
|
||||
{
|
||||
public function __construct(int $x, float $y)
|
||||
{
|
||||
// O verificador de tipos do Hack exige que os construtores pai
|
||||
// sejam chamados
|
||||
parent::__construct($x, $y);
|
||||
|
||||
// ...
|
||||
}
|
||||
|
||||
// A anotação __Override é uma anotação opcional que faz com que o
|
||||
// verificador de tipos do Hack sobrescreva um método em uma classe pai
|
||||
// ou um trait. Sem __Override, definir este método causará um erro,
|
||||
// pois ele já foi definido na classe pai (FooConsistente):
|
||||
<<__Override>>
|
||||
public function algumMetodo()
|
||||
{
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
class SubclasseFooInvalida extends FooConsistente
|
||||
{
|
||||
// Caso o construtor não combine com o construtor da classe pai, o
|
||||
// verificador de tipos acusará um erro:
|
||||
//
|
||||
// "Este objeto é incompatível com o objeto FooConsistente porque algum(ns)
|
||||
// dos seus métodos são incompatíveis"
|
||||
//
|
||||
public function __construct(float $x)
|
||||
{
|
||||
// ...
|
||||
}
|
||||
|
||||
// Usar a anotação __Override em um método que não existe na classe pai
|
||||
// causará um erro do verificador de tipos:
|
||||
// "SubclasseFooInvalida::outroMetodo() está marcada para sobrescrever;
|
||||
// nenhuma definição não-privada foi encontrada ou a classe pai foi
|
||||
// definida em código não-<?hh"
|
||||
//
|
||||
<<__Override>>
|
||||
public function outroMetodo()
|
||||
{
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Traits podem implementar interfaces (não suportado pelo PHP)
|
||||
interface InterfaceGatinho
|
||||
{
|
||||
public function brinca() : void;
|
||||
}
|
||||
|
||||
trait TraitGato implements InterfaceGatinho
|
||||
{
|
||||
public function brinca() : void
|
||||
{
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
class Samuel
|
||||
{
|
||||
use TraitGato;
|
||||
}
|
||||
|
||||
|
||||
$gato = new Samuel();
|
||||
$gato instanceof InterfaceGatinho === true; // True
|
||||
|
||||
```
|
||||
|
||||
## Mais informações
|
||||
|
||||
Visite a [documentação do Hack](http://docs.hhvm.com/manual/en/hacklangref.php)
|
||||
para ver explicações detalhadas dos recursos que Hack adiciona ao PHP, ou o [site oficial do Hack](http://hanlang.org/)
|
||||
para outras informações.
|
||||
|
||||
Visite o [site oficial do HHVM](http://hhvm.com/) para aprender a instalar o HHVM.
|
||||
|
||||
Visite [este artigo](http://docs.hhvm.com/manual/en/hack.unsupported.php) para ver
|
||||
os recursos do PHP que o Hack não suporta e ver incompatibilidades entre Hack e PHP.
|
547
pt-br/javascript-pt.html.markdown
Normal file
547
pt-br/javascript-pt.html.markdown
Normal file
@ -0,0 +1,547 @@
|
||||
---
|
||||
language: javascript
|
||||
contributors:
|
||||
- ["Adam Brenecki", "http://adam.brenecki.id.au"]
|
||||
- ["Ariel Krakowski", "http://www.learneroo.com"]
|
||||
translators:
|
||||
- ["Willian Justen", "http://willianjusten.com.br"]
|
||||
lang: pt-br
|
||||
---
|
||||
|
||||
JavaScript foi criada por Brendan Eich, funcionário da Netscape na época, em 1995. Ela
|
||||
foi originalmente criada para ser uma linguagem de script para websites,
|
||||
complementando o uso de Java para aplicações web mais complexas, mas a sua
|
||||
integração com páginas web e seu suporte nativo nos browsers fez com que
|
||||
ela se tornasse mais comum que Java no frontend web.
|
||||
|
||||
Javascript não é somente limitada a browsers web, existindo o Node.js,
|
||||
que é um projeto que fornece um interpretador baseado no motor V8 do Google
|
||||
Chrome e está se tornando cada vez mais famoso.
|
||||
|
||||
Feedback são muito apreciados! Você me encontrar em
|
||||
[@adambrenecki](https://twitter.com/adambrenecki), ou
|
||||
[adam@brenecki.id.au](mailto:adam@brenecki.id.au).
|
||||
|
||||
```js
|
||||
// Comentários são como em C. Comentários de uma linha começam com duas barras,
|
||||
/* e comentários de múltplas linhas começam com barra-asterisco
|
||||
e fecham com asterisco-barra */
|
||||
|
||||
// comandos podem ser terminados com ;
|
||||
facaAlgo();
|
||||
|
||||
// ... mas eles não precisam ser, o ponto-e-vírgula é automaticamente
|
||||
// inserido quando há uma nova linha, exceto alguns casos.
|
||||
facaAlgo()
|
||||
|
||||
// Como esses casos podem causar resultados inesperados, vamos continuar
|
||||
// a usar ponto-e-vírgula neste guia.
|
||||
|
||||
///////////////////////////////////
|
||||
// 1. Números, Strings e Operadores
|
||||
|
||||
// Javascript tem um tipo de número (que é o 64-bit IEEE 754 double).
|
||||
// Doubles tem uma mantissa 52-bit, que é suficiente para guardar inteiros
|
||||
// acima de 9✕10¹⁵ precisamente.
|
||||
3; // = 3
|
||||
1.5; // = 1.5
|
||||
|
||||
// A aritmética básica funciona como seria de se esperar.
|
||||
1 + 1; // = 2
|
||||
0.1 + 0.2; // = 0.30000000000000004
|
||||
8 - 1; // = 7
|
||||
10 * 2; // = 20
|
||||
35 / 5; // = 7
|
||||
|
||||
// Inclusive divisão desigual.
|
||||
5 / 2; // = 2.5
|
||||
|
||||
// Operadores Bitwise também funcionam; quando você faz uma operação bitwise
|
||||
// seu float é convertido para um int de até 32 bits.
|
||||
1 << 2; // = 4
|
||||
|
||||
// A precedência é aplicada com parênteses.
|
||||
(1 + 3) * 2; // = 8
|
||||
|
||||
// Existem três especiais valores não-é-número-real:
|
||||
Infinity; // resultado de 1/0
|
||||
-Infinity; // resultado de -1/0
|
||||
NaN; // resultado de 0/0
|
||||
|
||||
// Existe também o tipo booleano.
|
||||
true;
|
||||
false;
|
||||
|
||||
// Strings são criados com ' ou ".
|
||||
'abc';
|
||||
"Olá, mundo";
|
||||
|
||||
// Negação usa o símbolo !
|
||||
!true; // = false
|
||||
!false; // = true
|
||||
|
||||
// Igualdade é o sinal de ===
|
||||
1 === 1; // = true
|
||||
2 === 1; // = false
|
||||
|
||||
// Desigualdade é o sinal de !==
|
||||
1 !== 1; // = false
|
||||
2 !== 1; // = true
|
||||
|
||||
// Mais comparações
|
||||
1 < 10; // = true
|
||||
1 > 10; // = false
|
||||
2 <= 2; // = true
|
||||
2 >= 2; // = true
|
||||
|
||||
// Strings são concatenadas com +
|
||||
"Olá " + "mundo!"; // = "Olá mundo!"
|
||||
|
||||
// e comparadas com < e >
|
||||
"a" < "b"; // = true
|
||||
|
||||
// A comparação de tipos não é feita com o uso de ==...
|
||||
"5" == 5; // = true
|
||||
null == undefined; // = true
|
||||
|
||||
// ...a menos que use ===
|
||||
"5" === 5; // = false
|
||||
null === undefined; // = false
|
||||
|
||||
// ...isso pode resultar em comportamentos estranhos...
|
||||
13 + !0; // 14
|
||||
"13" + !0; // '13true'
|
||||
|
||||
// Você pode acessar caracteres de uma String usando o `charAt`
|
||||
"Isto é uma String".charAt(0); // = 'I'
|
||||
|
||||
// ...ou usar `substring` para pegar pedaços maiores.
|
||||
"Olá mundo".substring(0, 3); // = "Olá"
|
||||
|
||||
// `length` é uma propriedade, portanto não use ().
|
||||
"Olá".length; // = 3
|
||||
|
||||
// Existe também o `null` e o `undefined`.
|
||||
null; // usado para indicar um valor não considerado
|
||||
undefined; // usado para indicar um valor que não é a atualmente definido
|
||||
// (entretando `undefined` é considerado de fato um valor
|
||||
|
||||
// false, null, undefined, NaN, 0 and "" são valores falsos;
|
||||
// qualquer outro valor é verdadeiro
|
||||
// Note que 0 é falso e "0" é verdadeiro, até mesmo 0 == "0".
|
||||
|
||||
///////////////////////////////////
|
||||
// 2. Variáveis, Arrays e Objetos
|
||||
|
||||
// Variáveis são declaradas com a palavra-chave `var`. O Javascript é
|
||||
// dinâmicamente tipado, portanto você não precisa especificar o tipo.
|
||||
// Atribuições usam um simples caracter de `=`.
|
||||
var someVar = 5;
|
||||
|
||||
// se você deixar de colocar a palavra-chave var, você não irá receber um erro...
|
||||
someOtherVar = 10;
|
||||
|
||||
// ...mas sua variável será criada no escopo global, não no escopo em que você
|
||||
// definiu ela.
|
||||
|
||||
// Variáveis declaradas sem receberem um valor são definidas como `undefined`.
|
||||
var someThirdVar; // = undefined
|
||||
|
||||
// Existe um shorthand para operações matemáticas em variáveis:
|
||||
someVar += 5; // equivalente a someVar = someVar + 5; someVar é 10 agora
|
||||
someVar *= 10; // agora someVar é 100
|
||||
|
||||
// e um para adição e subtração de 1
|
||||
someVar++; // agora someVar é 101
|
||||
someVar--; // volta para 100
|
||||
|
||||
// Arrays são listas ordenadas de valores, de qualquer tipo.
|
||||
var myArray = ["Olá", 45, true];
|
||||
|
||||
// Seus membros podem ser acessados usando a sintaxe de colchetes.
|
||||
// O indíce de um Array começa pelo 0.
|
||||
myArray[1]; // = 45
|
||||
|
||||
// Arrays são mutáveis e de tamanho variável.
|
||||
myArray.push("World");
|
||||
myArray.length; // = 4
|
||||
|
||||
// Adicionar/modificar em um índice específico
|
||||
myArray[3] = "Hello";
|
||||
|
||||
// Objetos de Javascript são equivalentes aos dicionários ou maps de outras
|
||||
// linguagens: uma coleção não ordenada de pares chave-valor.
|
||||
var myObj = {chave1: "Olá", chave2: "Mundo"};
|
||||
|
||||
// Chaves são strings, mas as aspas não são necessárias se elas são
|
||||
// identificadores válidos no Javascript. Valores podem ser de qualquer tipo.
|
||||
var myObj = {myKey: "myValue", "my other key": 4};
|
||||
|
||||
// Atributos de objetos também podem ser acessados com a sintaxe de colchetes.
|
||||
myObj["my other key"]; // = 4
|
||||
|
||||
// ... ou usando a sintaxe de ponto, passando a chave que é um identificador
|
||||
// válido.
|
||||
myObj.myKey; // = "myValue"
|
||||
|
||||
// Objetos são mutáveis, valores podem ser modificados e novas chaves
|
||||
// adicionadas.
|
||||
myObj.myThirdKey = true;
|
||||
|
||||
// Se você tentar acessar um valor que não foi determinado ainda, você irá
|
||||
// receber `undefined`.
|
||||
myObj.myFourthKey; // = undefined
|
||||
|
||||
///////////////////////////////////
|
||||
// 3. Lógica e Estruturas de Controle
|
||||
|
||||
// A sintaxe para essa seção é quase idêntica a maioria das linguagens.
|
||||
|
||||
// The `if` structure works as you'd expect.
|
||||
// A estrutura `if` funciona como deveria ser.
|
||||
var count = 1
|
||||
if (count == 3){
|
||||
// executa se count é 3
|
||||
} else if (count == 4){
|
||||
// executa se count é 4
|
||||
} else {
|
||||
// executa se count não é 3 nem 4
|
||||
}
|
||||
|
||||
// Como se faz um `while`.
|
||||
while (true){
|
||||
// Um loop infinito!
|
||||
}
|
||||
|
||||
// Os loops do-while são como os loops de while, exceto quando eles sempre
|
||||
// executam pelo menos uma vez.
|
||||
do {
|
||||
input = getInput();
|
||||
} while (!isValid(input))
|
||||
|
||||
// The `for` loop is the same as C and Java:
|
||||
// initialisation; continue condition; iteration.
|
||||
|
||||
// O loop `for` é o mesmo de C e Java:
|
||||
// inicialização, condição para continuar; iteração
|
||||
for (var i = 0; i < 5; i++){
|
||||
// vai rodar cinco vezes
|
||||
}
|
||||
|
||||
// && é o `e` lógico , || é o `ou` lógico
|
||||
if (house.size == "big" && house.colour == "blue"){
|
||||
house.contains = "bear";
|
||||
}
|
||||
if (cor == "red" || cor == "blue"){
|
||||
// cor é vermelha OU azul
|
||||
}
|
||||
|
||||
// && e || "pequeno circuito", é útil para determinar valores padrões.
|
||||
var name = otherName || "padrão";
|
||||
|
||||
// O `switch` checa pela igualdade com `===`.
|
||||
// Use `break` após cada `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. Funções, Escopos e Closures
|
||||
|
||||
// Funções Javascript são declaradas com a palavra-chave `function`.
|
||||
function myFunction(thing){
|
||||
return thing.toUpperCase();
|
||||
}
|
||||
myFunction("foo"); // = "FOO"
|
||||
|
||||
// Repare que o valor a ser retornado deve começar na mesma linha que
|
||||
// a palavra-chave `return`, senão você sempre irá retornar `undefined`
|
||||
// visto que o ponto-e-vírgula é inserido automáticamente nas quebras de
|
||||
// linha. Preste atenção quando usar o estilo Allman.
|
||||
function myFunction()
|
||||
{
|
||||
return // <- ponto-e-vírgula adicionado automaticamente aqui
|
||||
{
|
||||
thisIsAn: 'object literal'
|
||||
}
|
||||
}
|
||||
myFunction(); // = undefined
|
||||
|
||||
// Funções Javascript são objetos de primeira classe, portanto elas podem
|
||||
// ser atribuídas a nomes de variáveis e serem passadas para outras funções
|
||||
// como argumentos - por exemplo, quando criamos um manipulador de eventos:
|
||||
function myFunction(){
|
||||
// este código será chamado em 5 segundos
|
||||
}
|
||||
setTimeout(myFunction, 5000);
|
||||
// Nota: `setTimeout` não é parte da linguagem Javascript, mas é provido pelos
|
||||
// browsers e o Node.js.
|
||||
|
||||
// Objetos de funções não precisam nem serem declarados com nome - você pode
|
||||
// escrever a definição de uma função anônima diretamente nos argumentos de
|
||||
// outra função.
|
||||
setTimeout(function(){
|
||||
// este código será chamado em 5 segundos
|
||||
}, 5000);
|
||||
|
||||
// O Javascript tem escopo de função; as funções tem seu próprio escopo,
|
||||
// mas outros blocos não.
|
||||
if (true){
|
||||
var i = 5;
|
||||
}
|
||||
i; // = 5 - não `undefined` como você esperaria numa linguagem de blogo-escopo
|
||||
|
||||
// Isso levou a padrão comum chamado de IIFE (Imediately Invoked Function
|
||||
// Expression) ou (Expressão de Função Invocada Imediatamente), que previne
|
||||
// que variáveis temporárias vazem para o escopo global.
|
||||
(function(){
|
||||
var temporary = 5;
|
||||
// Nós podemos acessar o escopo global definindo o "objeto global", que
|
||||
// no browser vai ser sempre `window`. O objeto global pode ter um nome
|
||||
// diferente para ambiente não-browser como o Node.js.
|
||||
window.permanent = 10;
|
||||
})();
|
||||
temporary; // levanta um erro de referência inexiste
|
||||
permanent; // = 10
|
||||
|
||||
// Uma das principais características do Javascript é a closure. Que é
|
||||
// uma função definida dentro de outra função, a função interna pode acessar
|
||||
// todas as variáveis da função externa, mesmo depois da função de fora
|
||||
// finalizar sua execução.
|
||||
function sayHelloInFiveSeconds(name){
|
||||
var prompt = "Hello, " + name + "!";
|
||||
|
||||
// Funções internas são colocadas no escopo local por padrão, assim como
|
||||
// se fossem declaradas com `var`.
|
||||
function inner(){
|
||||
alert(prompt);
|
||||
}
|
||||
setTimeout(inner, 5000);
|
||||
// `setTimeout` é assíncrono, portanto a função `sayHelloInFiveSeconds`
|
||||
// vai sair imediatamente, e o `setTimeout` irá chamar a interna depois.
|
||||
// Entretanto. como a interna é fechada dentro de "sayHelloInFiveSeconds",
|
||||
// a interna permanece podendo acessar a variável `prompt` quando depois
|
||||
// de chamada.
|
||||
}
|
||||
sayHelloInFiveSeconds("Adam"); // Vai abrir um popup com "Hello, Adam!" em 5s
|
||||
|
||||
///////////////////////////////////
|
||||
// 5. Mais sobre Objetos; Construtores e Prototypes
|
||||
|
||||
// Objetos podem conter funções.
|
||||
var myObj = {
|
||||
myFunc: function(){
|
||||
return "Olá mundo!";
|
||||
}
|
||||
};
|
||||
myObj.myFunc(); // = "Olá mundo!"
|
||||
|
||||
// Quando uma função ligada a um objeto é chamada, ela pode acessar o objeto
|
||||
// da qual foi ligada usando a palavra-chave `this`.
|
||||
myObj = {
|
||||
myString: "Olá mundo!",
|
||||
myFunc: function(){
|
||||
return this.myString;
|
||||
}
|
||||
};
|
||||
myObj.myFunc(); // = "Olá mundo!"
|
||||
|
||||
// O `this` só funciona para dentro do escopo do objeto, portanto, se chamarmos
|
||||
// um método do objeto fora de seu escopo, este não irá funcionar.
|
||||
var myFunc = myObj.myFunc;
|
||||
myFunc(); // = undefined
|
||||
|
||||
// Inversamente, uma função pode ser atribuída a um objeto e ganhar a acesso
|
||||
// através do `this`, até mesmo se ela não for chamada quando foi definida.
|
||||
var myOtherFunc = function(){
|
||||
return this.myString.toUpperCase();
|
||||
}
|
||||
myObj.myOtherFunc = myOtherFunc;
|
||||
myObj.myOtherFunc(); // = "OLÁ MUNDO!"
|
||||
|
||||
// Nós podemos também especificar um contexto onde a função irá executar,
|
||||
// usando o `call` ou `apply`.
|
||||
|
||||
var anotherFunc = function(s){
|
||||
return this.myString + s;
|
||||
}
|
||||
anotherFunc.call(myObj, " E Olá Lua!"); // = "Olá mundo! E Olá Lua!"
|
||||
|
||||
// A função `apply` é praticamente a mesma coisa, mas ela pega um array
|
||||
// como lista de argumentos.
|
||||
|
||||
anotherFunc.apply(myObj, [" E Olá Sol!"]); // = "Olá mundo! E Olá Sol!"
|
||||
|
||||
// Isto é util quando trabalhamos com uma função que aceita uma sequência de
|
||||
// argumentos e você quer passar um array.
|
||||
|
||||
Math.min(42, 6, 27); // = 6
|
||||
Math.min([42, 6, 27]); // = NaN (uh-oh!)
|
||||
Math.min.apply(Math, [42, 6, 27]); // = 6
|
||||
|
||||
// Mas, o `call` e `apply` são somente temporários. Quando você quiser que
|
||||
// permaneça sempre no escopo, use `bind`.
|
||||
|
||||
var boundFunc = anotherFunc.bind(myObj);
|
||||
boundFunc(" E Olá Saturno!"); // = "Olá mundo! E Olá Saturno!"
|
||||
|
||||
// `bind` também pode ser usado para parcialmente aplicar (curry) uma função.
|
||||
|
||||
var product = function(a, b){ return a * b; }
|
||||
var doubler = product.bind(this, 2);
|
||||
doubler(8); // = 16
|
||||
|
||||
// Quando você invoca uma função com a palavra-chave `new`, um novo objeto
|
||||
// é criado, e fica disponível para a função pela palavra-chave `this`.
|
||||
// Funções são desenhadas para serem invocadas como se invocam os construtores.
|
||||
|
||||
var MyConstructor = function(){
|
||||
this.myNumber = 5;
|
||||
}
|
||||
myNewObj = new MyConstructor(); // = {myNumber: 5}
|
||||
myNewObj.myNumber; // = 5
|
||||
|
||||
// Todo objeto JavaScript possui um `prototype`. Quando você tenta acessar
|
||||
// uma propriedade de um objeto que não existe no objeto atual, o interpretador
|
||||
// vai olhar imediatamente para o seu prototype.
|
||||
|
||||
// Algumas implementações em JS deixam você acessar o objeto prototype com a
|
||||
// propriedade mágica `__proto__`. Enquanto isso é util para explicar
|
||||
// prototypes, não é parte de um padrão; nós vamos falar de algumas formas de
|
||||
// usar prototypes depois.
|
||||
|
||||
var myObj = {
|
||||
myString: "Olá Mundo!"
|
||||
};
|
||||
var myPrototype = {
|
||||
meaningOfLife: 42,
|
||||
myFunc: function(){
|
||||
return this.myString.toLowerCase()
|
||||
}
|
||||
};
|
||||
|
||||
myObj.__proto__ = myPrototype;
|
||||
myObj.meaningOfLife; // = 42
|
||||
|
||||
// This works for functions, too.
|
||||
// Isto funciona para funções, também.
|
||||
myObj.myFunc(); // = "olá mundo!"
|
||||
|
||||
// É claro, se sua propriedade não está em seu prototype,
|
||||
// o prototype do prototype será procurado e por aí vai.
|
||||
myPrototype.__proto__ = {
|
||||
myBoolean: true
|
||||
};
|
||||
myObj.myBoolean; // = true
|
||||
|
||||
// Não há cópia envolvida aqui; cada objeto guarda uma referência do
|
||||
// prototype. Isso significa que podemos alterar o prototype e nossas mudanças
|
||||
// serão refletidas em qualquer lugar.
|
||||
myPrototype.meaningOfLife = 43;
|
||||
myObj.meaningOfLife; // = 43
|
||||
|
||||
|
||||
// Nós mencionamos que o `__proto__` não é uma forma padrão, e não há uma
|
||||
// forma padrão de mudar o prototype de um objeto já existente. Entretanto,
|
||||
// existem duas formas de se criar um objeto com um dado prototype.
|
||||
|
||||
// A primeira forma é `Object.create`, que é uma adição recente do JS,
|
||||
// e ainda não está disponível em todas as implementações.
|
||||
var myObj = Object.create(myPrototype);
|
||||
myObj.meaningOfLife; // = 43
|
||||
|
||||
// A segunda forma, que funciona em qualquer lugar, é feita com construtores.
|
||||
// Construtores tem uma propriedade chamada prototype. Este *não* é o prototype
|
||||
// do construtor em si; ao invés disso, ele é o prototype dos novos objetos
|
||||
// criados pelo construtor.
|
||||
MyConstructor.prototype = {
|
||||
myNumber: 5,
|
||||
getMyNumber: function(){
|
||||
return this.myNumber;
|
||||
}
|
||||
};
|
||||
var myNewObj2 = new MyConstructor();
|
||||
myNewObj2.getMyNumber(); // = 5
|
||||
myNewObj2.myNumber = 6
|
||||
myNewObj2.getMyNumber(); // = 6
|
||||
|
||||
// Tipos originais da linguagem como strings e números também possuem
|
||||
// construtores equivalentes.
|
||||
var myNumber = 12;
|
||||
var myNumberObj = new Number(12);
|
||||
myNumber == myNumberObj; // = true
|
||||
|
||||
// Exceto, que eles não são totalmente equivalentes.
|
||||
typeof myNumber; // = 'number'
|
||||
typeof myNumberObj; // = 'object'
|
||||
myNumber === myNumberObj; // = false
|
||||
if (0){
|
||||
// O código não vai executar, porque 0 é um valor falso.
|
||||
}
|
||||
|
||||
// Entretanto, esses objetos encapsulados e as funções originais compartilham
|
||||
// um mesmo prototype, portanto você pode adicionar funcionalidades a uma string,
|
||||
// por exemplo.
|
||||
String.prototype.firstCharacter = function(){
|
||||
return this.charAt(0);
|
||||
}
|
||||
"abc".firstCharacter(); // = "a"
|
||||
|
||||
// Esse fato é usado para criar os chamados `polyfills`, que implementam
|
||||
// uma nova característica do Javascript em uma versão mais velha, para que
|
||||
// assim funcionem em ambientes mais velhos como browsers ultrapassados.
|
||||
|
||||
// Havíamos mencionado que `Object.create` não estava ainda disponível em
|
||||
// todos as implementações, mas nós podemos usá-lo com esse polyfill:
|
||||
if (Object.create === undefined){ // don't overwrite it if it exists
|
||||
Object.create = function(proto){
|
||||
// faz um construtor temporário com o prototype certo
|
||||
var Constructor = function(){};
|
||||
Constructor.prototype = proto;
|
||||
// então utiliza o new para criar um objeto prototype apropriado
|
||||
return new Constructor();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Leitura Adicional
|
||||
|
||||
O [Mozilla Developer
|
||||
Network](https://developer.mozilla.org/en-US/docs/Web/JavaScript) dispõe de uma
|
||||
excelente documentação sobre Javascript e seu uso nos browsers. E mais,
|
||||
é uma wiki, portanto conforme você vai aprendendo, mais você pode ir ajudando
|
||||
os outros compartilhando do seu conhecimento.
|
||||
|
||||
[Uma re-introdução do JavaScript pela MDN]
|
||||
(https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript)
|
||||
cobre muito dos conceitos abordados aqui em mais detalhes. Este guia fala
|
||||
somente sobre a linguagem JavaScript em si; se você quiser aprender mais
|
||||
sobre e como usar o JavaScript em páginas na web, comece aprendendo sobre
|
||||
[Document Object
|
||||
Model](https://developer.mozilla.org/en-US/docs/Using_the_W3C_DOM_Level_1_Core)
|
||||
|
||||
[Aprenda Javascript por Exemplos e com Desafios](http://www.learneroo.com/modules/64/nodes/350) é uma
|
||||
variação desse guia com desafios.
|
||||
|
||||
[JavaScript Garden](http://bonsaiden.github.io/JavaScript-Garden/) é um guia
|
||||
profundo de todas as partes do JavaScript.
|
||||
|
||||
[JavaScript: The Definitive Guide](http://www.amazon.com/gp/product/0596805527/) é o guia clássico
|
||||
/ livro de referência.
|
||||
|
||||
Parte desse artigo foi adaptado do tutorial de Python do Louie Dinh que está
|
||||
nesse site e do [Tutorial de JS](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript)
|
||||
da Mozilla Developer Network.
|
@ -198,7 +198,7 @@ li[::-1] # => [3, 4, 2, 1]
|
||||
|
||||
# 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.
|
||||
|
@ -234,7 +234,8 @@ on a new line! ""Wow!"", the masses cried";
|
||||
// Üçlü operatörler
|
||||
// Basit bir if/else ifadesi şöyle yazılabilir
|
||||
// <koşul> ? <true> : <false>
|
||||
string isTrue = (true) ? "True" : "False";
|
||||
int toCompare = 17;
|
||||
string isTrue = toCompare == 17 ? "True" : "False";
|
||||
|
||||
// While döngüsü
|
||||
int fooWhile = 0;
|
||||
|
@ -8,12 +8,9 @@ lang: tr-tr
|
||||
|
||||
Swift iOS ve OSX platformlarında geliştirme yapmak için Apple tarafından oluşturulan yeni bir programlama dilidir. Objective - C ile beraber kullanılabilecek ve de hatalı kodlara karşı daha esnek bir yapı sunacak bir şekilde tasarlanmıştır. Swift 2014 yılında Apple'ın geliştirici konferansı WWDC de tanıtıldı. Xcode 6+'a dahil edilen LLVM derleyici ile geliştirildi.
|
||||
|
||||
The official [Swift Programming Language](https://itunes.apple.com/us/book/swift-programming-language/id881256329) book from Apple is now available via iBooks.
|
||||
|
||||
Apple'ın resmi [Swift Programlama Dili](https://itunes.apple.com/us/book/swift-programming-language/id881256329) kitabı iBooks'ta yerini aldı.
|
||||
|
||||
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.
|
||||
|
||||
Ayrıca Swift ile gelen tüm özellikleri görmek için Apple'ın [başlangıç kılavuzu](https://developer.apple.com/library/prerelease/ios/referencelibrary/GettingStarted/RoadMapiOS/index.html)na bakmanızda yarar var.
|
||||
|
||||
|
||||
@ -244,7 +241,7 @@ print("Benzin fiyatı: \(fiyat)")
|
||||
|
||||
// Çeşitli Argümanlar
|
||||
func ayarla(sayilar: Int...) {
|
||||
// its an array
|
||||
// bu bir dizidir
|
||||
let sayi = sayilar[0]
|
||||
let argumanSAyisi = sayilar.count
|
||||
}
|
||||
|
@ -236,7 +236,7 @@ Module Module1
|
||||
'Nine
|
||||
Private Sub IfElseStatement()
|
||||
Console.Title = "If / Else Statement | Learn X in Y Minutes"
|
||||
'Sometimes its important to consider more than two alternatives.
|
||||
'Sometimes it is important to consider more than two alternatives.
|
||||
'Sometimes there are a good few others.
|
||||
'When this is the case, more than one if statement would be required.
|
||||
'An if statement is great for vending machines. Where the user enters a code.
|
||||
|
@ -232,7 +232,8 @@ on a new line! ""Wow!"", the masses cried";
|
||||
// 三元表达式
|
||||
// 简单的 if/else 语句可以写成:
|
||||
// <条件> ? <真> : <假>
|
||||
string isTrue = (true) ? "True" : "False";
|
||||
int toCompare = 17;
|
||||
string isTrue = toCompare == 17 ? "True" : "False";
|
||||
|
||||
// While 循环
|
||||
int fooWhile = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user