mirror of
https://github.com/adambard/learnxinyminutes-docs.git
synced 2024-12-23 15:24:09 +03:00
Fix conflict bash.
This commit is contained in:
commit
af6701904b
@ -12,12 +12,24 @@ Make a new file, send a pull request, and if it passes muster I'll get it up pro
|
||||
Remember to fill in the "contributors" fields so you get credited
|
||||
properly!
|
||||
|
||||
### Contributing
|
||||
## Contributing
|
||||
|
||||
All contributions welcome, from the tiniest typo to a brand new article. Translations
|
||||
in all languages are welcome (or, for that matter, original articles in any language).
|
||||
Send a pull request or open an issue any time of day or night.
|
||||
|
||||
#### Style Guidelines
|
||||
**Please tag your issues pull requests with [language/lang-code] at the beginning**
|
||||
**(e.g. [python/en] for english python).** This will help everyone pick out things they
|
||||
care about.
|
||||
|
||||
### Style Guidelines
|
||||
|
||||
* **Keep lines under 80 chars**
|
||||
* **Prefer example to exposition**
|
||||
* **Eschew surplusage**
|
||||
* **Use utf-8**
|
||||
|
||||
Long version:
|
||||
|
||||
* Try to keep **line length in code blocks to 80 characters or fewer**, or they'll overflow
|
||||
and look odd.
|
||||
@ -29,9 +41,9 @@ in all languages are welcome (or, for that matter, original articles in any lang
|
||||
to keep articles succinct and scannable. We all know how to use google here.
|
||||
|
||||
* For translations (or english articles with non-ASCII characters), please make sure your file is
|
||||
utf-8 encoded.
|
||||
utf-8 encoded, and try to leave out the byte-order-mark at the start of the file. (`:set nobomb` in vim)
|
||||
|
||||
#### Header configuration
|
||||
### Header configuration
|
||||
|
||||
The actual site uses Middleman to generate HTML files from these markdown ones. Middleman, or at least
|
||||
the custom scripts underpinning the site, required that some key information be defined in the header.
|
||||
@ -47,6 +59,19 @@ Other fields:
|
||||
For non-english articles, *filename* should have a language-specific suffix.
|
||||
* **lang**: For translations, the human language this article is in. For categorization, mostly.
|
||||
|
||||
Here's an example header for an esperanto translation of Ruby:
|
||||
|
||||
```yaml
|
||||
---
|
||||
language: ruby
|
||||
filename: learnruby-epo.ruby
|
||||
contributors:
|
||||
- ["Doktor Esperanto", "http://example.com/"]
|
||||
- ["Someone else", "http://someoneelseswebsite.com/"]
|
||||
lang: ep-ep
|
||||
---
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
Contributors retain copyright to their work, and can request removal at any time.
|
||||
|
@ -1,12 +1,11 @@
|
||||
---
|
||||
|
||||
category: tool
|
||||
tool: bash
|
||||
contributors:
|
||||
- ["Max Yankov", "https://github.com/golergka"]
|
||||
- ["Darren Lin", "https://github.com/CogBear"]
|
||||
- ["Alexandre Medeiros", "http://alemedeiros.sdf.org"]
|
||||
filename: LearnBash.sh
|
||||
|
||||
---
|
||||
|
||||
Bash is a name of the unix shell, which was also distributed as the shell for the GNU operating system and as default shell on Linux and Mac OS X.
|
||||
@ -37,8 +36,22 @@ VARIABLE = "Some string"
|
||||
# Using the variable:
|
||||
echo $VARIABLE
|
||||
echo "$VARIABLE"
|
||||
echo '$VARIABLE'
|
||||
# When you use the variable itself — assign it, export it, or else — you write
|
||||
# its name without $. If you want to use variable's value, you should use $.
|
||||
# Note that ' (single quote) won't expand the variables!
|
||||
|
||||
# String substitution in variables
|
||||
echo ${VARIABLE/Some/A}
|
||||
# This will substitute the first occurance of "Some" with "A"
|
||||
|
||||
# Bultin variables:
|
||||
# There are some useful builtin variables, like
|
||||
echo "Last program return value: $?"
|
||||
echo "Script's PID: $$"
|
||||
echo "Number of arguments: $#"
|
||||
echo "Scripts arguments: $@"
|
||||
echo "Scripts arguments separeted in different variables: $1 $2..."
|
||||
|
||||
# Reading a value from input:
|
||||
echo "What's your name?"
|
||||
@ -46,19 +59,17 @@ read NAME # Note that we didn't need to declare new variable
|
||||
echo Hello, $NAME!
|
||||
|
||||
# We have the usual if structure:
|
||||
if true
|
||||
# use 'man test' for more info about conditionals
|
||||
if [ $NAME -ne $USER ]
|
||||
then
|
||||
echo "This is expected"
|
||||
echo "Your name is you username"
|
||||
else
|
||||
echo "And this is not"
|
||||
echo "Your name isn't you username"
|
||||
fi
|
||||
|
||||
# while loop:
|
||||
while [true]
|
||||
do
|
||||
echo "loop body here..."
|
||||
break
|
||||
done
|
||||
# There is also conditional execution
|
||||
echo "Always executed" || echo "Only executed if first command fail"
|
||||
echo "Always executed" && echo "Only executed if first command does NOT fail"
|
||||
|
||||
# Expressions are denoted with the following format:
|
||||
echo $(( 10 + 5 ))
|
||||
@ -76,25 +87,70 @@ ls -l # Lists every file and directory on a separate line
|
||||
# txt files in the current directory:
|
||||
ls -l | grep "\.txt"
|
||||
|
||||
# Commands can be substitued within other commands using $( ):
|
||||
# You can also redirect a command output, input and error output.
|
||||
python2 hello.py < "input.in"
|
||||
python2 hello.py > "output.out"
|
||||
python2 hello.py 2> "error.err"
|
||||
# The output error will overwrite the file if it exists, if you want to
|
||||
# concatenate them, use ">>" instead.
|
||||
|
||||
# Commands can be substituted within other commands using $( ):
|
||||
# The following command displays the number of files and directories in the
|
||||
# current directory.
|
||||
echo "There are $(ls | wc -l) items here."
|
||||
|
||||
# Bash uses a case statement that works similarily to switch in Java and C++:
|
||||
case "$VARIABLE"
|
||||
in
|
||||
# Bash uses a case statement that works similarly to switch in Java and C++:
|
||||
case "$VARIABLE" in
|
||||
#List patterns for the conditions you want to meet
|
||||
0) echo "There is a zero."
|
||||
1) echo "There is a one."
|
||||
*) echo "It is not null."
|
||||
0) echo "There is a zero.";;
|
||||
1) echo "There is a one.";;
|
||||
*) echo "It is not null.";;
|
||||
esac
|
||||
|
||||
#For loops iterate for as many arguments given:
|
||||
#The contents of var $VARIABLE is printed three times.
|
||||
for $VARIABLE in x y z
|
||||
# For loops iterate for as many arguments given:
|
||||
# The contents of var $VARIABLE is printed three times.
|
||||
# Note that ` ` is equivalent to $( ) and that seq returns a sequence of size 3.
|
||||
for VARIABLE in `seq 3`
|
||||
do
|
||||
echo "$VARIABLE"
|
||||
done
|
||||
|
||||
# while loop:
|
||||
while [true]
|
||||
do
|
||||
echo "loop body here..."
|
||||
break
|
||||
done
|
||||
|
||||
# You can also define functions
|
||||
# Definition:
|
||||
function foo ()
|
||||
{
|
||||
echo "Arguments work just like script arguments: $@"
|
||||
echo "And: $1 $2..."
|
||||
echo "This is a function"
|
||||
return 0
|
||||
}
|
||||
|
||||
# or simply
|
||||
bar ()
|
||||
{
|
||||
echo "Another way to declare functions!"
|
||||
return 0
|
||||
}
|
||||
|
||||
# Calling your function
|
||||
foo "My name is" $NAME
|
||||
|
||||
# There are a lot of useful commands you should learn:
|
||||
tail -n 10 file.txt
|
||||
# prints last 10 lines of file.txt
|
||||
head -n 10 file.txt
|
||||
# prints first 10 lines of file.txt
|
||||
sort file.txt
|
||||
# sort file.txt's lines
|
||||
uniq -d file.txt
|
||||
# report or omit repeated lines, with -d it reports them
|
||||
cut -d ',' -f 1 file.txt
|
||||
# prints only the first column before the ',' character
|
||||
```
|
||||
|
79
brainfuck.html.markdown
Normal file
79
brainfuck.html.markdown
Normal file
@ -0,0 +1,79 @@
|
||||
---
|
||||
language: brainfuck
|
||||
contributors:
|
||||
- ["Prajit Ramachandran", "http://prajitr.github.io/"]
|
||||
- ["Mathias Bynens", "http://mathiasbynens.be/"]
|
||||
---
|
||||
|
||||
Brainfuck (not capitalized except at the start of a sentence) is an extremely
|
||||
minimal Turing-complete programming language with just 8 commands.
|
||||
|
||||
```
|
||||
Any character not "><+-.,[]" (excluding quotation marks) is ignored.
|
||||
|
||||
Brainfuck is represented by an array with 30,000 cells initialized to zero
|
||||
and a data pointer pointing at the current cell.
|
||||
|
||||
There are eight commands:
|
||||
+ : Increments the value at the current cell by one.
|
||||
- : Decrements the value at the current cell by one.
|
||||
> : Moves the data pointer to the next cell (cell on the right).
|
||||
< : Moves the data pointer to the previous cell (cell on the left).
|
||||
. : Prints the ASCII value at the current cell (i.e. 65 = 'A').
|
||||
, : Reads a single input character into the current cell.
|
||||
[ : If the value at the current cell is zero, skips to the corresponding ] .
|
||||
Otherwise, move to the next instruction.
|
||||
] : If the value at the current cell is zero, move to the next instruction.
|
||||
Otherwise, move backwards in the instructions to the corresponding [ .
|
||||
|
||||
[ and ] form a while loop. Obviously, they must be balanced.
|
||||
|
||||
Let's look at some basic brainfuck programs.
|
||||
|
||||
++++++ [ > ++++++++++ < - ] > +++++ .
|
||||
|
||||
This program prints out the letter 'A'. First, it increments cell #1 to 6.
|
||||
Cell #1 will be used for looping. Then, it enters the loop ([) and moves
|
||||
to cell #2. It increments cell #2 10 times, moves back to cell #1, and
|
||||
decrements cell #1. This loop happens 6 times (it takes 6 decrements for
|
||||
cell #1 to reach 0, at which point it skips to the corresponding ] and
|
||||
continues on).
|
||||
|
||||
At this point, we're on cell #1, which has a value of 0, while cell #2 has a
|
||||
value of 60. We move on cell #2, increment 5 times, for a value of 65, and then
|
||||
print cell #2's value. 65 is 'A' in ASCII, so 'A' is printed to the terminal.
|
||||
|
||||
|
||||
, [ > + < - ] > .
|
||||
|
||||
This program reads a character from the user input and copies the character into
|
||||
cell #1. Then we start a loop. Move to cell #2, increment the value at cell #2,
|
||||
move back to cell #1, and decrement the value at cell #1. This continues on
|
||||
until cell #1 is 0, and cell #2 holds cell #1's old value. Because we're on
|
||||
cell #1 at the end of the loop, move to cell #2, and then print out the value
|
||||
in ASCII.
|
||||
|
||||
Also keep in mind that the spaces are purely for readability purposes. You
|
||||
could just as easily write it as:
|
||||
|
||||
,[>+<-]>.
|
||||
|
||||
Try and figure out what this program does:
|
||||
|
||||
,>,< [ > [ >+ >+ << -] >> [- << + >>] <<< -] >>
|
||||
|
||||
This program takes two numbers for input, and multiplies them.
|
||||
|
||||
The gist is it first reads in two inputs. Then it starts the outer loop,
|
||||
conditioned on cell #1. Then it moves to cell #2, and starts the inner
|
||||
loop conditioned on cell #2, incrementing cell #3. However, there comes a
|
||||
problem: At the end of the inner loop, cell #2 is zero. In that case,
|
||||
inner loop won't work anymore since next time. To solve this problem,
|
||||
we also increment cell #4, and then recopy cell #4 into cell #2.
|
||||
Then cell #3 is the result.
|
||||
```
|
||||
|
||||
And that's brainfuck. Not that hard, eh? For fun, you can write your own
|
||||
brainfuck programs, or you can write a brainfuck interpreter in another
|
||||
language. The interpreter is fairly simple to implement, but if you're a
|
||||
masochist, try writing a brainfuck interpreter… in brainfuck.
|
@ -96,6 +96,8 @@ int main() {
|
||||
// is not evaluated (except VLAs (see below)).
|
||||
// The value it yields in this case is a compile-time constant.
|
||||
int a = 1;
|
||||
// size_t is an unsiged integer type of at least 2 bytes used to represent
|
||||
// the size of an object.
|
||||
size_t size = sizeof(a++); // a++ is not evaluated
|
||||
printf("sizeof(a++) = %zu where a = %d\n", size, a);
|
||||
// prints "sizeof(a++) = 4 where a = 1" (on a 32-bit architecture)
|
||||
@ -339,7 +341,7 @@ int main() {
|
||||
printf("%zu, %zu\n", sizeof(px), sizeof(not_a_pointer));
|
||||
// => Prints "8, 4" on a typical 64-bit system
|
||||
|
||||
// To retreive the value at the address a pointer is pointing to,
|
||||
// To retrieve the value at the address a pointer is pointing to,
|
||||
// put * in front to de-reference it.
|
||||
// Note: yes, it may be confusing that '*' is used for _both_ declaring a
|
||||
// pointer and dereferencing it.
|
||||
|
@ -63,7 +63,7 @@ and often automatically.
|
||||
; If you want to create a literal list of data, use ' to stop it from
|
||||
; being evaluated
|
||||
'(+ 1 2) ; => (+ 1 2)
|
||||
; (shorthand for (quote (+ 1 2))
|
||||
; (shorthand for (quote (+ 1 2)))
|
||||
|
||||
; You can eval a quoted list
|
||||
(eval '(+ 1 2)) ; => 3
|
||||
@ -205,7 +205,7 @@ keymap ; => {:a 1, :c 3, :b 2}
|
||||
;("a" stringmap)
|
||||
; => Exception: java.lang.String cannot be cast to clojure.lang.IFn
|
||||
|
||||
; Retrieving a non-present value returns nil
|
||||
; Retrieving a non-present key returns nil
|
||||
(stringmap "d") ; => nil
|
||||
|
||||
; Use assoc to add new keys to hash-maps
|
||||
@ -341,7 +341,7 @@ keymap ; => {:a 1, :b 2, :c 3}
|
||||
(swap! my-atom assoc :a 1) ; Sets my-atom to the result of (assoc {} :a 1)
|
||||
(swap! my-atom assoc :b 2) ; Sets my-atom to the result of (assoc {:a 1} :b 2)
|
||||
|
||||
; Use '@' to dereference the atom and get the value
|
||||
; Use '@' to dereference the atom and get the value
|
||||
my-atom ;=> Atom<#...> (Returns the Atom object)
|
||||
@my-atom ; => {:a 1 :b 2}
|
||||
|
||||
@ -376,5 +376,5 @@ Clojuredocs.org has documentation with examples for most core functions:
|
||||
4Clojure is a great way to build your clojure/FP skills:
|
||||
[http://www.4clojure.com/](http://www.4clojure.com/)
|
||||
|
||||
Clojure-doc.org (yeah, really) has a number of getting started articles:
|
||||
Clojure-doc.org (yes, really) has a number of getting started articles:
|
||||
[http://clojure-doc.org/](http://clojure-doc.org/)
|
||||
|
@ -205,7 +205,7 @@ nil ; for false - and the empty list
|
||||
|
||||
;; Or use concatenate -
|
||||
|
||||
(concatenate
|
||||
(concatenate 'list '(1 2) '(3 4))
|
||||
|
||||
;; Lists are a very central type, so there is a wide variety of functionality for
|
||||
;; them, a few examples:
|
||||
@ -219,7 +219,7 @@ nil ; for false - and the empty list
|
||||
|
||||
;;; Vectors
|
||||
|
||||
;; Vectors are fixed-length arrays
|
||||
;; Vector's literals are fixed-length arrays
|
||||
#(1 2 3) ; => #(1 2 3)
|
||||
|
||||
;; Use concatenate to add vectors together
|
||||
@ -253,6 +253,23 @@ nil ; for false - and the empty list
|
||||
|
||||
; => 0
|
||||
|
||||
;;; Adjustable vectors
|
||||
|
||||
;; Adjustable vectors have the same printed representation
|
||||
;; as fixed-length vector's literals.
|
||||
|
||||
(defparameter *adjvec* (make-array '(3) :initial-contents '(1 2 3)
|
||||
:adjustable t :fill-pointer t))
|
||||
|
||||
*adjvec* ; => #(1 2 3)
|
||||
|
||||
;; Adding new element:
|
||||
(vector-push-extend 4 *adjvec*) ; => 3
|
||||
|
||||
*adjvec* ; => #(1 2 3 4)
|
||||
|
||||
|
||||
|
||||
;;; Naively, sets are just lists:
|
||||
|
||||
(set-difference '(1 2 3 4) '(4 5 6 7)) ; => (3 2 1)
|
||||
@ -279,10 +296,10 @@ nil ; for false - and the empty list
|
||||
;; not.
|
||||
|
||||
;; Retrieving a non-present value returns nil
|
||||
(gethash *m* 'd) ;=> nil, nil
|
||||
(gethash 'd *m*) ;=> nil, nil
|
||||
|
||||
;; You can provide a default value for missing keys
|
||||
(gethash *m* 'd :not-found) ; => :NOT-FOUND
|
||||
(gethash 'd *m* :not-found) ; => :NOT-FOUND
|
||||
|
||||
;; Let's handle the multiple return values here in code.
|
||||
|
||||
@ -360,7 +377,7 @@ nil ; for false - and the empty list
|
||||
;; 4. Equality
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; Common Lisp has a sophisticated equality system. A couple are covered yere.
|
||||
;; Common Lisp has a sophisticated equality system. A couple are covered here.
|
||||
|
||||
;; for numbers use `='
|
||||
(= 3 3.0) ; => t
|
||||
@ -457,8 +474,8 @@ nil ; for false - and the empty list
|
||||
:accessor velocity
|
||||
:initarg :velocity)
|
||||
(average-efficiency
|
||||
:accessor average-efficiency)
|
||||
:initarg :average-efficiency)
|
||||
:accessor average-efficiency
|
||||
:initarg :average-efficiency))
|
||||
(:documentation "A human powered conveyance"))
|
||||
|
||||
;; defclass, followed by name, followed by the superclass list,
|
||||
@ -506,7 +523,7 @@ nil ; for false - and the empty list
|
||||
; Direct superclasses: STANDARD-OBJECT
|
||||
; Direct subclasses: UNICYCLE, BICYCLE, CANOE
|
||||
; Not yet finalized.
|
||||
(defparameter *foo#\u03BBooo* nil) ; Direct slots:
|
||||
; Direct slots:
|
||||
; VELOCITY
|
||||
; Readers: VELOCITY
|
||||
; Writers: (SETF VELOCITY)
|
||||
@ -602,4 +619,4 @@ nil ; for false - and the empty list
|
||||
Lots of thanks to the Scheme people for rolling up a great starting
|
||||
point which could be easily moved to Common Lisp.
|
||||
|
||||
- [Paul Khoung](https://github.com/pkhuong) for some great reviewing.
|
||||
- [Paul Khuong](https://github.com/pkhuong) for some great reviewing.
|
||||
|
@ -1,11 +1,11 @@
|
||||
---
|
||||
|
||||
language: c#
|
||||
contributors:
|
||||
- ["Irfan Charania", "https://github.com/irfancharania"]
|
||||
- ["Max Yankov", "https://github.com/golergka"]
|
||||
- ["Melvyn Laïly", "http://x2a.yt"]
|
||||
- ["Shaun McCarthy", "http://www.shaunmccarthy.com"]
|
||||
filename: LearnCSharp.cs
|
||||
|
||||
---
|
||||
|
||||
C# is an elegant and type-safe object-oriented language that enables developers to build a variety of secure and robust applications that run on the .NET Framework.
|
||||
@ -24,7 +24,12 @@ Multi-line comments look like this
|
||||
// Specify namespaces application will be using
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using System.Data.Entity;
|
||||
using System.Dynamic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
// defines scope to organize code into "packages"
|
||||
namespace Learning
|
||||
@ -33,8 +38,8 @@ namespace Learning
|
||||
// you're allowed to do otherwise, but shouldn't for sanity.
|
||||
public class LearnCSharp
|
||||
{
|
||||
// A console application must have a main method as an entry point
|
||||
public static void Main(string[] args)
|
||||
// BASIC SYNTAX - skip to INTERESTING FEATURES if you have used Java or C++ before
|
||||
public static void Syntax()
|
||||
{
|
||||
// Use Console.WriteLine to print lines
|
||||
Console.WriteLine("Hello World");
|
||||
@ -47,7 +52,6 @@ namespace Learning
|
||||
Console.Write("Hello ");
|
||||
Console.Write("World");
|
||||
|
||||
|
||||
///////////////////////////////////////////////////
|
||||
// Types & Variables
|
||||
//
|
||||
@ -62,123 +66,83 @@ namespace Learning
|
||||
// (0 <= byte <= 255)
|
||||
byte fooByte = 100;
|
||||
|
||||
// Short - Signed 16-bit integer
|
||||
// (-32,768 <= short <= 32,767)
|
||||
// Short - 16-bit integer
|
||||
// Signed - (-32,768 <= short <= 32,767)
|
||||
// Unsigned - (0 <= ushort <= 65,535)
|
||||
short fooShort = 10000;
|
||||
|
||||
// Ushort - Unsigned 16-bit integer
|
||||
// (0 <= ushort <= 65,535)
|
||||
ushort fooUshort = 10000;
|
||||
|
||||
// Integer - Signed 32-bit integer
|
||||
// (-2,147,483,648 <= int <= 2,147,483,647)
|
||||
int fooInt = 1;
|
||||
// Integer - 32-bit integer
|
||||
int fooInt = 1; // (-2,147,483,648 <= int <= 2,147,483,647)
|
||||
uint fooUint = 1; // (0 <= uint <= 4,294,967,295)
|
||||
|
||||
// Uinteger - Unsigned 32-bit integer
|
||||
// (0 <= uint <= 4,294,967,295)
|
||||
uint fooUint = 1;
|
||||
|
||||
// Long - Signed 64-bit integer
|
||||
// (-9,223,372,036,854,775,808 <= long <= 9,223,372,036,854,775,807)
|
||||
long fooLong = 100000L;
|
||||
// Long - 64-bit integer
|
||||
long fooLong = 100000L; // (-9,223,372,036,854,775,808 <= long <= 9,223,372,036,854,775,807)
|
||||
ulong fooUlong = 100000L; // (0 <= ulong <= 18,446,744,073,709,551,615)
|
||||
// Numbers default to being int or uint depending on size.
|
||||
// L is used to denote that this variable value is of type long or ulong
|
||||
// anything without is treated as int or uint depending on size.
|
||||
|
||||
// Ulong - Unsigned 64-bit integer
|
||||
// (0 <= ulong <= 18,446,744,073,709,551,615)
|
||||
ulong fooUlong = 100000L;
|
||||
|
||||
// Float - Single-precision 32-bit IEEE 754 Floating Point
|
||||
// Precision: 7 digits
|
||||
float fooFloat = 234.5f;
|
||||
// f is used to denote that this variable value is of type float;
|
||||
// otherwise it is treated as double.
|
||||
|
||||
// Double - Double-precision 64-bit IEEE 754 Floating Point
|
||||
// Precision: 15-16 digits
|
||||
double fooDouble = 123.4;
|
||||
double fooDouble = 123.4; // Precision: 15-16 digits
|
||||
|
||||
// Bool - true & false
|
||||
bool fooBoolean = true;
|
||||
bool barBoolean = false;
|
||||
// Float - Single-precision 32-bit IEEE 754 Floating Point
|
||||
float fooFloat = 234.5f; // Precision: 7 digits
|
||||
// f is used to denote that this variable value is of type float
|
||||
|
||||
// Decimal - a 128-bits data type, with more precision than other floating-point types,
|
||||
// suited for financial and monetary calculations
|
||||
decimal fooDecimal = 150.3m;
|
||||
|
||||
// Boolean - true & false
|
||||
bool fooBoolean = true; // or false
|
||||
|
||||
// Char - A single 16-bit Unicode character
|
||||
char fooChar = 'A';
|
||||
|
||||
// Strings
|
||||
string fooString = "My string is here!";
|
||||
// Strings -- unlike the previous base types which are all value types,
|
||||
// a string is a reference type. That is, you can set it to null
|
||||
string fooString = "\"escape\" quotes and add \n (new lines) and \t (tabs)";
|
||||
Console.WriteLine(fooString);
|
||||
|
||||
// formatting
|
||||
string fooFs = string.Format("Check Check, {0} {1}, {0} {1:0.0}", 1, 2);
|
||||
Console.WriteLine(fooFormattedString);
|
||||
// You can access each character of the string with an indexer:
|
||||
char charFromString = fooString[1]; // 'y'
|
||||
// Strings are immutable: you can't do fooString[1] = 'X';
|
||||
|
||||
// formatting dates
|
||||
// Compare strings with current culture, ignoring case
|
||||
string.Compare(fooString, "x", StringComparison.CurrentCultureIgnoreCase);
|
||||
|
||||
// Formatting, based on sprintf
|
||||
string fooFs = string.Format("Check Check, {0} {1}, {0} {1:0.0}", 1, 2);
|
||||
|
||||
// Dates & Formatting
|
||||
DateTime fooDate = DateTime.Now;
|
||||
Console.WriteLine(fooDate.ToString("hh:mm, dd MMM yyyy"));
|
||||
|
||||
// \n is an escaped character that starts a new line
|
||||
string barString = "Printing on a new line?\nNo Problem!";
|
||||
Console.WriteLine(barString);
|
||||
|
||||
// it can be written prettier by using the @ symbol
|
||||
// You can split a string over two lines with the @ symbol. To escape " use ""
|
||||
string bazString = @"Here's some stuff
|
||||
on a new line!";
|
||||
Console.WriteLine(bazString);
|
||||
|
||||
// quotes need to be escaped
|
||||
// use \" normally
|
||||
string quotedString = "some \"quoted\" stuff";
|
||||
Console.WriteLine(quotedString);
|
||||
|
||||
// use "" when strings start with @
|
||||
string quotedString2 = @"some MORE ""quoted"" stuff";
|
||||
Console.WriteLine(quotedString2);
|
||||
on a new line! ""Wow!"", the masses cried";
|
||||
|
||||
// Use const or read-only to make a variable immutable
|
||||
// const values are calculated at compile time
|
||||
const int HOURS_I_WORK_PER_WEEK = 9001;
|
||||
|
||||
// Nullable types
|
||||
// any type can be made nullable by suffixing a ?
|
||||
// <type>? <var name> = <value>
|
||||
int? nullable = null;
|
||||
Console.WriteLine("Nullable variable: " + nullable);
|
||||
|
||||
// In order to use nullable's value, you have to use Value property or to explicitly cast it
|
||||
string? nullableString = "not null";
|
||||
Console.WriteLine("Nullable value is: " + nullableString.Value + " or: " + (string) nullableString );
|
||||
|
||||
// ?? is syntactic sugar for specifying default value
|
||||
// in case variable is null
|
||||
int notNullable = nullable ?? 0;
|
||||
Console.WriteLine("Not nullable variable: " + notNullable);
|
||||
|
||||
// Var - compiler will choose the most appropriate type based on value
|
||||
var fooImplicit = true;
|
||||
|
||||
///////////////////////////////////////////////////
|
||||
// Data Structures
|
||||
///////////////////////////////////////////////////
|
||||
Console.WriteLine("\n->Data Structures");
|
||||
|
||||
// Arrays
|
||||
// Arrays - zero indexed
|
||||
// The array size must be decided upon declaration
|
||||
// The format for declaring an array is follows:
|
||||
// <datatype>[] <var name> = new <datatype>[<array size>];
|
||||
int[] intArray = new int[10];
|
||||
string[] stringArray = new string[1];
|
||||
bool[] boolArray = new bool[100];
|
||||
|
||||
// Another way to declare & initialize an array
|
||||
int[] y = { 9000, 1000, 1337 };
|
||||
|
||||
// Indexing an array - Accessing an element
|
||||
Console.WriteLine("intArray @ 0: " + intArray[0]);
|
||||
|
||||
// Arrays are zero-indexed and mutable.
|
||||
// Arrays are mutable.
|
||||
intArray[1] = 1;
|
||||
Console.WriteLine("intArray @ 1: " + intArray[1]); // => 1
|
||||
|
||||
// Lists
|
||||
// Lists are used more frequently than arrays as they are more flexible
|
||||
@ -186,28 +150,21 @@ namespace Learning
|
||||
// List<datatype> <var name> = new List<datatype>();
|
||||
List<int> intList = new List<int>();
|
||||
List<string> stringList = new List<string>();
|
||||
|
||||
// Another way to declare & initialize a list
|
||||
List<int> z = new List<int> { 9000, 1000, 1337 };
|
||||
|
||||
// Indexing a list - Accessing an element
|
||||
// Lists are zero-indexed and mutable.
|
||||
Console.WriteLine("z @ 0: " + z[2]);
|
||||
List<int> z = new List<int> { 9000, 1000, 1337 }; // intialize
|
||||
// The <> are for generics - Check out the cool stuff section
|
||||
|
||||
// Lists don't default to a value;
|
||||
// A value must be added before accessing the index
|
||||
intList.Add(1);
|
||||
Console.WriteLine("intList @ 0: " + intList[0]);
|
||||
|
||||
|
||||
// Others data structures to check out:
|
||||
//
|
||||
// Stack/Queue
|
||||
// Dictionary
|
||||
// Dictionary (an implementation of a hash map)
|
||||
// HashSet
|
||||
// Read-only Collections
|
||||
// Tuple (.Net 4+)
|
||||
|
||||
|
||||
///////////////////////////////////////
|
||||
// Operators
|
||||
///////////////////////////////////////
|
||||
@ -216,10 +173,7 @@ namespace Learning
|
||||
int i1 = 1, i2 = 2; // Shorthand for multiple declarations
|
||||
|
||||
// Arithmetic is straightforward
|
||||
Console.WriteLine("1+2 = " + (i1 + i2)); // => 3
|
||||
Console.WriteLine("2-1 = " + (i2 - i1)); // => 1
|
||||
Console.WriteLine("2*1 = " + (i2 * i1)); // => 2
|
||||
Console.WriteLine("1/2 = " + (i1 / i2)); // => 0 (0.5 truncated down)
|
||||
Console.WriteLine(i1 + i2 - i1 * 3 / 7); //
|
||||
|
||||
// Modulo
|
||||
Console.WriteLine("11%3 = " + (11 % 3)); // => 2
|
||||
@ -237,7 +191,6 @@ namespace Learning
|
||||
~ Unary bitwise complement
|
||||
<< Signed left shift
|
||||
>> Signed right shift
|
||||
>>> Unsigned right shift
|
||||
& Bitwise AND
|
||||
^ Bitwise exclusive OR
|
||||
| Bitwise inclusive OR
|
||||
@ -251,7 +204,6 @@ namespace Learning
|
||||
Console.WriteLine(i--); //i = 1. Post-Decrementation
|
||||
Console.WriteLine(--i); //i = 0. Pre-Decrementation
|
||||
|
||||
|
||||
///////////////////////////////////////
|
||||
// Control Structures
|
||||
///////////////////////////////////////
|
||||
@ -276,40 +228,39 @@ namespace Learning
|
||||
// A simple if/else can be written as follows
|
||||
// <condition> ? <true> : <false>
|
||||
string isTrue = (true) ? "True" : "False";
|
||||
Console.WriteLine("Ternary demo: " + isTrue);
|
||||
|
||||
|
||||
// While loop
|
||||
int fooWhile = 0;
|
||||
while (fooWhile < 100)
|
||||
{
|
||||
//Console.WriteLine(fooWhile);
|
||||
//Increment the counter
|
||||
//Iterated 99 times, fooWhile 0->99
|
||||
//Iterated 100 times, fooWhile 0->99
|
||||
fooWhile++;
|
||||
}
|
||||
Console.WriteLine("fooWhile Value: " + fooWhile);
|
||||
|
||||
// Do While Loop
|
||||
int fooDoWhile = 0;
|
||||
do
|
||||
{
|
||||
//Console.WriteLine(fooDoWhile);
|
||||
//Increment the counter
|
||||
//Iterated 99 times, fooDoWhile 0->99
|
||||
fooDoWhile++;
|
||||
} while (fooDoWhile < 100);
|
||||
Console.WriteLine("fooDoWhile Value: " + fooDoWhile);
|
||||
|
||||
// For Loop
|
||||
int fooFor;
|
||||
//for loop structure => for(<start_statement>; <conditional>; <step>)
|
||||
for (fooFor = 0; fooFor < 10; fooFor++)
|
||||
for (int fooFor = 0; fooFor < 10; fooFor++)
|
||||
{
|
||||
//Console.WriteLine(fooFor);
|
||||
//Iterated 10 times, fooFor 0->9
|
||||
}
|
||||
Console.WriteLine("fooFor Value: " + fooFor);
|
||||
|
||||
// For Each Loop
|
||||
// foreach loop structure => foreach(<iteratorType> <iteratorName> in <enumerable>)
|
||||
// The foreach loop loops over any object implementing IEnumerable or IEnumerable<T>
|
||||
// All the collection types (Array, List, Dictionary...) in the .Net framework
|
||||
// implement one or both of these interfaces.
|
||||
// (The ToCharArray() could be removed, because a string also implements IEnumerable)
|
||||
foreach (char character in "Hello World".ToCharArray())
|
||||
{
|
||||
//Iterated over all the characters in the string
|
||||
}
|
||||
|
||||
// Switch Case
|
||||
// A switch works with the byte, short, char, and int data types.
|
||||
@ -329,15 +280,21 @@ namespace Learning
|
||||
case 3:
|
||||
monthString = "March";
|
||||
break;
|
||||
// You can assign more than one case to an action
|
||||
// But you can't add an action without a break before another case
|
||||
// (if you want to do this, you would have to explicitly add a goto case x
|
||||
case 6:
|
||||
case 7:
|
||||
case 8:
|
||||
monthString = "Summer time!!";
|
||||
break;
|
||||
default:
|
||||
monthString = "Some other month";
|
||||
break;
|
||||
}
|
||||
Console.WriteLine("Switch Case Result: " + monthString);
|
||||
|
||||
|
||||
///////////////////////////////////////
|
||||
// Converting Data Types And Typcasting
|
||||
// Converting Data Types And Typecasting
|
||||
///////////////////////////////////////
|
||||
|
||||
// Converting data
|
||||
@ -349,49 +306,231 @@ namespace Learning
|
||||
// try parse will default to type default on failure
|
||||
// in this case: 0
|
||||
int tryInt;
|
||||
int.TryParse("123", out tryInt);
|
||||
if (int.TryParse("123", out tryInt)) // Funciton is boolean
|
||||
Console.WriteLine(tryInt); // 123
|
||||
|
||||
// Convert Integer To String
|
||||
// Convert class has a number of methods to facilitate conversions
|
||||
Convert.ToString(123);
|
||||
// or
|
||||
tryInt.ToString();
|
||||
}
|
||||
|
||||
///////////////////////////////////////
|
||||
// Classes And Functions
|
||||
///////////////////////////////////////
|
||||
|
||||
Console.WriteLine("\n->Classes & Functions");
|
||||
|
||||
// (definition of the Bicycle class follows)
|
||||
///////////////////////////////////////
|
||||
// CLASSES - see definitions at end of file
|
||||
///////////////////////////////////////
|
||||
public static void Classes()
|
||||
{
|
||||
// See Declaration of objects at end of file
|
||||
|
||||
// Use new to instantiate a class
|
||||
Bicycle trek = new Bicycle();
|
||||
|
||||
// Call object methods
|
||||
trek.speedUp(3); // You should always use setter and getter methods
|
||||
trek.setCadence(100);
|
||||
trek.SpeedUp(3); // You should always use setter and getter methods
|
||||
trek.Cadence = 100;
|
||||
|
||||
// ToString is a convention to display the value of this Object.
|
||||
Console.WriteLine("trek info: " + trek.ToString());
|
||||
|
||||
// Instantiate another new Bicycle
|
||||
Bicycle octo = new Bicycle(5, 10);
|
||||
Console.WriteLine("octo info: " + octo.ToString());
|
||||
Console.WriteLine("trek info: " + trek.Info());
|
||||
|
||||
// Instantiate a new Penny Farthing
|
||||
PennyFarthing funbike = new PennyFarthing(1, 10);
|
||||
Console.WriteLine("funbike info: " + funbike.ToString());
|
||||
Console.WriteLine("funbike info: " + funbike.Info());
|
||||
|
||||
Console.Read();
|
||||
} // End main method
|
||||
|
||||
// CONSOLE ENTRY A console application must have a main method as an entry point
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
OtherInterestingFeatures();
|
||||
}
|
||||
|
||||
//
|
||||
// INTERESTING FEATURES
|
||||
//
|
||||
|
||||
// DEFAULT METHOD SIGNATURES
|
||||
|
||||
public // Visibility
|
||||
static // Allows for direct call on class without object
|
||||
int // Return Type,
|
||||
MethodSignatures(
|
||||
int maxCount, // First variable, expects an int
|
||||
int count = 0, // will default the value to 0 if not passed in
|
||||
int another = 3,
|
||||
params string[] otherParams // captures all other parameters passed to method
|
||||
)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Methods can have the same name, as long as the signature is unique
|
||||
public static void MethodSignature(string maxCount)
|
||||
{
|
||||
}
|
||||
|
||||
// GENERICS
|
||||
// The classes for TKey and TValue is specified by the user calling this function.
|
||||
// This method emulates the SetDefault of Python
|
||||
public static TValue SetDefault<TKey, TValue>(
|
||||
IDictionary<TKey, TValue> dictionary,
|
||||
TKey key,
|
||||
TValue defaultItem)
|
||||
{
|
||||
TValue result;
|
||||
if (!dictionary.TryGetValue(key, out result))
|
||||
return dictionary[key] = defaultItem;
|
||||
return result;
|
||||
}
|
||||
|
||||
// You can narrow down the objects that are passed in
|
||||
public static void IterateAndPrint<T>(T toPrint) where T: IEnumerable<int>
|
||||
{
|
||||
// We can iterate, since T is a IEnumerable
|
||||
foreach (var item in toPrint)
|
||||
// Item is an int
|
||||
Console.WriteLine(item.ToString());
|
||||
}
|
||||
|
||||
public static void OtherInterestingFeatures()
|
||||
{
|
||||
// OPTIONAL PARAMETERS
|
||||
MethodSignatures(3, 1, 3, "Some", "Extra", "Strings");
|
||||
MethodSignatures(3, another: 3); // explicity set a parameter, skipping optional ones
|
||||
|
||||
// EXTENSION METHODS
|
||||
int i = 3;
|
||||
i.Print(); // Defined below
|
||||
|
||||
// NULLABLE TYPES - great for database interaction / return values
|
||||
// any value type (i.e. not a class) can be made nullable by suffixing a ?
|
||||
// <type>? <var name> = <value>
|
||||
int? nullable = null; // short hand for Nullable<int>
|
||||
Console.WriteLine("Nullable variable: " + nullable);
|
||||
bool hasValue = nullable.HasValue; // true if not null
|
||||
|
||||
// ?? is syntactic sugar for specifying default value (coalesce)
|
||||
// in case variable is null
|
||||
int notNullable = nullable ?? 0; // 0
|
||||
|
||||
// IMPLICITLY TYPED VARIABLES - you can let the compiler work out what the type is:
|
||||
var magic = "magic is a string, at compile time, so you still get type safety";
|
||||
// magic = 9; will not work as magic is a string, not an int
|
||||
|
||||
// GENERICS
|
||||
//
|
||||
var phonebook = new Dictionary<string, string>() {
|
||||
{"Sarah", "212 555 5555"} // Add some entries to the phone book
|
||||
};
|
||||
|
||||
// Calling SETDEFAULT defined as a generic above
|
||||
Console.WriteLine(SetDefault<string,string>(phonebook, "Shaun", "No Phone")); // No Phone
|
||||
// nb, you don't need to specify the TKey and TValue since they can be
|
||||
// derived implicitly
|
||||
Console.WriteLine(SetDefault(phonebook, "Sarah", "No Phone")); // 212 555 5555
|
||||
|
||||
// LAMBDA EXPRESSIONS - allow you to write code in line
|
||||
Func<int, int> square = (x) => x * x; // Last T item is the return value
|
||||
Console.WriteLine(square(3)); // 9
|
||||
|
||||
// PARALLEL FRAMEWORK
|
||||
// http://blogs.msdn.com/b/csharpfaq/archive/2010/06/01/parallel-programming-in-net-framework-4-getting-started.aspx
|
||||
var websites = new string[] {
|
||||
"http://www.google.com", "http://www.reddit.com",
|
||||
"http://www.shaunmccarthy.com"
|
||||
};
|
||||
var responses = new Dictionary<string, string>();
|
||||
|
||||
// Will spin up separate threads for each request, and join on them
|
||||
// before going to the next step!
|
||||
Parallel.ForEach(websites,
|
||||
new ParallelOptions() {MaxDegreeOfParallelism = 3}, // max of 3 threads
|
||||
website =>
|
||||
{
|
||||
// Do something that takes a long time on the file
|
||||
using (var r = WebRequest.Create(new Uri(website)).GetResponse())
|
||||
{
|
||||
responses[website] = r.ContentType;
|
||||
}
|
||||
});
|
||||
|
||||
// This won't happen till after all requests have been completed
|
||||
foreach (var key in responses.Keys)
|
||||
Console.WriteLine("{0}:{1}", key, responses[key]);
|
||||
|
||||
// DYNAMIC OBJECTS (great for working with other languages)
|
||||
dynamic student = new ExpandoObject();
|
||||
student.FirstName = "First Name"; // No need to define class first!
|
||||
|
||||
// You can even add methods (returns a string, and takes in a string)
|
||||
student.Introduce = new Func<string, string>(
|
||||
(introduceTo) => string.Format("Hey {0}, this is {1}", student.FirstName, introduceTo));
|
||||
Console.WriteLine(student.Introduce("Beth"));
|
||||
|
||||
// IQUERYABLE<T> - almost all collections implement this, which gives you a lot of
|
||||
// very useful Map / Filter / Reduce style methods
|
||||
var bikes = new List<Bicycle>();
|
||||
bikes.Sort(); // Sorts the array
|
||||
bikes.Sort((b1, b2) => b1.Wheels.CompareTo(b2.Wheels)); // Sorts based on wheels
|
||||
var result = bikes
|
||||
.Where(b => b.Wheels > 3) // Filters - chainable (returns IQueryable of previous type)
|
||||
.Where(b => b.IsBroken && b.HasTassles)
|
||||
.Select(b => b.ToString()); // Map - we only this selects, so result is a IQueryable<string>
|
||||
|
||||
var sum = bikes.Sum(b => b.Wheels); // Reduce - sums all the wheels in the collection
|
||||
|
||||
// Create a list of IMPLICIT objects based on some parameters of the bike
|
||||
var bikeSummaries = bikes.Select(b=>new { Name = b.Name, IsAwesome = !b.IsBroken && b.HasTassles });
|
||||
// Hard to show here, but you get type ahead completion since the compiler can implicitly work
|
||||
// out the types above!
|
||||
foreach (var bikeSummary in bikeSummaries.Where(b => b.IsAwesome))
|
||||
Console.WriteLine(bikeSummary.Name);
|
||||
|
||||
// ASPARALLEL
|
||||
// And this is where things get wicked - combines linq and parallel operations
|
||||
var threeWheelers = bikes.AsParallel().Where(b => b.Wheels == 3).Select(b => b.Name);
|
||||
// this will happen in parallel! Threads will automagically be spun up and the
|
||||
// results divvied amongst them! Amazing for large datasets when you have lots of
|
||||
// cores
|
||||
|
||||
// LINQ - maps a store to IQueryable<T> objects, with delayed execution
|
||||
// e.g. LinqToSql - maps to a database, LinqToXml maps to an xml document
|
||||
var db = new BikeRespository();
|
||||
|
||||
// execution is delayed, which is great when querying a database
|
||||
var fitler = db.Bikes.Where(b => b.HasTassles); // no query run
|
||||
if (42 > 6) // You can keep adding filters, even conditionally - great for "advanced search" functionality
|
||||
fitler = fitler.Where(b => b.IsBroken); // no query run
|
||||
|
||||
var query = fitler
|
||||
.OrderBy(b => b.Wheels)
|
||||
.ThenBy(b => b.Name)
|
||||
.Select(b => b.Name); // still no query run
|
||||
|
||||
// Now the query runs, but opens a reader, so only populates are you iterate through
|
||||
foreach (string bike in query)
|
||||
Console.WriteLine(result);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
} // End LearnCSharp class
|
||||
|
||||
// You can include other classes in a .cs file
|
||||
|
||||
public static class Extensions
|
||||
{
|
||||
// EXTENSION FUNCTIONS
|
||||
public static void Print(this object obj)
|
||||
{
|
||||
Console.WriteLine(obj.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
// Class Declaration Syntax:
|
||||
// <public/private/protected> class <class name>{
|
||||
// <public/private/protected/internal> class <class name>{
|
||||
// //data fields, constructors, functions all inside.
|
||||
// //functions are called as methods in Java.
|
||||
// }
|
||||
@ -399,61 +538,88 @@ namespace Learning
|
||||
public class Bicycle
|
||||
{
|
||||
// Bicycle's Fields/Variables
|
||||
public int cadence; // Public: Can be accessed from anywhere
|
||||
private int _speed; // Private: Only accessible from within the class
|
||||
protected int gear; // Protected: Accessible from the class and subclasses
|
||||
internal int wheels; // Internal: Accessible from within the assembly
|
||||
string name; // Everything is private by default: Only accessible from within this class
|
||||
public int Cadence // Public: Can be accessed from anywhere
|
||||
{
|
||||
get // get - define a method to retrieve the property
|
||||
{
|
||||
return _cadence;
|
||||
}
|
||||
set // set - define a method to set a proprety
|
||||
{
|
||||
_cadence = value; // Value is the value passed in to to the setter
|
||||
}
|
||||
}
|
||||
private int _cadence;
|
||||
|
||||
protected virtual int Gear // Protected: Accessible from the class and subclasses
|
||||
{
|
||||
get; // creates an auto property so you don't need a member field
|
||||
set;
|
||||
}
|
||||
|
||||
internal int Wheels // Internal: Accessible from within the assembly
|
||||
{
|
||||
get;
|
||||
private set; // You can set modifiers on the get/set methods
|
||||
}
|
||||
|
||||
int _speed; // Everything is private by default: Only accessible from within this class.
|
||||
// can also use keyword privatee
|
||||
public string Name { get; set; }
|
||||
|
||||
// Enum is a value type that consists of a set of named constants
|
||||
public enum Brand
|
||||
// It is really just mapping a name to a value (an int, unless specified otherwise).
|
||||
// The approved types for an enum are byte, sbyte, short, ushort, int, uint, long, or ulong.
|
||||
// An enum can't contain the same value twice.
|
||||
public enum BikeBrand
|
||||
{
|
||||
AIST,
|
||||
BMC,
|
||||
Electra,
|
||||
Electra = 42, //you can explicitly set a value to a name
|
||||
Gitane
|
||||
}
|
||||
// We defined this type inside a Bicycle class, so it is a nested type
|
||||
// Code outside of this class should reference this type as Bicycle.Brand
|
||||
|
||||
public Brand brand; // After declaing an enum type, we can declare the field of this type
|
||||
public BikeBrand Brand; // After declaring an enum type, we can declare the field of this type
|
||||
|
||||
// Static members belong to the type itself rather then specific object.
|
||||
static public int bicyclesCreated = 0;
|
||||
// You can access them without a reference to any object:
|
||||
// Console.WriteLine("Bicycles created: " + Bicycle.bicyclesCreated);
|
||||
static public int BicyclesCreated = 0;
|
||||
|
||||
// readonly values are set at run time
|
||||
// they can only be assigned upon declaration or in a constructor
|
||||
readonly bool hasCardsInSpokes = false; // read-only private
|
||||
readonly bool _hasCardsInSpokes = false; // read-only private
|
||||
|
||||
// Constructors are a way of creating classes
|
||||
// This is a default constructor
|
||||
private Bicycle()
|
||||
public Bicycle()
|
||||
{
|
||||
gear = 1;
|
||||
cadence = 50;
|
||||
this.Gear = 1; // you can access mmebers of the object with the keyword this
|
||||
Cadence = 50; // but you don't always need it
|
||||
_speed = 5;
|
||||
name = "Bontrager";
|
||||
brand = Brand.AIST;
|
||||
bicyclesCreated++;
|
||||
Name = "Bontrager";
|
||||
Brand = BikeBrand.AIST;
|
||||
BicyclesCreated++;
|
||||
}
|
||||
|
||||
// This is a specified constructor (it contains arguments)
|
||||
public Bicycle(int startCadence, int startSpeed, int startGear,
|
||||
string name, bool hasCardsInSpokes, Brand brand)
|
||||
string name, bool hasCardsInSpokes, BikeBrand brand)
|
||||
: base() // calls base first
|
||||
{
|
||||
this.gear = startGear; // "this" keyword denotes the current object
|
||||
this.cadence = startCadence;
|
||||
this._speed = startSpeed;
|
||||
this.name = name; // it can be useful when there's a name conflict
|
||||
this.hasCardsInSpokes = hasCardsInSpokes;
|
||||
this.brand = brand;
|
||||
Gear = startGear;
|
||||
Cadence = startCadence;
|
||||
_speed = startSpeed;
|
||||
Name = name;
|
||||
_hasCardsInSpokes = hasCardsInSpokes;
|
||||
Brand = brand;
|
||||
}
|
||||
|
||||
// Constructors can be chained
|
||||
public Bicycle(int startCadence, int startSpeed, Brand brand) :
|
||||
this(startCadence, startSpeed, 0, "big wheels", true)
|
||||
public Bicycle(int startCadence, int startSpeed, BikeBrand brand) :
|
||||
this(startCadence, startSpeed, 0, "big wheels", true, brand)
|
||||
{
|
||||
}
|
||||
|
||||
@ -461,28 +627,10 @@ namespace Learning
|
||||
// <public/private/protected> <return type> <function name>(<args>)
|
||||
|
||||
// classes can implement getters and setters for their fields
|
||||
// or they can implement properties
|
||||
// or they can implement properties (this is the preferred way in C#)
|
||||
|
||||
// Method declaration syntax:
|
||||
// <scope> <return type> <method name>(<args>)
|
||||
public int GetCadence()
|
||||
{
|
||||
return cadence;
|
||||
}
|
||||
|
||||
// void methods require no return statement
|
||||
public void SetCadence(int newValue)
|
||||
{
|
||||
cadence = newValue;
|
||||
}
|
||||
|
||||
// virtual keyword indicates this method can be overridden
|
||||
public virtual void SetGear(int newValue)
|
||||
{
|
||||
gear = newValue;
|
||||
}
|
||||
|
||||
// Method parameters can have defaut values. In this case, methods can be called with these parameters omitted
|
||||
// Method parameters can have default values.
|
||||
// In this case, methods can be called with these parameters omitted
|
||||
public void SpeedUp(int increment = 1)
|
||||
{
|
||||
_speed += increment;
|
||||
@ -503,6 +651,12 @@ namespace Learning
|
||||
set { _hasTassles = value; }
|
||||
}
|
||||
|
||||
// You can also define an automatic property in one line
|
||||
// this syntax will create a backing field automatically.
|
||||
// You can set an access modifier on either the getter or the setter (or both)
|
||||
// to restrict its access:
|
||||
public bool IsBroken { get; private set; }
|
||||
|
||||
// Properties can be auto-implemented
|
||||
public int FrameSize
|
||||
{
|
||||
@ -513,13 +667,13 @@ namespace Learning
|
||||
}
|
||||
|
||||
//Method to display the attribute values of this Object.
|
||||
public override string ToString()
|
||||
public virtual string Info()
|
||||
{
|
||||
return "gear: " + gear +
|
||||
" cadence: " + cadence +
|
||||
" speed: " + _speed +
|
||||
" name: " + name +
|
||||
" cards in spokes: " + (hasCardsInSpokes ? "yes" : "no") +
|
||||
return "Gear: " + Gear +
|
||||
" Cadence: " + Cadence +
|
||||
" Speed: " + _speed +
|
||||
" Name: " + Name +
|
||||
" Cards in Spokes: " + (_hasCardsInSpokes ? "yes" : "no") +
|
||||
"\n------------------------------\n"
|
||||
;
|
||||
}
|
||||
@ -527,10 +681,11 @@ namespace Learning
|
||||
// Methods can also be static. It can be useful for helper methods
|
||||
public static bool DidWeCreateEnoughBycles()
|
||||
{
|
||||
// Within a static method, we only can reference static class memebers
|
||||
return bicyclesCreated > 9000;
|
||||
// Within a static method, we only can reference static class members
|
||||
return BicyclesCreated > 9000;
|
||||
} // If your class only needs static members, consider marking the class itself as static.
|
||||
|
||||
|
||||
} // end class Bicycle
|
||||
|
||||
// PennyFarthing is a subclass of Bicycle
|
||||
@ -541,20 +696,27 @@ namespace Learning
|
||||
|
||||
// calling parent constructor
|
||||
public PennyFarthing(int startCadence, int startSpeed) :
|
||||
base(startCadence, startSpeed, 0, "PennyFarthing", true)
|
||||
base(startCadence, startSpeed, 0, "PennyFarthing", true, BikeBrand.Electra)
|
||||
{
|
||||
}
|
||||
|
||||
public override void SetGear(int gear)
|
||||
protected override int Gear
|
||||
{
|
||||
gear = 0;
|
||||
get
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new ArgumentException("You can't change gears on a PennyFarthing");
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
public override string Info()
|
||||
{
|
||||
string result = "PennyFarthing bicycle ";
|
||||
result += base.ToString(); // Calling the base version of the method
|
||||
return reuslt;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@ -566,7 +728,7 @@ namespace Learning
|
||||
|
||||
interface IBreakable
|
||||
{
|
||||
bool Broken { get; } // interfaces can contain properties as well as methods, fields & events
|
||||
bool Broken { get; } // interfaces can contain properties as well as methods & events
|
||||
}
|
||||
|
||||
// Class can inherit only one other class, but can implement any amount of interfaces
|
||||
@ -579,7 +741,7 @@ namespace Learning
|
||||
damage += meters;
|
||||
}
|
||||
|
||||
public void Broken
|
||||
public bool Broken
|
||||
{
|
||||
get
|
||||
{
|
||||
@ -587,24 +749,34 @@ namespace Learning
|
||||
}
|
||||
}
|
||||
}
|
||||
} // End Namespace
|
||||
|
||||
/// <summary>
|
||||
/// Used to connect to DB for LinqToSql example.
|
||||
/// EntityFramework Code First is awesome (similar to Ruby's ActiveRecord, but bidirectional)
|
||||
/// http://msdn.microsoft.com/en-us/data/jj193542.aspx
|
||||
/// </summary>
|
||||
public class BikeRespository : DbSet
|
||||
{
|
||||
public BikeRespository()
|
||||
: base()
|
||||
{
|
||||
}
|
||||
|
||||
public DbSet<Bicycle> Bikes { get; set; }
|
||||
}
|
||||
} // End Namespace
|
||||
```
|
||||
|
||||
## Topics Not Covered
|
||||
|
||||
* Flags
|
||||
* Attributes
|
||||
* Generics (T), Delegates, Func, Actions, lambda expressions
|
||||
* Static properties
|
||||
* Exceptions, Abstraction
|
||||
* LINQ
|
||||
* ASP.NET (Web Forms/MVC/WebMatrix)
|
||||
* Winforms
|
||||
* Windows Presentation Foundation (WPF)
|
||||
|
||||
|
||||
|
||||
## Further Reading
|
||||
|
||||
* [DotNetPerls](http://www.dotnetperls.com)
|
||||
|
@ -1,11 +1,19 @@
|
||||
---
|
||||
language: bash
|
||||
contributors:
|
||||
- ["Jake Prather", "http:#github.com/JakeHP"]
|
||||
- ["kultprok", "http://www.kulturproktologie.de"]
|
||||
filename: LearnBash-de.bash
|
||||
lang: de-de
|
||||
---
|
||||
category: tool
|
||||
tool: bash
|
||||
lang: de-de
|
||||
contributors:
|
||||
- ["Max Yankov", "https://github.com/golergka"]
|
||||
- ["Darren Lin", "https://github.com/CogBear"]
|
||||
translators:
|
||||
- ["kultprok", "http://www.kulturproktologie.de"]
|
||||
filename: LearnBash-de.sh
|
||||
---
|
||||
|
||||
Bash ist der Name der Unix-Shell, die als Shell des GNU-Betriebssystems und auch als Standard-Shell von Linux und Mac OS X ausgeliefert wurde.
|
||||
Beinahe alle der folgenden Beispiele können als Teile eines Shell-Skripts oder direkt in der Shell ausgeführt werden.
|
||||
|
||||
[Weitere Informationen \(Englisch\)](http://www.gnu.org/software/bash/manual/bashref.html)
|
||||
|
||||
```bash
|
||||
#!/bin/sh
|
||||
|
419
de-de/elixir-de.html.markdown
Normal file
419
de-de/elixir-de.html.markdown
Normal file
@ -0,0 +1,419 @@
|
||||
---
|
||||
language: elixir
|
||||
contributors:
|
||||
- ["Joao Marques", "http://github.com/mrshankly"]
|
||||
translators:
|
||||
- ["Gregor Große-Bölting", "http://www.ideen-und-soehne.de"]
|
||||
filename: learnelixir-de.ex
|
||||
lang: de-de
|
||||
---
|
||||
|
||||
Elixir ist eine moderne, funktionale Sprache für die Erlang VM. Sie ist voll
|
||||
kompatibel mit Erlang, verfügt aber über eine freundlichere Syntax und bringt
|
||||
viele Features mit.
|
||||
|
||||
```ruby
|
||||
|
||||
# Einzeilige Kommentare werden mit der Raute gesetzt.
|
||||
|
||||
# Es gibt keine mehrzeiligen Kommentare;
|
||||
# es ist aber problemlos möglich mehrere einzeilige Kommentare hintereinander
|
||||
# zu setzen (so wie hier).
|
||||
|
||||
# Mit 'iex' ruft man die Elixir-Shell auf.
|
||||
# Zum kompilieren von Modulen dient der Befehl 'elixirc'.
|
||||
|
||||
# Beide Befehle sollten als Umgebungsvariable gesetzt sein, wenn Elixir korrekt
|
||||
# installiert wurde.
|
||||
|
||||
## ---------------------------
|
||||
## -- Basistypen
|
||||
## ---------------------------
|
||||
|
||||
# Es gibt Nummern:
|
||||
3 # Integer
|
||||
0x1F # Integer
|
||||
3.0 # Float
|
||||
|
||||
# Atome, das sind Literale, sind Konstanten mit Namen. Sie starten mit einem
|
||||
# ':'.
|
||||
:hello # Atom
|
||||
|
||||
# Außerdem gibt es Tupel, deren Werte im Arbeitsspeicher vorgehalten werden.
|
||||
{1,2,3} # Tupel
|
||||
|
||||
# Die Werte innerhalb eines Tupels können mit der 'elem'-Funktion ausgelesen
|
||||
# werden:
|
||||
elem({1, 2, 3}, 0) # => 1
|
||||
|
||||
# Listen sind als verkettete Listen implementiert.
|
||||
[1, 2, 3] # list
|
||||
|
||||
# Auf Kopf und Rest einer Liste kann wie folgt zugegriffen werden:
|
||||
[ kopf | rest ] = [1,2,3]
|
||||
kopf # => 1
|
||||
rest # => [2, 3]
|
||||
|
||||
# In Elixir, wie auch in Erlang, kennzeichnet '=' ein 'pattern matching'
|
||||
# (Musterabgleich) und keine Zuweisung.
|
||||
# Das heißt, dass die linke Seite auf die rechte Seite 'abgeglichen' wird.
|
||||
# Auf diese Weise kann im Beispiel oben auf Kopf und Rest der Liste zugegriffen
|
||||
# werden.
|
||||
|
||||
# Ein Musterabgleich wird einen Fehler werfen, wenn die beiden Seiten nicht
|
||||
# zusammenpassen.
|
||||
# Im folgenden Beispiel haben die Tupel eine unterschiedliche Anzahl an
|
||||
# Elementen:
|
||||
{a, b, c} = {1, 2} #=> ** (MatchError) no match of right hand side value: {1,2}
|
||||
|
||||
# Es gibt außerdem 'binaries',
|
||||
<<1,2,3>> # binary.
|
||||
|
||||
# Strings und 'char lists'
|
||||
"hello" # String
|
||||
'hello' # Char-Liste
|
||||
|
||||
# ... und mehrzeilige Strings
|
||||
"""
|
||||
Ich bin ein
|
||||
mehrzeiliger String.
|
||||
"""
|
||||
#=> "Ich bin ein\nmehrzeiliger String.\n"
|
||||
|
||||
# Alles Strings werden in UTF-8 enkodiert:
|
||||
"héllò" #=> "héllò"
|
||||
|
||||
# Eigentlich sind Strings in Wahrheit nur binaries und 'char lists' einfach
|
||||
# Listen.
|
||||
<<?a, ?b, ?c>> #=> "abc"
|
||||
[?a, ?b, ?c] #=> 'abc'
|
||||
|
||||
# In Elixir gibt `?a` den ASCII-Integer für den Buchstaben zurück.
|
||||
?a #=> 97
|
||||
|
||||
# Um Listen zu verbinden gibt es den Operator '++', für binaries nutzt man '<>'
|
||||
[1,2,3] ++ [4,5] #=> [1,2,3,4,5]
|
||||
'hello ' ++ 'world' #=> 'hello world'
|
||||
|
||||
<<1,2,3>> <> <<4,5>> #=> <<1,2,3,4,5>>
|
||||
"hello " <> "world" #=> "hello world"
|
||||
|
||||
## ---------------------------
|
||||
## -- Operatoren
|
||||
## ---------------------------
|
||||
|
||||
# Einfache Arithmetik
|
||||
1 + 1 #=> 2
|
||||
10 - 5 #=> 5
|
||||
5 * 2 #=> 10
|
||||
10 / 2 #=> 5.0
|
||||
|
||||
# In Elixir gibt der Operator '/' immer einen Float-Wert zurück.
|
||||
|
||||
# Für Division mit ganzzahligen Ergebnis gibt es 'div'
|
||||
div(10, 2) #=> 5
|
||||
|
||||
# Um den Rest der ganzzahligen Division zu erhalten gibt es 'rem'
|
||||
rem(10, 3) #=> 1
|
||||
|
||||
# Natürlich gibt es auch Operatoren für Booleans: 'or', 'and' und 'not'. Diese
|
||||
# Operatoren erwarten einen Boolean als erstes Argument.
|
||||
true and true #=> true
|
||||
false or true #=> true
|
||||
# 1 and true #=> ** (ArgumentError) argument error
|
||||
|
||||
# Elixir bietet auch '||', '&&' und '!', die Argumente jedweden Typs
|
||||
# akzeptieren. Alle Werte außer 'false' und 'nil' werden zu wahr evaluiert.
|
||||
1 || true #=> 1
|
||||
false && 1 #=> false
|
||||
nil && 20 #=> nil
|
||||
|
||||
!true #=> false
|
||||
|
||||
# Für Vergleiche gibt es die Operatoren `==`, `!=`, `===`, `!==`, `<=`, `>=`,
|
||||
# `<` und `>`
|
||||
1 == 1 #=> true
|
||||
1 != 1 #=> false
|
||||
1 < 2 #=> true
|
||||
|
||||
# '===' und '!==' sind strikter beim Vergleich von Integern und Floats:
|
||||
1 == 1.0 #=> true
|
||||
1 === 1.0 #=> false
|
||||
|
||||
# Es ist außerdem möglich zwei verschiedene Datentypen zu vergleichen:
|
||||
1 < :hello #=> true
|
||||
|
||||
# Die gesamte Ordnung über die Datentypen ist wie folgt definiert:
|
||||
# number < atom < reference < functions < port < pid < tuple < list < bitstring
|
||||
|
||||
# Um Joe Armstrong zu zitieren: "The actual order is not important, but that a
|
||||
# total ordering is well defined is important."
|
||||
|
||||
## ---------------------------
|
||||
## -- Kontrollstrukturen
|
||||
## ---------------------------
|
||||
|
||||
# Es gibt die `if`-Verzweigung
|
||||
if false do
|
||||
"Dies wird nie jemand sehen..."
|
||||
else
|
||||
"...aber dies!"
|
||||
end
|
||||
|
||||
# ...und ebenso `unless`
|
||||
unless true do
|
||||
"Dies wird nie jemand sehen..."
|
||||
else
|
||||
"...aber dies!"
|
||||
end
|
||||
|
||||
# Du erinnerst dich an 'pattern matching'? Viele Kontrollstrukturen in Elixir
|
||||
# arbeiten damit.
|
||||
|
||||
# 'case' erlaubt es uns Werte mit vielerlei Mustern zu vergleichen.
|
||||
case {:one, :two} do
|
||||
{:four, :five} ->
|
||||
"Das wird nicht passen"
|
||||
{:one, x} ->
|
||||
"Das schon und außerdem wird es ':two' dem Wert 'x' zuweisen."
|
||||
_ ->
|
||||
"Dieser Fall greift immer."
|
||||
end
|
||||
|
||||
# Es ist eine übliche Praxis '_' einen Wert zuzuweisen, sofern dieser Wert
|
||||
# nicht weiter verwendet wird.
|
||||
# Wenn wir uns zum Beispiel nur für den Kopf einer Liste interessieren:
|
||||
[kopf | _] = [1,2,3]
|
||||
kopf #=> 1
|
||||
|
||||
# Für bessere Lesbarkeit können wir auch das Folgende machen:
|
||||
[kopf | _rest] = [:a, :b, :c]
|
||||
kopf #=> :a
|
||||
|
||||
# Mit 'cond' können diverse Bedingungen zur selben Zeit überprüft werden. Man
|
||||
# benutzt 'cond' statt viele if-Verzweigungen zu verschachteln.
|
||||
cond do
|
||||
1 + 1 == 3 ->
|
||||
"Ich werde nie aufgerufen."
|
||||
2 * 5 == 12 ->
|
||||
"Ich auch nicht."
|
||||
1 + 2 == 3 ->
|
||||
"Aber ich!"
|
||||
end
|
||||
|
||||
# Es ist üblich eine letzte Bedingung einzufügen, die immer zu wahr evaluiert.
|
||||
cond do
|
||||
1 + 1 == 3 ->
|
||||
"Ich werde nie aufgerufen."
|
||||
2 * 5 == 12 ->
|
||||
"Ich auch nicht."
|
||||
true ->
|
||||
"Aber ich! (dies ist im Grunde ein 'else')"
|
||||
end
|
||||
|
||||
# 'try/catch' wird verwendet um Werte zu fangen, die zuvor 'geworfen' wurden.
|
||||
# Das Konstrukt unterstützt außerdem eine 'after'-Klausel die aufgerufen wird,
|
||||
# egal ob zuvor ein Wert gefangen wurde.
|
||||
try do
|
||||
throw(:hello)
|
||||
catch
|
||||
nachricht -> "#{nachricht} gefangen."
|
||||
after
|
||||
IO.puts("Ich bin die 'after'-Klausel.")
|
||||
end
|
||||
#=> Ich bin die 'after'-Klausel.
|
||||
# ":hello gefangen"
|
||||
|
||||
## ---------------------------
|
||||
## -- Module und Funktionen
|
||||
## ---------------------------
|
||||
|
||||
# Anonyme Funktionen (man beachte den Punkt)
|
||||
square = fn(x) -> x * x end
|
||||
square.(5) #=> 25
|
||||
|
||||
# Anonyme Funktionen unterstützen auch 'pattern' und 'guards'. Guards erlauben
|
||||
# es die Mustererkennung zu justieren und werden mit dem Schlüsselwort 'when'
|
||||
# eingeführt:
|
||||
f = fn
|
||||
x, y when x > 0 -> x + y
|
||||
x, y -> x * y
|
||||
end
|
||||
|
||||
f.(1, 3) #=> 4
|
||||
f.(-1, 3) #=> -3
|
||||
|
||||
# Elixir bietet zahlreiche eingebaute Funktionen. Diese sind im gleichen
|
||||
# Geltungsbereich ('scope') verfügbar.
|
||||
is_number(10) #=> true
|
||||
is_list("hello") #=> false
|
||||
elem({1,2,3}, 0) #=> 1
|
||||
|
||||
# Mehrere Funktionen können in einem Modul gruppiert werden. Innerhalb eines
|
||||
# Moduls ist es möglich mit dem Schlüsselwort 'def' eine Funktion zu
|
||||
# definieren.
|
||||
defmodule Math do
|
||||
def sum(a, b) do
|
||||
a + b
|
||||
end
|
||||
|
||||
def square(x) do
|
||||
x * x
|
||||
end
|
||||
end
|
||||
|
||||
Math.sum(1, 2) #=> 3
|
||||
Math.square(3) #=> 9
|
||||
|
||||
# Um unser einfaches Mathe-Modul zu kompilieren muss es unter 'math.ex'
|
||||
# gesichert werden. Anschließend kann es mit 'elixirc' im Terminal aufgerufen
|
||||
# werden: elixirc math.ex
|
||||
|
||||
# Innerhalb eines Moduls definieren wir private Funktionen mit 'defp'. Eine
|
||||
# Funktion, die mit 'def' erstellt wurde, kann von anderen Modulen aufgerufen
|
||||
# werden; eine private Funktion kann nur lokal angesprochen werden.
|
||||
defmodule PrivateMath do
|
||||
def sum(a, b) do
|
||||
do_sum(a, b)
|
||||
end
|
||||
|
||||
defp do_sum(a, b) do
|
||||
a + b
|
||||
end
|
||||
end
|
||||
|
||||
PrivateMath.sum(1, 2) #=> 3
|
||||
# PrivateMath.do_sum(1, 2) #=> ** (UndefinedFunctionError)
|
||||
|
||||
# Auch Funktionsdeklarationen unterstützen 'guards' und Mustererkennung:
|
||||
defmodule Geometry do
|
||||
def area({:rectangle, w, h}) do
|
||||
w * h
|
||||
end
|
||||
|
||||
def area({:circle, r}) when is_number(r) do
|
||||
3.14 * r * r
|
||||
end
|
||||
end
|
||||
|
||||
Geometry.area({:rectangle, 2, 3}) #=> 6
|
||||
Geometry.area({:circle, 3}) #=> 28.25999999999999801048
|
||||
# Geometry.area({:circle, "not_a_number"})
|
||||
#=> ** (FunctionClauseError) no function clause matching in Geometry.area/1
|
||||
|
||||
# Wegen der Unveränderlichkeit von Variablen ist Rekursion ein wichtiger
|
||||
# Bestandteil von Elixir.
|
||||
defmodule Recursion do
|
||||
def sum_list([head | tail], acc) do
|
||||
sum_list(tail, acc + head)
|
||||
end
|
||||
|
||||
def sum_list([], acc) do
|
||||
acc
|
||||
end
|
||||
end
|
||||
|
||||
Recursion.sum_list([1,2,3], 0) #=> 6
|
||||
|
||||
# Elixir-Module unterstützen Attribute. Es gibt eingebaute Attribute, ebenso
|
||||
# ist es möglich eigene Attribute hinzuzufügen.
|
||||
defmodule MyMod do
|
||||
@moduledoc """
|
||||
Dies ist ein eingebautes Attribut in einem Beispiel-Modul
|
||||
"""
|
||||
|
||||
@my_data 100 # Dies ist ein selbst-definiertes Attribut.
|
||||
IO.inspect(@my_data) #=> 100
|
||||
end
|
||||
|
||||
## ---------------------------
|
||||
## -- 'Records' und Ausnahmebehandlung
|
||||
## ---------------------------
|
||||
|
||||
# 'Records' sind im Grunde Strukturen, die es erlauben einem Wert einen eigenen
|
||||
# Namen zuzuweisen.
|
||||
defrecord Person, name: nil, age: 0, height: 0
|
||||
|
||||
joe_info = Person.new(name: "Joe", age: 30, height: 180)
|
||||
#=> Person[name: "Joe", age: 30, height: 180]
|
||||
|
||||
# Zugriff auf den Wert von 'name'
|
||||
joe_info.name #=> "Joe"
|
||||
|
||||
# Den Wert von 'age' überschreiben
|
||||
joe_info = joe_info.age(31) #=> Person[name: "Joe", age: 31, height: 180]
|
||||
|
||||
# Der 'try'-Block wird zusammen mit dem 'rescue'-Schlüsselwort dazu verwendet,
|
||||
# um Ausnahmen beziehungsweise Fehler zu behandeln.
|
||||
try do
|
||||
raise "Irgendein Fehler."
|
||||
rescue
|
||||
RuntimeError -> "Laufzeit-Fehler gefangen."
|
||||
_error -> "Und dies fängt jeden Fehler."
|
||||
end
|
||||
|
||||
# Alle Ausnahmen haben das Attribut 'message'
|
||||
try do
|
||||
raise "ein Fehler"
|
||||
rescue
|
||||
x in [RuntimeError] ->
|
||||
x.message
|
||||
end
|
||||
|
||||
## ---------------------------
|
||||
## -- Nebenläufigkeit
|
||||
## ---------------------------
|
||||
|
||||
# Elixir beruht auf dem Aktoren-Model zur Behandlung der Nebenläufigkeit. Alles
|
||||
# was man braucht um in Elixir nebenläufige Programme zu schreiben sind drei
|
||||
# Primitive: Prozesse erzeugen, Nachrichten senden und Nachrichten empfangen.
|
||||
|
||||
# Um einen neuen Prozess zu erzeugen nutzen wir die 'spawn'-Funktion, die
|
||||
# wiederum eine Funktion als Argument entgegen nimmt.
|
||||
f = fn -> 2 * 2 end #=> #Function<erl_eval.20.80484245>
|
||||
spawn(f) #=> #PID<0.40.0>
|
||||
|
||||
# 'spawn' gibt eine pid (einen Identifikator des Prozesses) zurück. Diese kann
|
||||
# nun verwendet werden, um Nachrichten an den Prozess zu senden. Um
|
||||
# zu senden nutzen wir den '<-' Operator. Damit das alles Sinn macht müssen wir
|
||||
# in der Lage sein Nachrichten zu empfangen. Dies wird mit dem
|
||||
# 'receive'-Mechanismus sichergestellt:
|
||||
defmodule Geometry do
|
||||
def area_loop do
|
||||
receive do
|
||||
{:rectangle, w, h} ->
|
||||
IO.puts("Area = #{w * h}")
|
||||
area_loop()
|
||||
{:circle, r} ->
|
||||
IO.puts("Area = #{3.14 * r * r}")
|
||||
area_loop()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Kompiliere das Modul, starte einen Prozess und gib die 'area_loop' Funktion
|
||||
# in der Shell mit, etwa so:
|
||||
pid = spawn(fn -> Geometry.area_loop() end) #=> #PID<0.40.0>
|
||||
|
||||
# Sende eine Nachricht an die 'pid', die ein Muster im 'receive'-Ausdruck
|
||||
# erfüllt:
|
||||
pid <- {:rectangle, 2, 3}
|
||||
#=> Area = 6
|
||||
# {:rectangle,2,3}
|
||||
|
||||
pid <- {:circle, 2}
|
||||
#=> Area = 12.56000000000000049738
|
||||
# {:circle,2}
|
||||
|
||||
# Die Shell selbst ist ein Prozess und mit dem Schlüsselwort 'self' kann man
|
||||
# die aktuelle pid herausfinden.
|
||||
self() #=> #PID<0.27.0>
|
||||
|
||||
```
|
||||
|
||||
## Referenzen und weitere Lektüre
|
||||
|
||||
* [Getting started guide](http://elixir-lang.org/getting_started/1.html) auf der [elixir Website](http://elixir-lang.org)
|
||||
* [Elixir Documentation](http://elixir-lang.org/docs/master/)
|
||||
* ["Learn You Some Erlang for Great Good!"](http://learnyousomeerlang.com/) von Fred Hebert
|
||||
* "Programming Erlang: Software for a Concurrent World" von Joe Armstrong
|
@ -1,10 +1,10 @@
|
||||
---
|
||||
---
|
||||
category: tool
|
||||
tool: git
|
||||
contributors:
|
||||
- ["Jake Prather", "http:#github.com/JakeHP"]
|
||||
- ["Jake Prather", "http://github.com/JakeHP"]
|
||||
translators:
|
||||
- ["kultprok", "http://www.kulturproktologie.de"]
|
||||
filename: LearnGit-de.txt
|
||||
lang: de-de
|
||||
---
|
||||
|
||||
|
450
de-de/javascript-de.html.markdown
Normal file
450
de-de/javascript-de.html.markdown
Normal file
@ -0,0 +1,450 @@
|
||||
---
|
||||
language: javascript
|
||||
contributors:
|
||||
- ["Adam Brenecki", "http://adam.brenecki.id.au"]
|
||||
translators:
|
||||
- ["ggb", "http://www.ideen-und-soehne.de"]
|
||||
filename: learnjavascript-de.js
|
||||
lang: de-de
|
||||
---
|
||||
|
||||
(Anmerkungen des Original-Autors:)
|
||||
JavaScript wurde im Jahr 1995 von Brendan Eich bei Netscape entwickelt. Ursprünglich war es als einfachere Skriptsprache für Websites gedacht, ergänzent zu Java, das für komplexere Webanwendungen verwendet wird. Die enge Integration in Websites und der in Browser eingebaute Support der Sprache haben dafür gesorgt, dass JavaScript weit häufiger für Web-Frontends verwendet wird als Java.
|
||||
|
||||
Dabei ist JavaScript inzwischen nicht mehr auf Browser beschränkt: Node.js, ein Projekt, dass eine eigene Laufzeitumgebung auf Grundlage von Google Chromes V8 mitbringt, wird derzeit immer populärer.
|
||||
|
||||
Feedback ist herzlich Willkommen! Der ursprüngliche Autor ist unter [@adambrenecki](https://twitter.com/adambrenecki) oder [adam@brenecki.id.au](mailto:adam@brenecki.id.au) zu erreichen. Der Übersetzer unter [gregorbg@web.de](mailto:gregorbg@web.id.au).
|
||||
|
||||
```js
|
||||
// Kommentare werden wie in C gesetzt: Einzeilige Kommentare starten mit zwei
|
||||
// Slashes
|
||||
/* während mehrzeilige Kommentare mit einem
|
||||
Slash und einem Stern anfangen und enden */
|
||||
|
||||
// Statements können mit einem Semikolon beendet werden
|
||||
machWas();
|
||||
|
||||
// ...müssen sie aber nicht, weil Semikola automatisch eingefügt werden, wenn
|
||||
// eine neue Zeile beginnt, abgesehen von einigen Ausnahmen.
|
||||
machWas()
|
||||
|
||||
// Obwohl wir uns für den Anfang nicht um diese Ausnahmen kümmern müssen ist
|
||||
// es besser die Semikola immer zu setzen.
|
||||
|
||||
///////////////////////////////////
|
||||
// 1. Nummern, Strings und Operationen
|
||||
|
||||
// JavaScript hat einen Nummern-Typ (64-bit IEEE 754 double).
|
||||
3; // = 3
|
||||
1.5; // = 1.5
|
||||
|
||||
// Alle grundlegenden arithmetischen Operationen arbeiten wie erwartet.
|
||||
1 + 1; // = 2
|
||||
8 - 1; // = 7
|
||||
10 * 2; // = 20
|
||||
35 / 5; // = 7
|
||||
|
||||
// Division funktioniert auch mit einem Ergebnis nach dem Komma.
|
||||
5 / 2; // = 2.5
|
||||
|
||||
// Bit-weise Operationen sind auch möglich; wenn eine Bit-weise Operation
|
||||
// ausgeführt wird, wird die Fließkomma-Zahl in einen 32-bit Integer (mit
|
||||
// Vorzeichen) umgewandelt.
|
||||
1 << 2; // = 4
|
||||
|
||||
// Die Rangfolge der Operationen kann mit Klammern erzwungen werden.
|
||||
(1 + 3) * 2; // = 8
|
||||
|
||||
// Es gibt drei spezielle, nicht-reale Nummern-Werte:
|
||||
Infinity; // Ergebnis von z. B. 1 / 0
|
||||
-Infinity; // Ergebnis von z. B. -1 / 0
|
||||
NaN; // Ergebnis von z. B. 0 / 0
|
||||
|
||||
// Es gibt auch einen Boolean-Typ (für Wahrheitswerte).
|
||||
true;
|
||||
false;
|
||||
|
||||
// Strings werden mit ' oder " erzeugt.
|
||||
'abc';
|
||||
"Hello, world";
|
||||
|
||||
// Für die Negation wird das ! benutzt.
|
||||
!true; // = false
|
||||
!false; // = true
|
||||
|
||||
// Gleichheit wird mit == geprüft.
|
||||
1 == 1; // = true
|
||||
2 == 1; // = false
|
||||
|
||||
// Ungleichheit wird mit != überprüft.
|
||||
1 != 1; // = false
|
||||
2 != 1; // = true
|
||||
|
||||
// Andere Vergleichsoperatoren sind
|
||||
1 < 10; // = true
|
||||
1 > 10; // = false
|
||||
2 <= 2; // = true
|
||||
2 >= 2; // = true
|
||||
|
||||
// Strings können mit + verbunden
|
||||
"Hello " + "world!"; // = "Hello world!"
|
||||
|
||||
// und mit < und > verglichen werden.
|
||||
"a" < "b"; // = true
|
||||
|
||||
// Für den Vergleich von Werten wird eine Typumwandlung erzwungen...
|
||||
"5" == 5; // = true
|
||||
|
||||
// ...solange man nicht === verwendet.
|
||||
"5" === 5; // = false
|
||||
|
||||
// Auf einzelne Buchstaben innerhalb eines Strings kann mit der Methode
|
||||
// charAt zugegriffen werden
|
||||
"This is a string".charAt(0); // = "T"
|
||||
|
||||
// Es gibt außerdem die Werte 'null' und 'undefined'
|
||||
null; // wird verwendet um einen vorsätzlich gewählten 'Nicht'-Wert anzuzeigen
|
||||
undefined; // wird verwendet um anzuzeigen, dass der Wert (aktuell) nicht
|
||||
// verfügbar ist (obwohl genau genommen undefined selbst einen Wert
|
||||
// darstellt)
|
||||
|
||||
// false, null, undefined, NaN, 0 und "" sind 'falsy', d. h. alles andere ist
|
||||
// wahr. Man beachte, dass 0 falsch und "0" wahr ist, obwohl 0 == "0".
|
||||
|
||||
///////////////////////////////////
|
||||
// 2. Variablen, Arrays und Objekte
|
||||
|
||||
// Variablen werden mit dem Schlüsselwort 'var' und einem frei wählbaren
|
||||
// Bezeichner deklariert. JavaScript ist dynamisch typisiert, so dass man einer
|
||||
// Variable keinen Typ zuweisen muss. Die Zuweisung verwendet ein einfaches =.
|
||||
var einWert = 5;
|
||||
|
||||
// Wenn man das Schlüsselwort 'var' weglässt, bekommt man keinen Fehler
|
||||
einAndererWert = 10;
|
||||
|
||||
// ...aber die Variable wird im globalen Kontext erzeugt, nicht in dem Kontext,
|
||||
// in dem sie erzeugt wurde.
|
||||
|
||||
// Variablen die erzeugt wurden ohne ihnen einen Wert zuzuweisen, erhalten den
|
||||
// Wert 'undefined'.
|
||||
var einDritterWert; // = undefined
|
||||
|
||||
// Es existiert eine Kurzform, um mathematische Operationen mit Variablen
|
||||
// auszuführen:
|
||||
einWert += 5; // äquivalent zu einWert = einWert + 5; einWert ist nun also 10
|
||||
einWert *= 10; // einWert ist nach dieser Operation 100
|
||||
|
||||
// Und es existiert eine weitere, sogar noch kürzere Form, um 1 zu addieren
|
||||
// oder zu subtrahieren
|
||||
einWert++; // nun ist einWert 101
|
||||
einWert--; // wieder 100
|
||||
|
||||
// Arrays sind geordnete Listen von Werten irgendeines Typs
|
||||
var myArray = ["Hello", 45, true];
|
||||
|
||||
// Auf einzelne Elemente eines Arrays kann zugegriffen werden, in dem der Index
|
||||
// in eckigen Klammern hinter das Array geschrieben werden. Die Indexierung
|
||||
// beginnt bei 0.
|
||||
myArray[1]; // = 45
|
||||
|
||||
// Die Objekte in JavaScript entsprechen 'dictionaries' oder 'maps' in anderen
|
||||
// Sprachen: es handelt sich um ungeordnete Schlüssel-Wert-Paare.
|
||||
var myObj = { key1: "Hello", key2: "World" };
|
||||
|
||||
// Schlüssel sind Strings, aber es werden keine Anführungszeichen benötigt,
|
||||
// sofern es sich um reguläre JavaScript-Bezeichner handelt. Werte können von
|
||||
// jedem Typ sein.
|
||||
var myObj = { myKey: "myValue", "my other key": 4 };
|
||||
|
||||
// Auf Attribute von Objekten kann ebenfalls mit eckigen Klammern zugegriffen
|
||||
// werden,
|
||||
myObj["my other key"]; // = 4
|
||||
|
||||
// ... oder in dem man die Punkt-Notation verwendet, vorausgesetzt es handelt
|
||||
// sich bei dem Schlüssel um einen validen Bezeichner.
|
||||
myObj.myKey; // = "myValue"
|
||||
|
||||
// Objekte sind veränderlich, Werte können verändert und neue Schlüssel
|
||||
// hinzugefügt werden.
|
||||
myObj.myThirdKey = true;
|
||||
|
||||
// Der Zugriff auf einen noch nicht definierten Schlüssel, liefert ein
|
||||
// undefined.
|
||||
myObj.myFourthKey; // = undefined
|
||||
|
||||
///////////////////////////////////
|
||||
// 3. Logik und Kontrollstrukturen
|
||||
|
||||
// Die if-Struktur arbeitet, wie man es erwartet.
|
||||
var count = 1;
|
||||
if (count == 3){
|
||||
// wird evaluiert, wenn count gleich 3 ist
|
||||
} else if (count == 4) {
|
||||
// wird evaluiert, wenn count gleich 4 ist
|
||||
} else {
|
||||
// wird evaluiert, wenn es weder 3 noch 4 ist
|
||||
}
|
||||
|
||||
// Genauso 'while'.
|
||||
while (true) {
|
||||
// Eine unendliche Schleife!
|
||||
}
|
||||
|
||||
// Do-while-Scheifen arbeiten wie while-Schleifen, abgesehen davon, dass sie
|
||||
// immer mindestens einmal ausgeführt werden.
|
||||
var input;
|
||||
do {
|
||||
input = getInput();
|
||||
} while ( !isValid( input ) )
|
||||
|
||||
// Die for-Schleife arbeitet genau wie in C und Java:
|
||||
// Initialisierung; Bedingung, unter der die Ausführung fortgesetzt wird;
|
||||
// Iteration.
|
||||
for ( var i = 0; i < 5; i++ ) {
|
||||
// wird 5-mal ausgeführt
|
||||
}
|
||||
|
||||
// '&&' ist das logische und, '||' ist das logische oder
|
||||
if (house.size == "big" && house.colour == "blue"){
|
||||
house.contains = "bear";
|
||||
// Die Größe des Hauses ist groß und die Farbe blau.
|
||||
}
|
||||
if (colour == "red" || colour == "blue"){
|
||||
// Die Farbe ist entweder rot oder blau.
|
||||
}
|
||||
|
||||
// Die Auswertung von '&&' und '||' erfolgt so, dass abgebrochen wird, wenn die
|
||||
// Bedingung erfüllt ist (bei oder) oder nicht-erfüllt ist (bei und). Das ist
|
||||
// nützlich, um einen Default-Wert zu setzen.
|
||||
var name = otherName || "default";
|
||||
|
||||
///////////////////////////////////
|
||||
// 4. Funktionen, Geltungsbereich und Closures
|
||||
|
||||
// In JavaScript werden Funktionen mit dem Schlüsselwort 'function' deklariert.
|
||||
function myFunction(thing){
|
||||
return thing.toUpperCase();
|
||||
}
|
||||
myFunction("foo"); // = "FOO"
|
||||
|
||||
// In JavaScript sind Funktionen 'Bürger erster Klasse', also können sie wie
|
||||
// Variablen verwendet und als Parameter anderen Funktionen übergeben werden
|
||||
// - zum Beispiel, um einen 'event handler' zu 'beliefern'.
|
||||
function myFunction() {
|
||||
// wird ausgeführt, nachdem 5 Sekunden vergangen sind
|
||||
}
|
||||
setTimeout(myFunction, 5000);
|
||||
|
||||
// Funktionen können auch deklariert werden, ohne ihnen einen Namen zuzuweisen.
|
||||
// Es ist möglich diese anonymen Funktionen direkt als (oder im) Argument
|
||||
// einer anderen Funktion zu definieren.
|
||||
setTimeout(function() {
|
||||
// wird ausgeführt, nachdem 5 Sekunden vergangen sind
|
||||
}, 5000);
|
||||
|
||||
// JavaScript hat einen Geltungsbereich, der sich auf Funktionen erstreckt:
|
||||
// Funktionen haben ihren eigenen Geltungsbereich, andere Blöcke nicht.
|
||||
if(true) {
|
||||
var i = 5;
|
||||
}
|
||||
i; // = 5 - nicht undefined, wie man es von einer Sprache erwarten würde, die
|
||||
// ihren Geltungsbereich nach Blöcken richtet
|
||||
|
||||
// Daraus ergibt sich ein bestimmtes Muster für sofort-ausführbare, anonyme
|
||||
// Funktionen, die es vermeiden, dass der globale Geltungsbereich von Variablen
|
||||
// 'verschmutzt' wird.
|
||||
(function(){
|
||||
var temporary = 5;
|
||||
// Auf eine Variable im globalen Geltungsbereich kann zugegriffen werden,
|
||||
// sofern sie im globalen Objekt definiert ist (in einem Webbrowser ist
|
||||
// dies immer das 'window'-Objekt, in anderen Umgebungen, bspw. Node.js,
|
||||
// kann das anders aussehen).
|
||||
window.permanent = 10;
|
||||
})();
|
||||
temporary; // wirft einen ReferenceError
|
||||
permanent; // = 10
|
||||
|
||||
// Eines der mächtigsten Charakteristika von JavaScript sind Closures. Wird
|
||||
// eine Funktion innerhalb einer anderen Funktion definiert, dann hat die
|
||||
// innere Funktion Zugriff auf alle Variablen der äußeren Funktion, sogar dann,
|
||||
// wenn die äußere Funktion beendet wurde.
|
||||
function sayHelloInFiveSeconds(name){
|
||||
var prompt = "Hello, " + name + "!";
|
||||
function inner(){
|
||||
alert(prompt);
|
||||
}
|
||||
setTimeout(inner, 5000);
|
||||
// setTimeout wird asynchron ausgeführt. Also wird sayHelloInFiveSeconds
|
||||
// sofort verlassen und setTimeout wird die innere Funktion 'im nachhinein'
|
||||
// aufrufen. Dennoch: Weil sayHelloInFiveSeconds eine Hülle um die innere
|
||||
// Funktion bildet, hat die innere Funktion immer noch Zugriff auf die
|
||||
// Variable prompt.
|
||||
}
|
||||
sayHelloInFiveSeconds("Adam"); // wird nach 5 Sekunden ein Popup mit der
|
||||
// Nachricht "Hello, Adam!" öffnen.
|
||||
|
||||
///////////////////////////////////
|
||||
// 5. Mehr über Objekte, Konstruktoren und Prototypen
|
||||
|
||||
// Objekte können Funktionen enthalten.
|
||||
var myObj = {
|
||||
myFunc: function(){
|
||||
return "Hello world!";
|
||||
}
|
||||
};
|
||||
myObj.myFunc(); // = "Hello world!"
|
||||
|
||||
// Wenn Funktionen aufgerufen werden, die zu einem Objekt gehören, können sie
|
||||
// auf das eigene Objekt mit dem Schlüsselwort 'this' zugreifen.
|
||||
myObj = {
|
||||
myString: "Hello world!",
|
||||
myFunc: function(){
|
||||
return this.myString;
|
||||
}
|
||||
};
|
||||
myObj.myFunc(); // = "Hello world!"
|
||||
|
||||
// Worauf 'this' gesetzt wird, ist davon abhängig, wie die Funktion aufgerufen
|
||||
// wird, nicht wo sie definiert wurde. Unsere Funktion wird daher nicht
|
||||
// funktionieren, sofern sie außerhalb des Kontextes des Objekts aufgerufen
|
||||
// wird.
|
||||
var myFunc = myObj.myFunc;
|
||||
myFunc(); // = undefined
|
||||
|
||||
// Umgekehrt ist es möglich eine Funktion einem Objekt zuzuweisen und dadurch
|
||||
// Zugriff auf den this-Kontext zu erhalten, sogar dann, wenn die Funktion dem
|
||||
// Objekt nach dessen Definition zugewiesen wird.
|
||||
var myOtherFunc = function(){
|
||||
return this.myString.toUpperCase();
|
||||
}
|
||||
myObj.myOtherFunc = myOtherFunc;
|
||||
myObj.myOtherFunc(); // = "HELLO WORLD!"
|
||||
|
||||
// Wenn eine Funktion mit dem Schlüsselwort 'new' aufgerufen wird, dann wird
|
||||
// ein neues Objekt erzeugt. Funktionen, die darauf ausgelegt sind in dieser
|
||||
// Art aufgerufen zu werden, werden Konstruktoren genannt.
|
||||
var MyConstructor = function(){
|
||||
this.myNumber = 5;
|
||||
}
|
||||
myNewObj = new MyConstructor(); // = {myNumber: 5}
|
||||
myNewObj.myNumber; // = 5
|
||||
|
||||
// Jedes JavaScript-Objekt hat einen Prototyp. Wenn man versucht auf eine
|
||||
// Eigenschaft des Objekts zuzugreifen, das nicht im Objekt selbst existiert,
|
||||
// schaut der Interpreter in dessen Prototyp nach.
|
||||
|
||||
// Einige JavaScript-Implementierungen erlauben den direkten Zugriff auf den
|
||||
// Prototyp eines Objekts durch die magische Eigenschaft __proto__. Obwohl das
|
||||
// nützlich ist, um Prototypen im Allgemeinen zu erklären, ist das nicht Teil
|
||||
// des Standards; zum Standard-Weg der Nutzung von Prototypen kommen wir
|
||||
// später.
|
||||
var myObj = {
|
||||
myString: "Hello world!",
|
||||
};
|
||||
var myPrototype = {
|
||||
meaningOfLife: 42,
|
||||
myFunc: function(){
|
||||
return this.myString.toLowerCase()
|
||||
}
|
||||
};
|
||||
myObj.__proto__ = myPrototype;
|
||||
myObj.meaningOfLife; // = 42
|
||||
|
||||
// Das funktioniert auch bei Funktionen.
|
||||
myObj.myFunc(); // = "hello world!"
|
||||
|
||||
// Sollte die Eigenschaft nicht im Prototypen des Objekts enthalten sein, dann
|
||||
// wird im Prototypen des Prototypen nachgesehen und so weiter.
|
||||
myPrototype.__proto__ = {
|
||||
myBoolean: true
|
||||
};
|
||||
myObj.myBoolean; // = true
|
||||
|
||||
// Dafür wird nichts hin und her kopiert; jedes Objekt speichert eine Referenz
|
||||
// auf seinen Prototypen. Das heißt wenn der Prototyp geändert wird, dann
|
||||
// werden die Änderungen überall sichtbar.
|
||||
myPrototype.meaningOfLife = 43;
|
||||
myObj.meaningOfLife; // = 43
|
||||
|
||||
// Es wurde bereits erwähnt, dass __proto__ nicht zum Standard gehört und es
|
||||
// gibt ebenso keinen Standard-Weg, um den Prototyp eines existierenden Objekts
|
||||
// zu ändern. Es gibt dennoch zwei Wege, wie man ein neues Objekt mit einem
|
||||
// gegebenen Prototypen erzeugt.
|
||||
|
||||
// Der erste Weg ist die Methode Object.create, die eine jüngere Ergänzung des
|
||||
// JavaScript-Standards ist und daher noch nicht in allen Implementierungen
|
||||
// verfügbar.
|
||||
var myObj = Object.create(myPrototype);
|
||||
myObj.meaningOfLife; // = 43
|
||||
|
||||
// Der zweite Weg, der immer funktioniert, hat mit den Konstruktoren zu tun.
|
||||
// Konstruktoren haben eine Eigenschaft, die Prototyp heißt. Dabei handelt es
|
||||
// sich *nicht* um den Prototypen der Konstruktor-Funktion; stattdessen handelt
|
||||
// es sich um den Prototypen, der einem neuen Objekt mitgegeben wird, wenn es
|
||||
// mit dem Konstruktor und dem Schlüsselwort 'new' erzeugt wird.
|
||||
myConstructor.prototype = {
|
||||
getMyNumber: function(){
|
||||
return this.myNumber
|
||||
}
|
||||
};
|
||||
var myNewObj2 = new myConstructor();
|
||||
myNewObj2.getMyNumber(); // = 5
|
||||
|
||||
// Die eingebauten Typen, also strings und numbers, haben auch Konstruktoren,
|
||||
// die zu dem Typ äquivalente Wrapper-Objekte erzeugen.
|
||||
var myNumber = 12;
|
||||
var myNumberObj = new Number(12);
|
||||
myNumber == myNumberObj; // = true
|
||||
|
||||
// Genau genommen: Sie sind nicht exakt äquivalent.
|
||||
typeof(myNumber); // = 'number'
|
||||
typeof(myNumberObj); // = 'object'
|
||||
myNumber === myNumberObj; // = false
|
||||
if (0){
|
||||
// Dieser Teil wird nicht ausgeführt, weil 0 'falsy' ist.
|
||||
}
|
||||
if (Number(0)){
|
||||
// Dieser Teil des Codes wird ausgeführt, weil Number(0) zu wahr evaluiert.
|
||||
}
|
||||
|
||||
// Das Wrapper-Objekt und die regulären, eingebauten Typen, teilen sich einen
|
||||
// Prototyp; so ist es möglich zum Beispiel einem String weitere Funktionen
|
||||
// hinzuzufügen.
|
||||
String.prototype.firstCharacter = function(){
|
||||
return this.charAt(0);
|
||||
}
|
||||
"abc".firstCharacter(); // = "a"
|
||||
|
||||
// Diese Tatsache wird häufig bei einer Methode mit dem Namen 'polyfilling'
|
||||
// verwendet: Dabei wird ein neues Feature von JavaScript in einer älteren
|
||||
// Untermenge der Sprache integriert, so dass bestimmte Funktionen auch in
|
||||
// älteren Umgebungen und Browsern verwendet werden können.
|
||||
|
||||
// Ein Beispiel: Es wurde erwähnt, dass die Methode Object.create nicht in
|
||||
// allen Umgebungen verfügbar ist - wir können sie dennoch verwenden, mit einem
|
||||
// 'polyfill':
|
||||
if (Object.create === undefined){ // überschreib nichts, was eventuell bereits
|
||||
// existiert
|
||||
Object.create = function(proto){
|
||||
// erstelle einen vorübergehenden Konstruktor mit dem richtigen
|
||||
// Prototypen
|
||||
var Constructor = function(){};
|
||||
Constructor.prototype = proto;
|
||||
// verwende es dann, um ein neues Objekt mit einem passenden
|
||||
// Prototypen zurückzugeben
|
||||
return new Constructor();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Zur weiteren Lektüre (englisch)
|
||||
|
||||
Das [Mozilla Developer Network](https://developer.mozilla.org/en-US/docs/Web/JavaScript) bietet eine ausgezeichnete Dokumentation für die Verwendung von JavaScript im Browser. Es ist außerdem ein Wiki und ermöglicht es damit anderen zu helfen, wenn man selbst ein wenig Wissen angesammelt hat.
|
||||
|
||||
MDN's [A re-introduction to JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript) führt sehr viele der hier vorgestellten Konzepte im Detail aus.
|
||||
|
||||
Dieses Tutorial hat nur die Sprache JavaScript vorgestellt; um mehr über den Einsatz in Websites zu lernen, ist es ein guter Start etwas über das [Document Object Model](https://developer.mozilla.org/en-US/docs/Using_the_W3C_DOM_Level_1_Core) zu lernen.
|
||||
|
||||
[JavaScript Garden](http://bonsaiden.github.io/JavaScript-Garden/) ist eine tiefgehende Einführung in die kontra-intuitiven Parts der Sprache.
|
||||
|
||||
Zusätzlich zu direkten Beiträgen zu diesem Artikel ist der Inhalt in Anlehnung an Louie Dinh's Python-Tutorial auf dieser Seite und das [JS Tutorial](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript) des Mozilla Developer Network entstanden.
|
@ -2,6 +2,7 @@
|
||||
language: python
|
||||
contributors:
|
||||
- ["Louie Dinh", "http://ldinh.ca"]
|
||||
translators:
|
||||
- ["kultprok", "http:/www.kulturproktologie.de"]
|
||||
filename: learnpython-de.py
|
||||
lang: de-de
|
||||
|
393
es-es/clojure-es.html.markdown
Normal file
393
es-es/clojure-es.html.markdown
Normal file
@ -0,0 +1,393 @@
|
||||
---
|
||||
language: clojure
|
||||
filename: learnclojure-es.clj
|
||||
contributors:
|
||||
- ["Adam Bard", "http://adambard.com/"]
|
||||
translators:
|
||||
- ["Antonio Hernández Blas", "https://twitter.com/nihilipster"]
|
||||
- ["Guillermo Vayá Pérez", "http://willyfrog.es"]
|
||||
lang: es-es
|
||||
---
|
||||
|
||||
Clojure es un lenguaje de la familia Lisp desarrollado sobre la Máquina Virtual
|
||||
de Java. Tiene un énfasis mayor en la [programación funcional](https://es.wikipedia.org/wiki/Programación_funcional) pura
|
||||
que Common Lisp, pero incluyendo la posibilidad de usar [SMT](https://es.wikipedia.org/wiki/Memoria_transacional) para manipular
|
||||
el estado según se presente.
|
||||
|
||||
Esta combinación le permite gestionar la concurrencia de manera muy sencilla
|
||||
y a menudo automáticamente.
|
||||
|
||||
(Necesitas la versión de Clojure 1.2 o posterior)
|
||||
|
||||
|
||||
```clojure
|
||||
; Los comentatios comienzan con punto y coma.
|
||||
|
||||
; Clojure se escribe mediante "forms" (patrones), los cuales son
|
||||
; listas de objectos entre paréntesis, separados por espacios en blanco.
|
||||
|
||||
; El "reader" (lector) de Clojure asume que el primer objeto es una
|
||||
; función o una macro que se va a llamar, y que el resto son argumentos.
|
||||
|
||||
; El primer form en un archivo debe ser ns, para establecer el namespace (espacio de
|
||||
; nombres)
|
||||
(ns learnclojure)
|
||||
|
||||
; Algunos ejemplos básicos:
|
||||
|
||||
; str crea una cadena de caracteres a partir de sus argumentos
|
||||
(str "Hello" " " "World") ; => "Hello World"
|
||||
|
||||
; Las operaciones matemáticas son sencillas
|
||||
(+ 1 1) ; => 2
|
||||
(- 2 1) ; => 1
|
||||
(* 1 2) ; => 2
|
||||
(/ 2 1) ; => 2
|
||||
|
||||
; La igualdad es =
|
||||
(= 1 1) ; => true
|
||||
(= 2 1) ; => false
|
||||
|
||||
; También es necesaria la negación para las operaciones lógicas
|
||||
(not true) ; => false
|
||||
|
||||
; Cuando se anidan Los patrones, estos funcionan de la manera esperada
|
||||
(+ 1 (- 3 2)) ; = 1 + (3 - 2) => 2
|
||||
|
||||
; Tipos
|
||||
;;;;;;;;;;;;;
|
||||
|
||||
; Clojure usa los tipos de objetos de Java para booleanos, strings (cadenas de
|
||||
; caracteres) y números.
|
||||
; Usa class para saber de qué tipo es.
|
||||
(class 1); Los enteros son java.lang.Long por defecto
|
||||
(class 1.); Los numeros en coma flotante son java.lang.Double
|
||||
(class ""); Los strings van entre comillas dobles, y son
|
||||
; son java.lang.String
|
||||
(class false); Los Booleanos son java.lang.Boolean
|
||||
(class nil); El valor "null" se escribe nil
|
||||
|
||||
; Si quieres crear una lista de datos, precedela con una comilla
|
||||
; simple para evitar su evaluación
|
||||
'(+ 1 2) ; => (+ 1 2)
|
||||
; (que es una abreviatura de (quote (+ 1 2)) )
|
||||
|
||||
; Puedes evaluar una lista precedida por comilla con eval
|
||||
(eval '(+ 1 2)) ; => 3
|
||||
|
||||
; Colecciones & Secuencias
|
||||
;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
; Las Listas están basadas en las listas enlazadas, mientras que los Vectores en
|
||||
; arrays.
|
||||
; ¡Los Vectores y las Listas también son clases de Java!
|
||||
(class [1 2 3]); => clojure.lang.PersistentVector
|
||||
(class '(1 2 3)); => clojure.lang.PersistentList
|
||||
|
||||
; Una lista podría ser escrita como (1 2 3), pero debemos ponerle una
|
||||
; comilla simple delante para evitar que el reader piense que es una función.
|
||||
; Además, (list 1 2 3) es lo mismo que '(1 2 3)
|
||||
|
||||
; Las "Colecciones" son solo grupos de datos
|
||||
; Tanto las listas como los vectores son colecciones:
|
||||
(coll? '(1 2 3)) ; => true
|
||||
(coll? [1 2 3]) ; => true
|
||||
|
||||
; Las "Secuencias" (seqs) son descripciones abstractas de listas de datos.
|
||||
; Solo las listas son seqs.
|
||||
(seq? '(1 2 3)) ; => true
|
||||
(seq? [1 2 3]) ; => false
|
||||
|
||||
; Una seq solo necesita proporcionar una entrada cuando es accedida.
|
||||
; Así que, las seqs pueden ser perezosas -- pueden establecer series infinitas:
|
||||
(range 4) ; => (0 1 2 3)
|
||||
(range) ; => (0 1 2 3 4 ...) (una serie infinita)
|
||||
(take 4 (range)) ; (0 1 2 3)
|
||||
|
||||
; Usa cons para agregar un elemento al inicio de una lista o vector
|
||||
(cons 4 [1 2 3]) ; => (4 1 2 3)
|
||||
(cons 4 '(1 2 3)) ; => (4 1 2 3)
|
||||
|
||||
; conj agregará un elemento a una colección en la forma más eficiente.
|
||||
; Para listas, se añade al inicio. Para vectores, al final.
|
||||
(conj [1 2 3] 4) ; => [1 2 3 4]
|
||||
(conj '(1 2 3) 4) ; => (4 1 2 3)
|
||||
|
||||
; Usa concat para concatenar listas o vectores
|
||||
(concat [1 2] '(3 4)) ; => (1 2 3 4)
|
||||
|
||||
; Usa filter y map para actuar sobre colecciones
|
||||
(map inc [1 2 3]) ; => (2 3 4)
|
||||
(filter even? [1 2 3]) ; => (2)
|
||||
|
||||
; Usa reduce para combinar sus elementos
|
||||
(reduce + [1 2 3 4])
|
||||
; = (+ (+ (+ 1 2) 3) 4)
|
||||
; => 10
|
||||
|
||||
; reduce puede tener un argumento indicando su valor inicial.
|
||||
(reduce conj [] '(3 2 1))
|
||||
; = (conj (conj (conj [] 3) 2) 1)
|
||||
; => [3 2 1]
|
||||
|
||||
; Funciones
|
||||
;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
; Usa fn para crear nuevas funciones. Una función siempre devuelve
|
||||
; su última expresión
|
||||
(fn [] "Hello World") ; => fn
|
||||
|
||||
; (Necesitas rodearlo con paréntesis para invocarla)
|
||||
((fn [] "Hello World")) ; => "Hello World"
|
||||
|
||||
; Puedes crear una var (variable) mediante def
|
||||
(def x 1)
|
||||
x ; => 1
|
||||
|
||||
; Asigna una función a una var
|
||||
(def hello-world (fn [] "Hello World"))
|
||||
(hello-world) ; => "Hello World"
|
||||
|
||||
; Puedes defn como atajo para lo anterior
|
||||
(defn hello-world [] "Hello World")
|
||||
|
||||
; El [] es el vector de argumentos de la función.
|
||||
(defn hello [name]
|
||||
(str "Hello " name))
|
||||
(hello "Steve") ; => "Hello Steve"
|
||||
|
||||
; Otra abreviatura para crear funciones es:
|
||||
(def hello2 #(str "Hello " %1))
|
||||
(hello2 "Fanny") ; => "Hello Fanny"
|
||||
|
||||
; Puedes tener funciones multi-variadic: funciones con un numero variable de
|
||||
; argumentos
|
||||
(defn hello3
|
||||
([] "Hello World")
|
||||
([name] (str "Hello " name)))
|
||||
(hello3 "Jake") ; => "Hello Jake"
|
||||
(hello3) ; => "Hello World"
|
||||
|
||||
; Las funciones pueden usar argumentos extras dentro de un seq utilizable en la función
|
||||
(defn count-args [& args]
|
||||
(str "You passed " (count args) " args: " args))
|
||||
(count-args 1 2 3) ; => "You passed 3 args: (1 2 3)"
|
||||
|
||||
; Y puedes mezclarlos con el resto de argumentos declarados de la función.
|
||||
(defn hello-count [name & args]
|
||||
(str "Hello " name ", you passed " (count args) " extra args"))
|
||||
(hello-count "Finn" 1 2 3)
|
||||
; => "Hello Finn, you passed 3 extra args"
|
||||
|
||||
|
||||
; Mapas
|
||||
;;;;;;;;;;
|
||||
|
||||
; Mapas de Hash y mapas de arrays comparten una misma interfaz. Los mapas de Hash
|
||||
; tienen búsquedas más rápidas pero no mantienen el orden de las claves.
|
||||
(class {:a 1 :b 2 :c 3}) ; => clojure.lang.PersistentArrayMap
|
||||
(class (hash-map :a 1 :b 2 :c 3)) ; => clojure.lang.PersistentHashMap
|
||||
|
||||
; Los mapas de arrays se convertidos en mapas de Hash en la mayoría de
|
||||
; operaciones si crecen mucho, por lo que no debes preocuparte.
|
||||
|
||||
; Los mapas pueden usar cualquier tipo para sus claves, pero generalmente las
|
||||
; keywords (palabras clave) son lo habitual.
|
||||
; Las keywords son parecidas a cadenas de caracteres con algunas ventajas de eficiencia
|
||||
(class :a) ; => clojure.lang.Keyword
|
||||
|
||||
(def stringmap {"a" 1, "b" 2, "c" 3})
|
||||
stringmap ; => {"a" 1, "b" 2, "c" 3}
|
||||
|
||||
(def keymap {:a 1, :b 2, :c 3})
|
||||
keymap ; => {:a 1, :c 3, :b 2}
|
||||
|
||||
; Por cierto, las comas son equivalentes a espacios en blanco y no hacen
|
||||
; nada.
|
||||
|
||||
; Recupera un valor de un mapa tratandolo como una función
|
||||
(stringmap "a") ; => 1
|
||||
(keymap :a) ; => 1
|
||||
|
||||
; ¡Las keywords pueden ser usadas para recuperar su valor del mapa, también!
|
||||
(:b keymap) ; => 2
|
||||
|
||||
; No lo intentes con strings.
|
||||
;("a" stringmap)
|
||||
; => Exception: java.lang.String cannot be cast to clojure.lang.IFn
|
||||
|
||||
; Si preguntamos por una clave que no existe nos devuelve nil
|
||||
(stringmap "d") ; => nil
|
||||
|
||||
; Usa assoc para añadir nuevas claves a los mapas de Hash
|
||||
(def newkeymap (assoc keymap :d 4))
|
||||
newkeymap ; => {:a 1, :b 2, :c 3, :d 4}
|
||||
|
||||
; Pero recuerda, ¡los tipos de Clojure son inmutables!
|
||||
keymap ; => {:a 1, :b 2, :c 3}
|
||||
|
||||
; Usa dissoc para eliminar llaves
|
||||
(dissoc keymap :a :b) ; => {:c 3}
|
||||
|
||||
; Conjuntos
|
||||
;;;;;;
|
||||
|
||||
(class #{1 2 3}) ; => clojure.lang.PersistentHashSet
|
||||
(set [1 2 3 1 2 3 3 2 1 3 2 1]) ; => #{1 2 3}
|
||||
|
||||
; Añade un elemento con conj
|
||||
(conj #{1 2 3} 4) ; => #{1 2 3 4}
|
||||
|
||||
; Elimina elementos con disj
|
||||
(disj #{1 2 3} 1) ; => #{2 3}
|
||||
|
||||
; Comprueba su existencia usando el conjunto como una función:
|
||||
(#{1 2 3} 1) ; => 1
|
||||
(#{1 2 3} 4) ; => nil
|
||||
|
||||
; Hay más funciones en el namespace clojure.sets
|
||||
|
||||
; Patrones útiles
|
||||
;;;;;;;;;;;;;;;;;
|
||||
|
||||
; Las construcciones lógicas en clojure son macros, y presentan el mismo aspecto
|
||||
; que el resto de forms.
|
||||
(if false "a" "b") ; => "b"
|
||||
(if false "a") ; => nil
|
||||
|
||||
; Usa let para crear un binding (asociación) temporal
|
||||
(let [a 1 b 2]
|
||||
(> a b)) ; => false
|
||||
|
||||
; Agrupa expresiones mediante do
|
||||
(do
|
||||
(print "Hello")
|
||||
"World") ; => "World" (prints "Hello")
|
||||
|
||||
; Las funciones tienen implicita la llamada a do
|
||||
(defn print-and-say-hello [name]
|
||||
(print "Saying hello to " name)
|
||||
(str "Hello " name))
|
||||
(print-and-say-hello "Jeff") ;=> "Hello Jeff" (prints "Saying hello to Jeff")
|
||||
|
||||
; Y el let también
|
||||
(let [name "Urkel"]
|
||||
(print "Saying hello to " name)
|
||||
(str "Hello " name)) ; => "Hello Urkel" (prints "Saying hello to Urkel")
|
||||
|
||||
; Módulos
|
||||
;;;;;;;;;;;;;;;
|
||||
|
||||
; Usa use para obtener todas las funciones del módulo
|
||||
(use 'clojure.set)
|
||||
|
||||
; Ahora podemos usar más operaciones de conjuntos
|
||||
(intersection #{1 2 3} #{2 3 4}) ; => #{2 3}
|
||||
(difference #{1 2 3} #{2 3 4}) ; => #{1}
|
||||
|
||||
; Puedes escoger un subgrupo de funciones a importar, también
|
||||
(use '[clojure.set :only [intersection]])
|
||||
|
||||
; Usa require para importar un módulo
|
||||
(require 'clojure.string)
|
||||
|
||||
; Usa / para llamar a las funciones de un módulo
|
||||
; Aquí, el módulo es clojure.string y la función es blank?
|
||||
(clojure.string/blank? "") ; => true
|
||||
|
||||
; Puedes asignarle una abreviatura a un modulo al importarlo
|
||||
(require '[clojure.string :as str])
|
||||
(str/replace "This is a test." #"[a-o]" str/upper-case) ; => "THIs Is A tEst."
|
||||
; (#"" es una expresión regular)
|
||||
|
||||
; Puedes usar require (y use, pero no lo hagas) desde un espacio de nombre
|
||||
; usando :require,
|
||||
; No necesitas preceder con comilla simple tus módulos si lo haces de esta
|
||||
; forma.
|
||||
(ns test
|
||||
(:require
|
||||
[clojure.string :as str]
|
||||
[clojure.set :as set]))
|
||||
|
||||
; Java
|
||||
;;;;;;;;;;;;;;;;;
|
||||
|
||||
; Java tiene una enorme librería estándar, por lo que resulta util
|
||||
; aprender como interactuar con ella.
|
||||
|
||||
; Usa import para cargar un módulo de java
|
||||
(import java.util.Date)
|
||||
|
||||
; Puedes importar desde un ns también.
|
||||
(ns test
|
||||
(:import java.util.Date
|
||||
java.util.Calendar))
|
||||
|
||||
; Usa el nombre de la clase con un "." al final para crear una nueva instancia
|
||||
(Date.) ; <un objeto Date>
|
||||
|
||||
; Usa "." para llamar a métodos o usa el atajo ".método"
|
||||
(. (Date.) getTime) ; <un timestamp>
|
||||
(.getTime (Date.)) ; exactamente la misma cosa
|
||||
|
||||
; Usa / para llamar métodos estáticos.
|
||||
(System/currentTimeMillis) ; <un timestamp> (System siempre está presente)
|
||||
|
||||
; Usa doto para hacer frente al uso de clases (mutables) más tolerable
|
||||
(import java.util.Calendar)
|
||||
(doto (Calendar/getInstance)
|
||||
(.set 2000 1 1 0 0 0)
|
||||
.getTime) ; => A Date. set to 2000-01-01 00:00:00
|
||||
|
||||
; STM
|
||||
;;;;;;;;;;;;;;;;;
|
||||
|
||||
; Software Transactional Memory es un mecanismo que usa clojure para gestionar
|
||||
; el estado persistente. Hay unas cuantas construcciones en clojure que
|
||||
; hacen uso de este mecanismo.
|
||||
|
||||
; Un atom es el más sencillo. Se le da un valor inicial
|
||||
(def my-atom (atom {}))
|
||||
|
||||
; Actualiza un atom con swap!
|
||||
; swap! toma una función y la llama con el valor actual del atom
|
||||
; como su primer argumento, y cualquier argumento restante como el segundo
|
||||
(swap! my-atom assoc :a 1) ; Establece my-atom al resultado de (assoc {} :a 1)
|
||||
(swap! my-atom assoc :b 2) ; Establece my-atom al resultado de (assoc {:a 1} :b 2)
|
||||
|
||||
; Usa '@' para no referenciar al atom sino para obtener su valor
|
||||
my-atom ;=> Atom<#...> (Regresa el objeto Atom)
|
||||
@my-atom ; => {:a 1 :b 2}
|
||||
|
||||
; Un sencillo contador usando un atom sería
|
||||
(def counter (atom 0))
|
||||
(defn inc-counter []
|
||||
(swap! counter inc))
|
||||
|
||||
(inc-counter)
|
||||
(inc-counter)
|
||||
(inc-counter)
|
||||
(inc-counter)
|
||||
(inc-counter)
|
||||
|
||||
@counter ; => 5
|
||||
|
||||
; Otros forms que utilizan STM son refs y agents.
|
||||
; Refs: http://clojure.org/refs
|
||||
; Agents: http://clojure.org/agents
|
||||
### Lectura adicional
|
||||
|
||||
Ésto queda lejos de ser exhaustivo, pero espero que sea suficiente para que puedas empezar tu camino.
|
||||
|
||||
Clojure.org tiene muchos artículos:
|
||||
[http://clojure.org/](http://clojure.org/)
|
||||
|
||||
Clojuredocs.org contiene documentación con ejemplos para la mayoría de
|
||||
funciones principales (pertenecientes al core):
|
||||
[http://clojuredocs.org/quickref/Clojure%20Core](http://clojuredocs.org/quickref/Clojure%20Core)
|
||||
|
||||
4Clojure es una genial forma de mejorar tus habilidades con clojure/FP:
|
||||
[http://www.4clojure.com/](http://www.4clojure.com/)
|
||||
|
||||
Clojure-doc.org (sí, de verdad) tiene un buen número de artículos con los que iniciarse en Clojure:
|
||||
[http://clojure-doc.org/](http://clojure-doc.org/)
|
@ -44,7 +44,7 @@ math =
|
||||
# "cube": function(x) { return x * square(x); }
|
||||
#}
|
||||
|
||||
# Símbolos:
|
||||
# Número de argumentos variable:
|
||||
race = (winner, runners...) ->
|
||||
print winner, runners
|
||||
|
||||
@ -52,6 +52,6 @@ race = (winner, runners...) ->
|
||||
alert "I knew it!" if elvis?
|
||||
#=> if(typeof elvis !== "undefined" && elvis !== null) { alert("I knew it!"); }
|
||||
|
||||
# Colecciones por comprensión:
|
||||
# Listas:
|
||||
cubes = (math.cube num for num in list) #=> ...
|
||||
```
|
||||
|
632
es-es/csharp-es.html.markdown
Normal file
632
es-es/csharp-es.html.markdown
Normal file
@ -0,0 +1,632 @@
|
||||
---
|
||||
language: c#
|
||||
contributors:
|
||||
- ["Irfan Charania", "https://github.com/irfancharania"]
|
||||
- ["Max Yankov", "https://github.com/golergka"]
|
||||
translators:
|
||||
- ["Olfran Jiménez", "https://twitter.com/neslux"]
|
||||
filename: LearnCSharp-es.cs
|
||||
lang: es-es
|
||||
---
|
||||
|
||||
C# es un lenguaje orientado a objetos elegante y de tipado seguro que
|
||||
permite a los desarrolladores construir una variedad de aplicaciones
|
||||
seguras y robustas que se ejecutan en el Framework .NET.
|
||||
|
||||
[Lee más aquí.](http://msdn.microsoft.com/es-es/library/vstudio/z1zx9t92.aspx)
|
||||
|
||||
```c#
|
||||
// Los comentarios de una sola línea comienzan con //
|
||||
/*
|
||||
Los comentarios de múltiples líneas son de esta manera
|
||||
*/
|
||||
/// <summary>
|
||||
/// Este es un comentario de documentación XML
|
||||
/// </summary>
|
||||
|
||||
// Especifica el espacio de nombres que estará usando la aplicación
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
||||
// Define un ambito para organizar el código en "paquetes"
|
||||
namespace Learning
|
||||
{
|
||||
// Cada archivo .cs debe contener al menos una clase con el mismo nombre que el archivo
|
||||
// Se permite colocar cualquier nombre, pero no deberías por cuestiones de consistencia.
|
||||
public class LearnCSharp
|
||||
{
|
||||
// Una aplicación de consola debe tener un método main como punto de entrada
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
// Usa Console.WriteLine para imprimir líneas
|
||||
Console.WriteLine("Hello World");
|
||||
Console.WriteLine(
|
||||
"Integer: " + 10 +
|
||||
" Double: " + 3.14 +
|
||||
" Boolean: " + true);
|
||||
|
||||
// Para imprimir sin una nueva línea, usa Console.Write
|
||||
Console.Write("Hello ");
|
||||
Console.Write("World");
|
||||
|
||||
|
||||
///////////////////////////////////////////////////
|
||||
// Variables y Tipos
|
||||
//
|
||||
// Declara una variable usando <tipo> <nombre>
|
||||
///////////////////////////////////////////////////
|
||||
|
||||
// Sbyte - Entero de 8 bits con signo
|
||||
// (-128 <= sbyte <= 127)
|
||||
sbyte fooSbyte = 100;
|
||||
|
||||
// Byte - Entero de 8 bits sin signo
|
||||
// (0 <= byte <= 255)
|
||||
byte fooByte = 100;
|
||||
|
||||
// Short - Entero de 16 bits con signo
|
||||
// (-32,768 <= short <= 32,767)
|
||||
short fooShort = 10000;
|
||||
|
||||
// Ushort - Entero de 16 bits sin signo
|
||||
// (0 <= ushort <= 65,535)
|
||||
ushort fooUshort = 10000;
|
||||
|
||||
// Integer - Entero de 32 bits con signo
|
||||
// (-2,147,483,648 <= int <= 2,147,483,647)
|
||||
int fooInt = 1;
|
||||
|
||||
// Uinteger - Entero de 32 bits sin signo
|
||||
// (0 <= uint <= 4,294,967,295)
|
||||
uint fooUint = 1;
|
||||
|
||||
// Long - Entero de 64 bits con signo
|
||||
// (-9,223,372,036,854,775,808 <= long <= 9,223,372,036,854,775,807)
|
||||
long fooLong = 100000L;
|
||||
// L es usado para indicar que esta variable es de tipo long o ulong
|
||||
// un valor sin este sufijo es tratado como int o uint dependiendo del tamaño.
|
||||
|
||||
// Ulong - Entero de 64 bits sin signo
|
||||
// (0 <= ulong <= 18,446,744,073,709,551,615)
|
||||
ulong fooUlong = 100000L;
|
||||
|
||||
// Float - Precisión simple de 32 bits. IEEE 754 Coma flotante
|
||||
// Precisión: 7 dígitos
|
||||
float fooFloat = 234.5f;
|
||||
// f es usado para indicar que el valor de esta variable es de tipo float
|
||||
// de otra manera sería tratado como si fuera de tipo double.
|
||||
|
||||
// Double - Doble precisión de 32 bits. IEEE 754 Coma flotante
|
||||
// Precisión: 15-16 dígitos
|
||||
double fooDouble = 123.4;
|
||||
|
||||
// Bool - true & false (verdadero y falso)
|
||||
bool fooBoolean = true;
|
||||
bool barBoolean = false;
|
||||
|
||||
// Char - Un solo caracter Unicode de 16 bits
|
||||
char fooChar = 'A';
|
||||
|
||||
// Strings
|
||||
string fooString = "My string is here!";
|
||||
Console.WriteLine(fooString);
|
||||
|
||||
// Formato de cadenas
|
||||
string fooFs = string.Format("Check Check, {0} {1}, {0} {1:0.0}", 1, 2);
|
||||
Console.WriteLine(fooFormattedString);
|
||||
|
||||
// Formato de fechas
|
||||
DateTime fooDate = DateTime.Now;
|
||||
Console.WriteLine(fooDate.ToString("hh:mm, dd MMM yyyy"));
|
||||
|
||||
// \n es un caracter de escape que comienza una nueva línea
|
||||
string barString = "Printing on a new line?\nNo Problem!";
|
||||
Console.WriteLine(barString);
|
||||
|
||||
// Puede ser escrito mejor usando el símbolo @
|
||||
string bazString = @"Here's some stuff
|
||||
on a new line!";
|
||||
Console.WriteLine(bazString);
|
||||
|
||||
// Las comillas deben ser escapadas
|
||||
// usa \" para escaparlas
|
||||
string quotedString = "some \"quoted\" stuff";
|
||||
Console.WriteLine(quotedString);
|
||||
|
||||
// usa "" cuando las cadenas comiencen con @
|
||||
string quotedString2 = @"some MORE ""quoted"" stuff";
|
||||
Console.WriteLine(quotedString2);
|
||||
|
||||
// Usa const o readonly para hacer las variables inmutables
|
||||
// los valores const son calculados en tiempo de compilación
|
||||
const int HOURS_I_WORK_PER_WEEK = 9001;
|
||||
|
||||
// Tipos que aceptan valores NULL (Nullable)
|
||||
// cualquier tipo de dato puede ser un tipo nulo añadiendole el sufijo ?
|
||||
// <tipo>? <variable> = <valor>
|
||||
int? nullable = null;
|
||||
Console.WriteLine("Nullable variable: " + nullable);
|
||||
|
||||
// Para usar valores nulos, tienes que usar la propiedad Value
|
||||
// o usar conversión explícita
|
||||
string? nullableString = "not null";
|
||||
Console.WriteLine("Nullable value is: " + nullableString.Value + " or: " + (string) nullableString );
|
||||
|
||||
// ?? is una manera corta de especificar valores por defecto
|
||||
// en caso de que la variable sea null
|
||||
int notNullable = nullable ?? 0;
|
||||
Console.WriteLine("Not nullable variable: " + notNullable);
|
||||
|
||||
// var - el compilador escogerá el tipo de dato más apropiado basado en el valor
|
||||
var fooImplicit = true;
|
||||
|
||||
///////////////////////////////////////////////////
|
||||
// Estructura de datos
|
||||
///////////////////////////////////////////////////
|
||||
Console.WriteLine("\n->Data Structures");
|
||||
|
||||
// Arreglos
|
||||
// El tamaño del arreglo debe decidirse al momento de la declaración
|
||||
// El formato para declarar un arreglo es el siguiente:
|
||||
// <tipo_de_dato>[] <nombre_variable> = new <tipo_de_dato>[<tamaño>];
|
||||
int[] intArray = new int[10];
|
||||
string[] stringArray = new string[1];
|
||||
bool[] boolArray = new bool[100];
|
||||
|
||||
// Otra forma de declarar e inicializar un arreglo
|
||||
int[] y = { 9000, 1000, 1337 };
|
||||
|
||||
// Indexar arreglos - Acceder a un elemento
|
||||
Console.WriteLine("intArray @ 0: " + intArray[0]);
|
||||
|
||||
// Los arreglos son de índice cero y son mutables.
|
||||
intArray[1] = 1;
|
||||
Console.WriteLine("intArray @ 1: " + intArray[1]); // => 1
|
||||
|
||||
// Listas
|
||||
// Las listas son usadas más frecuentemente que los arreglos ya que son más flexibles
|
||||
// El formato para declarar una lista es el siguiente:
|
||||
// List<tipo_de_dato> <nombre_variable> = new List<tipo_de_dato>();
|
||||
List<int> intList = new List<int>();
|
||||
List<string> stringList = new List<string>();
|
||||
|
||||
// Otra forma de declarar e inicializar una lista
|
||||
List<int> z = new List<int> { 9000, 1000, 1337 };
|
||||
|
||||
// Indexar una lista - Acceder a un elemento
|
||||
// Las listas son de índice cero y son mutables.
|
||||
Console.WriteLine("z @ 0: " + z[2]);
|
||||
|
||||
// Las listas no tienen valores por defecto;
|
||||
// Un valor debe ser añadido antes de acceder al índice
|
||||
intList.Add(1);
|
||||
Console.WriteLine("intList @ 0: " + intList[0]);
|
||||
|
||||
|
||||
// Otras estructuras de datos a chequear:
|
||||
//
|
||||
// Pilas/Colas
|
||||
// Diccionarios
|
||||
// Colecciones de sólo lectura
|
||||
// Tuplas (.Net 4+)
|
||||
|
||||
|
||||
///////////////////////////////////////
|
||||
// Operadores
|
||||
///////////////////////////////////////
|
||||
Console.WriteLine("\n->Operators");
|
||||
|
||||
int i1 = 1, i2 = 2; // Modo corto para múltiples declaraciones
|
||||
|
||||
// La aritmética es sencilla
|
||||
Console.WriteLine("1+2 = " + (i1 + i2)); // => 3
|
||||
Console.WriteLine("2-1 = " + (i2 - i1)); // => 1
|
||||
Console.WriteLine("2*1 = " + (i2 * i1)); // => 2
|
||||
Console.WriteLine("1/2 = " + (i1 / i2)); // => 0 (0.5 truncated down)
|
||||
|
||||
// Módulo
|
||||
Console.WriteLine("11%3 = " + (11 % 3)); // => 2
|
||||
|
||||
// Operadores de comparación
|
||||
Console.WriteLine("3 == 2? " + (3 == 2)); // => false
|
||||
Console.WriteLine("3 != 2? " + (3 != 2)); // => true
|
||||
Console.WriteLine("3 > 2? " + (3 > 2)); // => true
|
||||
Console.WriteLine("3 < 2? " + (3 < 2)); // => false
|
||||
Console.WriteLine("2 <= 2? " + (2 <= 2)); // => true
|
||||
Console.WriteLine("2 >= 2? " + (2 >= 2)); // => true
|
||||
|
||||
// Operadores a nivel de bits
|
||||
/*
|
||||
~ Complemento a nivel de bits
|
||||
<< Desplazamiento a la izquierda con signo
|
||||
>> Desplazamiento a la derecha con signo
|
||||
>>> Desplazamiento a la derecha sin signo
|
||||
& AND a nivel de bits
|
||||
^ XOR a nivel de bits
|
||||
| OR a nivel de bits
|
||||
*/
|
||||
|
||||
// Incremento
|
||||
int i = 0;
|
||||
Console.WriteLine("\n->Inc/Dec-remento");
|
||||
Console.WriteLine(i++); //i = 1. Posincrementación
|
||||
Console.WriteLine(++i); //i = 2. Preincremento
|
||||
Console.WriteLine(i--); //i = 1. Posdecremento
|
||||
Console.WriteLine(--i); //i = 0. Predecremento
|
||||
|
||||
|
||||
///////////////////////////////////////
|
||||
// Estructuras de control
|
||||
///////////////////////////////////////
|
||||
Console.WriteLine("\n->Control Structures");
|
||||
|
||||
// Las condiciones if son como en lenguaje c
|
||||
int j = 10;
|
||||
if (j == 10)
|
||||
{
|
||||
Console.WriteLine("I get printed");
|
||||
}
|
||||
else if (j > 10)
|
||||
{
|
||||
Console.WriteLine("I don't");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("I also don't");
|
||||
}
|
||||
|
||||
// Operador ternario
|
||||
// Un simple if/else puede ser escrito de la siguiente manera;
|
||||
// <condición> ? <true> : <false>
|
||||
string isTrue = (true) ? "True" : "False";
|
||||
Console.WriteLine("Ternary demo: " + isTrue);
|
||||
|
||||
|
||||
// Bucle while
|
||||
int fooWhile = 0;
|
||||
while (fooWhile < 100)
|
||||
{
|
||||
//Console.WriteLine(fooWhile);
|
||||
//Incrementar el contador
|
||||
//Iterar 99 veces, fooWhile 0->99
|
||||
fooWhile++;
|
||||
}
|
||||
Console.WriteLine("fooWhile Value: " + fooWhile);
|
||||
|
||||
// Bucle Do While
|
||||
int fooDoWhile = 0;
|
||||
do
|
||||
{
|
||||
//Console.WriteLine(fooDoWhile);
|
||||
//Incrementar el contador
|
||||
//Iterar 99 veces, fooDoWhile 0->99
|
||||
fooDoWhile++;
|
||||
} while (fooDoWhile < 100);
|
||||
Console.WriteLine("fooDoWhile Value: " + fooDoWhile);
|
||||
|
||||
// Bucle For
|
||||
int fooFor;
|
||||
//Estructura del bucle for => for(<declaración_inicial>; <condición>; <incremento>)
|
||||
for (fooFor = 0; fooFor < 10; fooFor++)
|
||||
{
|
||||
//Console.WriteLine(fooFor);
|
||||
//Iterated 10 times, fooFor 0->9
|
||||
}
|
||||
Console.WriteLine("fooFor Value: " + fooFor);
|
||||
|
||||
// Switch Case
|
||||
// El switch funciona con los tipos de datos byte, short, char e int
|
||||
// También funciona con las enumeraciones (discutidos en in Tipos Enum),
|
||||
// la clase string y algunas clases especiales que encapsulan
|
||||
// tipos primitivos: Character, Byte, Short, Integer.
|
||||
int month = 3;
|
||||
string monthString;
|
||||
switch (month)
|
||||
{
|
||||
case 1:
|
||||
monthString = "January";
|
||||
break;
|
||||
case 2:
|
||||
monthString = "February";
|
||||
break;
|
||||
case 3:
|
||||
monthString = "March";
|
||||
break;
|
||||
default:
|
||||
monthString = "Some other month";
|
||||
break;
|
||||
}
|
||||
Console.WriteLine("Switch Case Result: " + monthString);
|
||||
|
||||
|
||||
////////////////////////////////
|
||||
// Conversión de tipos de datos
|
||||
////////////////////////////////
|
||||
|
||||
// Convertir datos
|
||||
|
||||
// Convertir String a Integer
|
||||
// esto generará una excepción al fallar la conversión
|
||||
int.Parse("123");//retorna una versión entera de "123"
|
||||
|
||||
// TryParse establece la variable a un tipo por defecto
|
||||
// en este caso: 0
|
||||
int tryInt;
|
||||
int.TryParse("123", out tryInt);
|
||||
|
||||
// Convertir Integer a String
|
||||
// La clase Convert tiene algunos métodos para facilitar las conversiones
|
||||
Convert.ToString(123);
|
||||
|
||||
///////////////////////////////////////
|
||||
// Clases y Funciones
|
||||
///////////////////////////////////////
|
||||
|
||||
Console.WriteLine("\n->Classes & Functions");
|
||||
|
||||
// (Definición de la clase Bicycle (Bicicleta))
|
||||
|
||||
// Usar new para instanciar una clase
|
||||
Bicycle trek = new Bicycle();
|
||||
|
||||
// Llamar a los métodos del objeto
|
||||
trek.speedUp(3); // Siempre deberías usar métodos setter y métodos getter
|
||||
trek.setCadence(100);
|
||||
|
||||
// ToString es una convención para mostrar el valor del objeto.
|
||||
Console.WriteLine("trek info: " + trek.ToString());
|
||||
|
||||
// Instanciar otra nueva bicicleta
|
||||
Bicycle octo = new Bicycle(5, 10);
|
||||
Console.WriteLine("octo info: " + octo.ToString());
|
||||
|
||||
// Instanciar un Penny Farthing (Biciclo)
|
||||
PennyFarthing funbike = new PennyFarthing(1, 10);
|
||||
Console.WriteLine("funbike info: " + funbike.ToString());
|
||||
|
||||
Console.Read();
|
||||
} // Fin del método main
|
||||
|
||||
|
||||
} // Fin de la clase LearnCSharp
|
||||
|
||||
// Puedes incluir otras clases en un archivo .cs
|
||||
|
||||
|
||||
// Sintaxis para la declaración de clases:
|
||||
// <public/private/protected> class <nombre_de_clase>{
|
||||
// //campos, constructores, funciones todo adentro de la clase.
|
||||
// //las funciones son llamadas métodos como en java.
|
||||
// }
|
||||
|
||||
public class Bicycle
|
||||
{
|
||||
// Campos/Variables de la clase Bicycle
|
||||
public int cadence; // Public: Accesible desde cualquier lado
|
||||
private int _speed; // Private: Sólo es accesible desde dentro de la clase
|
||||
protected int gear; // Protected: Accesible desde clases y subclases
|
||||
internal int wheels; // Internal: Accesible en el ensamblado
|
||||
string name; // Todo es privado por defecto: Sólo es accesible desde dentro de esta clase
|
||||
|
||||
// Enum es un tipo valor que consiste un una serie de constantes con nombres
|
||||
public enum Brand
|
||||
{
|
||||
AIST,
|
||||
BMC,
|
||||
Electra,
|
||||
Gitane
|
||||
}
|
||||
// Definimos este tipo dentro de la clase Bicycle, por lo tanto es un tipo anidado
|
||||
// El código afuera de esta clase debería referenciar este tipo como Bicycle.Brand
|
||||
|
||||
public Brand brand; // Declaramos un tipo enum, podemos declarar un campo de este tipo
|
||||
|
||||
// Los miembros estáticos pertenecen al tipo mismo, no a un objeto en específico.
|
||||
static public int bicyclesCreated = 0;
|
||||
// Puedes acceder a ellos sin referenciar ningún objeto:
|
||||
// Console.WriteLine("Bicycles created: " + Bicycle.bicyclesCreated);
|
||||
|
||||
// Los valores readonly (Sólo lectura) son establecidos en tiempo de ejecución
|
||||
// sólo pueden ser asignados al momento de la declaración o dentro de un constructor
|
||||
readonly bool hasCardsInSpokes = false; // privado de sólo lectura
|
||||
|
||||
// Los constructores son una forma de crear clases
|
||||
// Este es un constructor por defecto
|
||||
private Bicycle()
|
||||
{
|
||||
gear = 1;
|
||||
cadence = 50;
|
||||
_speed = 5;
|
||||
name = "Bontrager";
|
||||
brand = Brand.AIST;
|
||||
bicyclesCreated++;
|
||||
}
|
||||
|
||||
// Este es un constructor específico (contiene argumentos)
|
||||
public Bicycle(int startCadence, int startSpeed, int startGear,
|
||||
string name, bool hasCardsInSpokes, Brand brand)
|
||||
{
|
||||
this.gear = startGear; // La palabra reservada "this" señala el objeto actual
|
||||
this.cadence = startCadence;
|
||||
this._speed = startSpeed;
|
||||
this.name = name; // Puede ser útil cuando hay un conflicto de nombres
|
||||
this.hasCardsInSpokes = hasCardsInSpokes;
|
||||
this.brand = brand;
|
||||
}
|
||||
|
||||
// Los constructores pueden ser encadenados
|
||||
public Bicycle(int startCadence, int startSpeed, Brand brand) :
|
||||
this(startCadence, startSpeed, 0, "big wheels", true)
|
||||
{
|
||||
}
|
||||
|
||||
// Sintaxis para Funciones:
|
||||
// <public/private/protected> <tipo_retorno> <nombre_funcion>(<args>)
|
||||
|
||||
// Las clases pueden implementar getters y setters para sus campos
|
||||
// o pueden implementar propiedades
|
||||
|
||||
// Sintaxis para la declaración de métodos:
|
||||
// <ámbito> <tipo_retorno> <nombre_método>(<argumentos>)
|
||||
public int GetCadence()
|
||||
{
|
||||
return cadence;
|
||||
}
|
||||
|
||||
// Los métodos void no requieren usar return
|
||||
public void SetCadence(int newValue)
|
||||
{
|
||||
cadence = newValue;
|
||||
}
|
||||
|
||||
// La palabra reservada virtual indica que este método puede ser sobrescrito
|
||||
public virtual void SetGear(int newValue)
|
||||
{
|
||||
gear = newValue;
|
||||
}
|
||||
|
||||
// Los parámetros de un método pueden tener valores por defecto.
|
||||
// En este caso, los métodos pueden ser llamados omitiendo esos parámetros
|
||||
public void SpeedUp(int increment = 1)
|
||||
{
|
||||
_speed += increment;
|
||||
}
|
||||
|
||||
public void SlowDown(int decrement = 1)
|
||||
{
|
||||
_speed -= decrement;
|
||||
}
|
||||
|
||||
// Propiedades y valores get/set
|
||||
// Cuando los datos sólo necesitan ser accedidos, considera usar propiedades.
|
||||
// Las propiedades pueden tener get, set o ambos
|
||||
private bool _hasTassles; // variable privada
|
||||
public bool HasTassles // acceso público
|
||||
{
|
||||
get { return _hasTassles; }
|
||||
set { _hasTassles = value; }
|
||||
}
|
||||
|
||||
// Las propiedades pueden ser auto implementadas
|
||||
public int FrameSize
|
||||
{
|
||||
get;
|
||||
// Puedes especificar modificadores de acceso tanto para get como para set
|
||||
// esto significa que sólo dentro de la clase Bicycle se puede modificar Framesize
|
||||
private set;
|
||||
}
|
||||
|
||||
//Método para mostrar los valores de atributos de este objeto.
|
||||
public override string ToString()
|
||||
{
|
||||
return "gear: " + gear +
|
||||
" cadence: " + cadence +
|
||||
" speed: " + _speed +
|
||||
" name: " + name +
|
||||
" cards in spokes: " + (hasCardsInSpokes ? "yes" : "no") +
|
||||
"\n------------------------------\n"
|
||||
;
|
||||
}
|
||||
|
||||
// Los métodos también pueden ser estáticos. Puede ser útil para métodos de ayuda
|
||||
public static bool DidWeCreateEnoughBycles()
|
||||
{
|
||||
// Dentro de un método esático,
|
||||
// Sólo podemos hacer referencia a miembros estáticos de clases
|
||||
return bicyclesCreated > 9000;
|
||||
} // Si tu clase sólo necesita miembros estáticos,
|
||||
// considera establecer la clase como static.
|
||||
|
||||
} // fin de la clase Bicycle
|
||||
|
||||
// PennyFarthing es una subclase de Bicycle
|
||||
class PennyFarthing : Bicycle
|
||||
{
|
||||
// (Penny Farthings son las bicicletas con una rueda delantera enorme.
|
||||
// No tienen engranajes.)
|
||||
|
||||
// llamar al constructor de la clase padre
|
||||
public PennyFarthing(int startCadence, int startSpeed) :
|
||||
base(startCadence, startSpeed, 0, "PennyFarthing", true)
|
||||
{
|
||||
}
|
||||
|
||||
public override void SetGear(int gear)
|
||||
{
|
||||
gear = 0;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string result = "PennyFarthing bicycle ";
|
||||
result += base.ToString(); // Llamar a la versión base del método
|
||||
return reuslt;
|
||||
}
|
||||
}
|
||||
|
||||
// Las interfaces sólo contienen las declaraciones
|
||||
// de los miembros, sin la implementación.
|
||||
interface IJumpable
|
||||
{
|
||||
void Jump(int meters); // todos los miembros de interfaces son implícitamente públicos
|
||||
}
|
||||
|
||||
interface IBreakable
|
||||
{
|
||||
// Las interfaces pueden contener tanto propiedades como métodos, campos y eventos
|
||||
bool Broken { get; }
|
||||
}
|
||||
|
||||
// Las clases sólo heredan de alguna otra clase, pero pueden implementar
|
||||
// cualquier cantidad de interfaces
|
||||
class MountainBike : Bicycle, IJumpable, IBreakable
|
||||
{
|
||||
int damage = 0;
|
||||
|
||||
public void Jump(int meters)
|
||||
{
|
||||
damage += meters;
|
||||
}
|
||||
|
||||
public void Broken
|
||||
{
|
||||
get
|
||||
{
|
||||
return damage > 100;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // Fin del espacio de nombres
|
||||
|
||||
```
|
||||
|
||||
## Temas no cubiertos
|
||||
|
||||
* Flags
|
||||
* Attributes
|
||||
* Generics (T), Delegates, Func, Actions, lambda expressions
|
||||
* Static properties
|
||||
* Exceptions, Abstraction
|
||||
* LINQ
|
||||
* ASP.NET (Web Forms/MVC/WebMatrix)
|
||||
* Winforms
|
||||
* Windows Presentation Foundation (WPF)
|
||||
|
||||
|
||||
|
||||
## Lecturas recomendadas
|
||||
|
||||
* [DotNetPerls](http://www.dotnetperls.com)
|
||||
* [C# in Depth](http://manning.com/skeet2)
|
||||
* [Programming C#](http://shop.oreilly.com/product/0636920024064.do)
|
||||
* [LINQ](http://shop.oreilly.com/product/9780596519254.do)
|
||||
* [MSDN Library](http://msdn.microsoft.com/es-es/library/618ayhy6.aspx)
|
||||
* [ASP.NET MVC Tutorials](http://www.asp.net/mvc/tutorials)
|
||||
* [ASP.NET Web Matrix Tutorials](http://www.asp.net/web-pages/tutorials)
|
||||
* [ASP.NET Web Forms Tutorials](http://www.asp.net/web-forms/tutorials)
|
||||
* [Windows Forms Programming in C#](http://www.amazon.com/Windows-Forms-Programming-Chris-Sells/dp/0321116208)
|
||||
|
||||
|
||||
|
||||
[Convenciones de código de C#](http://msdn.microsoft.com/es-es/library/vstudio/ff926074.aspx)
|
301
es-es/go-es.html.markdown
Normal file
301
es-es/go-es.html.markdown
Normal file
@ -0,0 +1,301 @@
|
||||
---
|
||||
name: Go
|
||||
category: language
|
||||
language: Go
|
||||
filename: learngo.go
|
||||
contributors:
|
||||
- ["Sonia Keys", "https://github.com/soniakeys"]
|
||||
translators:
|
||||
- ["Adrian Espinosa", "http://www.adrianespinosa.com"]
|
||||
lang: es-es
|
||||
|
||||
|
||||
---
|
||||
|
||||
Go fue creado por la necesidad de hacer el trabajo rápidamente. No es la última
|
||||
tendencia en informática, pero es la forma nueva y más rápida de resolver problemas reales.
|
||||
|
||||
Tiene conceptos familiares de lenguajes imperativos con tipado estático.
|
||||
Es rápido compilando y rápido al ejecutar, añade una concurrencia fácil de entender para las CPUs de varios núcleos de hoy en día, y tiene características que ayudan con la programación a gran escala.
|
||||
Go viene con una librería estándar muy buena y una comunidad entusiasta.
|
||||
|
||||
```go
|
||||
// Comentario de una sola línea
|
||||
/* Comentario
|
||||
multi línea */
|
||||
|
||||
// La cláusula package aparece al comienzo de cada archivo fuente.
|
||||
// Main es un nombre especial que declara un ejecutable en vez de una librería.
|
||||
package main
|
||||
|
||||
// La declaración Import declara los paquetes de librerías referenciados en este archivo.
|
||||
import (
|
||||
"fmt" // Un paquete en la librería estándar de Go
|
||||
"net/http" // Sí, un servidor web!
|
||||
"strconv" // Conversiones de cadenas
|
||||
)
|
||||
|
||||
// Definición de una función. Main es especial. Es el punto de entrada para el ejecutable.
|
||||
// Te guste o no, Go utiliza llaves.
|
||||
func main() {
|
||||
// Println imprime una línea a stdout.
|
||||
// Cualificalo con el nombre del paquete, fmt.
|
||||
fmt.Println("Hello world!")
|
||||
|
||||
// Llama a otra función de este paquete.
|
||||
beyondHello()
|
||||
}
|
||||
|
||||
// Las funciones llevan parámetros entre paréntesis.
|
||||
// Si no hay parámetros, los paréntesis siguen siendo obligatorios.
|
||||
func beyondHello() {
|
||||
var x int // Declaración de una variable. Las variables se deben declarar antes de
|
||||
// utilizarlas.
|
||||
x = 3 // Asignación de variables.
|
||||
// Declaración "corta" con := para inferir el tipo, declarar y asignar.
|
||||
y := 4
|
||||
sum, prod := learnMultiple(x, y) // función devuelve dos valores
|
||||
fmt.Println("sum:", sum, "prod:", prod) // simple salida
|
||||
learnTypes() // < y minutes, learn more!
|
||||
}
|
||||
|
||||
// Las funciones pueden tener parámetros y (múltiples!) valores de retorno.
|
||||
func learnMultiple(x, y int) (sum, prod int) {
|
||||
return x + y, x * y // devolver dos valores
|
||||
}
|
||||
|
||||
// Algunos tipos incorporados y literales.
|
||||
func learnTypes() {
|
||||
// La declaración corta suele darte lo que quieres.
|
||||
s := "Learn Go!" // tipo cadena
|
||||
|
||||
s2 := ` Un tipo cadena "puro" puede incluir
|
||||
saltos de línea.` // mismo tipo cadena
|
||||
|
||||
// Literal no ASCII. Los fuentes de Go son UTF-8.
|
||||
g := 'Σ' // tipo rune, un alias de uint32, alberga un punto unicode.
|
||||
f := 3.14195 // float64, el estándar IEEE-754 de coma flotante 64-bit
|
||||
c := 3 + 4i // complex128, representado internamente por dos float64
|
||||
// Sintaxis Var con inicializadores.
|
||||
var u uint = 7 // sin signo, pero la implementación depende del tamaño como en int
|
||||
var pi float32 = 22. / 7
|
||||
|
||||
// Sintáxis de conversión con una declaración corta.
|
||||
n := byte('\n') // byte es un alias de uint8
|
||||
|
||||
// Los Arrays tienen un tamaño fijo a la hora de compilar.
|
||||
var a4 [4]int // un array de 4 ints, inicializados a 0
|
||||
a3 := [...]int{3, 1, 5} // un array de 3 ints, inicializados como se indica
|
||||
|
||||
// Los Slices tienen tamaño dinámico. Los arrays y slices tienen sus ventajas
|
||||
// y desventajas pero los casos de uso para los slices son más comunes.
|
||||
s3 := []int{4, 5, 9} // Comparar con a3. No hay puntos suspensivos
|
||||
s4 := make([]int, 4) // Asigna slices de 4 ints, inicializados a 0
|
||||
var d2 [][]float64 // solo declaración, sin asignación
|
||||
bs := []byte("a slice") // sintaxis de conversión de tipo
|
||||
|
||||
p, q := learnMemory() // declara p, q para ser un tipo puntero a int.
|
||||
fmt.Println(*p, *q) // * sigue un puntero. Esto imprime dos ints.
|
||||
|
||||
// Los Maps son arrays asociativos dinámicos, como los hash o diccionarios
|
||||
// de otros lenguajes
|
||||
m := map[string]int{"three": 3, "four": 4}
|
||||
m["one"] = 1
|
||||
|
||||
// Las variables no utilizadas en Go producen error.
|
||||
// El guión bajo permite "utilizar" una variable, pero descartar su valor.
|
||||
_, _, _, _, _, _, _, _, _ = s2, g, f, u, pi, n, a3, s4, bs
|
||||
// Esto cuenta como utilización de variables.
|
||||
fmt.Println(s, c, a4, s3, d2, m)
|
||||
|
||||
learnFlowControl() // vuelta al flujo
|
||||
}
|
||||
|
||||
// Go posee recolector de basura. Tiene puntero pero no aritmética de punteros.
|
||||
// Puedes cometer un errores con un puntero nil, pero no incrementando un puntero.
|
||||
func learnMemory() (p, q *int) {
|
||||
// q y p tienen un tipo puntero a int.
|
||||
p = new(int) // función incorporada que asigna memoria.
|
||||
// La asignación de int se inicializa a 0, p ya no es nil.
|
||||
s := make([]int, 20) // asigna 20 ints a un solo bloque de memoria.
|
||||
s[3] = 7 // asignar uno de ellos
|
||||
r := -2 // declarar otra variable local
|
||||
return &s[3], &r // & toma la dirección de un objeto.
|
||||
}
|
||||
|
||||
func expensiveComputation() int {
|
||||
return 1e6
|
||||
}
|
||||
|
||||
func learnFlowControl() {
|
||||
// La declaración If requiere llaves, pero no paréntesis.
|
||||
if true {
|
||||
fmt.Println("told ya")
|
||||
}
|
||||
// El formato está estandarizado por el comando "go fmt."
|
||||
if false {
|
||||
// pout
|
||||
} else {
|
||||
// gloat
|
||||
}
|
||||
// Utiliza switch preferiblemente para if encadenados.
|
||||
x := 1
|
||||
switch x {
|
||||
case 0:
|
||||
case 1:
|
||||
// los cases no se mezclan, no requieren de "break"
|
||||
case 2:
|
||||
// no llega
|
||||
}
|
||||
// Como if, for no utiliza paréntesis tampoco.
|
||||
for x := 0; x < 3; x++ { // ++ es una sentencia
|
||||
fmt.Println("iteration", x)
|
||||
}
|
||||
// x == 1 aqui.
|
||||
|
||||
// For es la única sentencia de bucle en Go, pero tiene formas alternativas.
|
||||
for { // bucle infinito
|
||||
break // solo bromeaba!
|
||||
continue // no llega
|
||||
}
|
||||
// Como en for, := en una sentencia if significa declarar y asignar primero,
|
||||
// luego comprobar y > x.
|
||||
if y := expensiveComputation(); y > x {
|
||||
x = y
|
||||
}
|
||||
// Los literales de funciones son "closures".
|
||||
xBig := func() bool {
|
||||
return x > 100 // referencia a x declarada encima de la sentencia switch.
|
||||
}
|
||||
fmt.Println("xBig:", xBig()) // verdadero (la última vez asignamos 1e6 a x)
|
||||
x /= 1e5 // esto lo hace == 10
|
||||
fmt.Println("xBig:", xBig()) // ahora es falso
|
||||
|
||||
// Cuando lo necesites, te encantará.
|
||||
goto love
|
||||
love:
|
||||
|
||||
learnInterfaces() // Buen material dentro de poco!
|
||||
}
|
||||
|
||||
// Define Stringer como un tipo interfaz con un método, String.
|
||||
type Stringer interface {
|
||||
String() string
|
||||
}
|
||||
|
||||
// Define pair como un struct con dos campos int, x e y.
|
||||
type pair struct {
|
||||
x, y int
|
||||
}
|
||||
|
||||
// Define un método del tipo pair. Pair ahora implementa Stringer.
|
||||
func (p pair) String() string { // p se llama "recibidor"
|
||||
// Sprintf es otra función pública del paquete fmt.
|
||||
// La sintaxis con punto referencia campos de p.
|
||||
return fmt.Sprintf("(%d, %d)", p.x, p.y)
|
||||
}
|
||||
|
||||
func learnInterfaces() {
|
||||
// La sintaxis de llaves es un "literal struct". Evalúa a un struct
|
||||
// inicializado. La sintaxis := declara e inicializa p a este struct.
|
||||
p := pair{3, 4}
|
||||
fmt.Println(p.String()) // llamar al método String de p, de tipo pair.
|
||||
var i Stringer // declarar i como interfaz tipo Stringer.
|
||||
i = p // válido porque pair implementa Stringer
|
||||
// Llamar al metodo String de i, de tipo Stringer. Misma salida que arriba
|
||||
fmt.Println(i.String())
|
||||
|
||||
// Las funciones en el paquete fmt llaman al método String para preguntar a un objeto
|
||||
// por una versión imprimible de si mismo
|
||||
fmt.Println(p) // salida igual que arriba. Println llama al método String.
|
||||
fmt.Println(i) // salida igual que arriba.
|
||||
|
||||
learnErrorHandling()
|
||||
}
|
||||
|
||||
func learnErrorHandling() {
|
||||
// ", ok" forma utilizada para saber si algo funcionó o no.
|
||||
m := map[int]string{3: "three", 4: "four"}
|
||||
if x, ok := m[1]; !ok { // ok será falso porque 1 no está en el map.
|
||||
fmt.Println("no one there")
|
||||
} else {
|
||||
fmt.Print(x) // x sería el valor, si estuviera en el map.
|
||||
}
|
||||
// Un valor de error comunica más información sobre el problema aparte de "ok".
|
||||
if _, err := strconv.Atoi("non-int"); err != nil { // _ descarta el valor
|
||||
// imprime "strconv.ParseInt: parsing "non-int": invalid syntax"
|
||||
fmt.Println(err)
|
||||
}
|
||||
// Revisarmeos las interfaces más tarde. Mientras tanto,
|
||||
learnConcurrency()
|
||||
}
|
||||
|
||||
// c es un canal, un objeto de comunicación de concurrencia segura.
|
||||
func inc(i int, c chan int) {
|
||||
c <- i + 1 // <- es el operador "enviar" cuando un canal aparece a la izquierda.
|
||||
}
|
||||
|
||||
// Utilizaremos inc para incrementar algunos números concurrentemente.
|
||||
func learnConcurrency() {
|
||||
// Misma función make utilizada antes para crear un slice. Make asigna e
|
||||
// inicializa slices, maps, y channels.
|
||||
c := make(chan int)
|
||||
// Iniciar tres goroutines concurrentes. Los números serán incrementados
|
||||
// concurrentemente, quizás en paralelo si la máquina es capaz y
|
||||
// está correctamente configurada. Las tres envían al mismo channel.
|
||||
go inc(0, c) // go es una sentencia que inicia una nueva goroutine.
|
||||
go inc(10, c)
|
||||
go inc(-805, c)
|
||||
// Leer los tres resultados del channel e imprimirlos.
|
||||
// No se puede saber en que orden llegarán los resultados!
|
||||
fmt.Println(<-c, <-c, <-c) // channel a la derecha, <- es el operador "recibir".
|
||||
|
||||
cs := make(chan string) // otro channel, este gestiona cadenas.
|
||||
cc := make(chan chan string) // un channel de cadenas de channels.
|
||||
go func() { c <- 84 }() // iniciar una nueva goroutine solo para enviar un valor.
|
||||
go func() { cs <- "wordy" }() // otra vez, para cs en esta ocasión
|
||||
// Select tiene una sintáxis parecida a la sentencia switch pero cada caso involucra
|
||||
// una operacion de channels. Selecciona un caso de forma aleatoria de los casos
|
||||
// que están listos para comunicarse.
|
||||
select {
|
||||
case i := <-c: // el valor recibido puede ser asignado a una variable
|
||||
fmt.Printf("it's a %T", i)
|
||||
case <-cs: // o el valor puede ser descartado
|
||||
fmt.Println("it's a string")
|
||||
case <-cc: // channel vacío, no está listo para la comunicación.
|
||||
fmt.Println("didn't happen.")
|
||||
}
|
||||
// En este punto un valor fue devuelvto de c o cs. Uno de las dos
|
||||
// goroutines que se iniciaron se ha completado, la otrá permancerá bloqueada.
|
||||
|
||||
learnWebProgramming() // Go lo hace. Tu también quieres hacerlo.
|
||||
}
|
||||
|
||||
// Una simple función del paquete http inicia un servidor web.
|
||||
func learnWebProgramming() {
|
||||
// El primer parámetro de la direccinón TCP a la que escuchar.
|
||||
// El segundo parámetro es una interfaz, concretamente http.Handler.
|
||||
err := http.ListenAndServe(":8080", pair{})
|
||||
fmt.Println(err) // no ignorar errores
|
||||
}
|
||||
|
||||
// Haz pair un http.Handler implementando su único método, ServeHTTP.
|
||||
func (p pair) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
// Servir datos con un método de http.ResponseWriter
|
||||
w.Write([]byte("You learned Go in Y minutes!"))
|
||||
}
|
||||
```
|
||||
|
||||
## Para leer más
|
||||
|
||||
La raíz de todas las cosas de Go es la [web oficial de Go](http://golang.org/).
|
||||
Ahí puedes seguir el tutorial, jugar interactivamente y leer mucho.
|
||||
|
||||
La propia definición del lenguaje también está altamente recomendada. Es fácil de leer
|
||||
e increíblemente corta (como otras definiciones de lenguajes hoy en día)
|
||||
|
||||
En la lista de lectura de estudiantes de Go está el código fuente de la
|
||||
librería estándar. Muy bien documentada, demuestra lo mejor de Go leíble, comprendible,
|
||||
estilo Go y formas Go. Pincha en el nombre de una función en la documentación
|
||||
y te aparecerá el código fuente!
|
||||
|
160
es-es/perl-es.html.markdown
Normal file
160
es-es/perl-es.html.markdown
Normal file
@ -0,0 +1,160 @@
|
||||
---
|
||||
name: perl
|
||||
category: language
|
||||
language: perl
|
||||
filename: learnperl-es.pl
|
||||
contributors:
|
||||
- ["Korjavin Ivan", "http://github.com/korjavin"]
|
||||
translators:
|
||||
- ["Francisco Gomez", "http://github.com/frncscgmz"]
|
||||
lang: es-es
|
||||
---
|
||||
|
||||
Perl 5 es un lenguaje de programación altamente capaz, rico en características con mas de 25 años de desarrollo.
|
||||
|
||||
Perl 5 corre en mas de 100 plataformas desde portales hasta mainframes y es adecuado para realizar prototipos rápidos hasta desarrollar proyectos a gran escala.
|
||||
|
||||
```perl
|
||||
# Comentarios de una sola linea con un carácter hash.
|
||||
|
||||
#### Tipos de variables en Perl
|
||||
|
||||
# Las variables comienzan con el símbolo $.
|
||||
# Un nombre de variable valido empieza con una letra o un guión bajo,
|
||||
# seguido por cualquier numero de letras, números o guiones bajos.
|
||||
|
||||
### Perl tiene tres tipos principales de variables: escalares, arreglos y hashes.
|
||||
|
||||
## Escalares
|
||||
# Un escalar representa un solo valor:
|
||||
my $animal = "camello";
|
||||
my $respuesta = 42;
|
||||
|
||||
# Los valores escalares pueden ser cadenas de caracteres, números enteros o
|
||||
# de punto flotante, Perl automáticamente los convertirá como sea requerido.
|
||||
|
||||
## Arreglos
|
||||
# Un arreglo representa una lista de valores:
|
||||
my @animales = {"camello","llama","buho"};
|
||||
my @numeros = {23,42,69};
|
||||
my @mixto = {"camello",42,1.23};
|
||||
|
||||
|
||||
|
||||
## Hashes
|
||||
# Un hash representa un conjunto de pares llave/valor:
|
||||
|
||||
my %color_fruta = {"manzana","rojo","banana","amarillo"};
|
||||
|
||||
# Puedes usar un espacio en blanco y el operador "=>" para asignarlos mas
|
||||
# fácilmente.
|
||||
|
||||
my %color_fruta = (
|
||||
manzana => "rojo",
|
||||
banana => "amarillo",
|
||||
);
|
||||
# Los escalares, arreglos y hashes están mas documentados en perldata. (perldoc perldata).
|
||||
|
||||
# Los tipos de datos mas complejos pueden ser construidos utilizando
|
||||
# referencias, las cuales te permiten construir listas y hashes dentro
|
||||
# de listas y hashes.
|
||||
|
||||
#### Estructuras condicionales y de ciclos
|
||||
|
||||
# Perl tiene la mayoría de las estructuras condicionales y de ciclos mas comunes.
|
||||
|
||||
if ( $var ) {
|
||||
...
|
||||
} elsif ( $var eq 'bar' ) {
|
||||
...
|
||||
} else {
|
||||
...
|
||||
}
|
||||
|
||||
unless ( condicion ) {
|
||||
...
|
||||
}
|
||||
# Esto es proporcionado como una version mas fácil de leer que "if (!condición)"
|
||||
|
||||
# La post condición al modo Perl
|
||||
print "Yow!" if $zippy;
|
||||
print "No tenemos bananas" unless $bananas;
|
||||
|
||||
# while
|
||||
while ( condicion ) {
|
||||
...
|
||||
}
|
||||
|
||||
|
||||
# for y foreach
|
||||
for ($i = 0; $i <= $max; $i++) {
|
||||
...
|
||||
}
|
||||
|
||||
foreach (@array) {
|
||||
print "Este elemento es $_\n";
|
||||
}
|
||||
|
||||
|
||||
#### Expresiones regulares
|
||||
|
||||
# El soporte de expresiones regulares en Perl es muy amplio y profundo, y es
|
||||
# sujeto a una extensa documentación en perlrequick, perlretut, entre otros.
|
||||
# Sin embargo, resumiendo:
|
||||
|
||||
# Pareo simple
|
||||
if (/foo/) { ... } # verdadero si $_ contiene "foo"
|
||||
if ($a =~ /foo/) { ... } # verdadero si $a contiene "foo"
|
||||
|
||||
# Substitución simple
|
||||
$a =~ s/foo/bar/; # remplaza foo con bar en $a
|
||||
$a =~ s/foo/bar/g; # remplaza TODAS LAS INSTANCIAS de foo con bar en $a
|
||||
|
||||
|
||||
#### Archivos e I/O
|
||||
|
||||
# Puedes abrir un archivo para obtener datos o escribirlos utilizando la
|
||||
# función "open()".
|
||||
|
||||
open(my $entrada, "<" "entrada.txt") or die "No es posible abrir entrada.txt: $!";
|
||||
open(my $salida, ">", "salida.txt") or die "No es posible abrir salida.txt: $!";
|
||||
open(my $log, ">>", "mi.log") or die "No es posible abrir mi.log: $!";
|
||||
|
||||
# Es posible leer desde un gestor de archivo abierto utilizando el operador "<>"
|
||||
# operador. En contexto escalar leer una sola linea desde el gestor de
|
||||
# archivo, y en contexto de lista leer el archivo completo en donde, asigna
|
||||
# cada linea a un elemento de la lista.
|
||||
|
||||
my $linea = <$entrada>;
|
||||
my @lineas = <$entrada>;
|
||||
|
||||
#### Escribiendo subrutinas
|
||||
|
||||
# Escribir subrutinas es fácil:
|
||||
|
||||
sub logger {
|
||||
my $mensajelog = shift;
|
||||
open my $archivolog, ">>", "mi.log" or die "No es posible abrir mi.log: $!";
|
||||
print $archivolog $mensajelog;
|
||||
}
|
||||
|
||||
# Ahora podemos utilizar la subrutina al igual que cualquier otra función
|
||||
# incorporada:
|
||||
|
||||
logger("Tenemos una subrutina logger!");
|
||||
|
||||
|
||||
```
|
||||
|
||||
#### Utilizando módulos Perl
|
||||
|
||||
Los módulos en Perl proveen una gama de funciones que te pueden ayudar a evitar reinventar la rueda, estas pueden ser descargadas desde CPAN( http://www.cpan.org/ ). Algunos de los módulos mas populares ya están incluidos con la misma distribución de Perl.
|
||||
|
||||
perlfaq contiene preguntas y respuestas relacionadas con muchas tareas comunes, y algunas veces provee sugerencias sobre buenos módulos CPAN para usar.
|
||||
|
||||
#### Material de Lectura
|
||||
|
||||
- [perl-tutorial](http://perl-tutorial.org/)
|
||||
- [Aprende en www.perl.com](http://www.perl.org/learn.html)
|
||||
- [perldoc](http://perldoc.perl.org/)
|
||||
- y perl incorporado: `perldoc perlintro`
|
81
fa-ir/brainfuck.html.markdown
Normal file
81
fa-ir/brainfuck.html.markdown
Normal file
@ -0,0 +1,81 @@
|
||||
---
|
||||
language: brainfuck
|
||||
contributors:
|
||||
- ["Mohammad Valipour", "https://github.com/mvalipour"]
|
||||
lang: fa-ir
|
||||
---
|
||||
|
||||
<p dir='rtl'>برین فاک زبان برنامه نویسی تورینگ کامل بی نهایت ساده ایست که دارای فقط هشت</p>
|
||||
<p dir='rtl'>دستور است.</p>
|
||||
|
||||
<p dir='rtl'>هر کارکتری به جر کارکتر های زیر در این زبان در نظر گرفته نمیشود.</p>
|
||||
|
||||
|
||||
`>` `<` `+` `-` `.` `,` `[` `]`
|
||||
|
||||
<p dir='rtl'>برین فاک به صورت یک آرایه ی سی هزار خانه ای کار میکند که در ابتدا تمامی خانه های آن صفر هستند.</p>
|
||||
<p dir='rtl'>همچنین یک اشاره گر در این برنامه به خانه ی فعلی اشاره میکند.</p>
|
||||
|
||||
<p dir='rtl'>در زیر هشت دستور این زبان شرح داده شده است:</p>
|
||||
|
||||
<p dir='rtl'>`+` : یک عدد به خانه ی فعلی اضافه می کند.
|
||||
<p dir='rtl'>`-` : یک عدد از خانه ی فعلی کم می کند. </p>
|
||||
<p dir='rtl'>`>` : اشاره گر به خانه ی بعدی میرود -- به راست</p>
|
||||
<p dir='rtl'>`<` : اشاره گر به خانه ی قبلی میرود -- به چپ</p>
|
||||
<p dir='rtl'>`.` : کارکتر اسکی معادل مقدار خانه ی فعلی را چاپ میکند. -- به عنوان مثال 65 برای A</p>
|
||||
<p dir='rtl'>`,` : یک کارکتر را از ورودی خوانده و مقدار آن را در خانه ی فعلی زخیره میکند.</p>
|
||||
<p dir='rtl'>`[` : اگر مقدار خانه ی فعلی صفر باشد به محل بسته شدن کروشه جهش میکند. -- و از همه ی دستور های بین آن صرف نظر میشود.</p>
|
||||
<p dir='rtl'>در غیر این صورت به دستور بعدی میرود.</p>
|
||||
<p dir='rtl'>`]` : اگر مقدار خانه ی فعلی صفر باشد به خانه ی بعدی و در غیر این صورت به محل باز شدن کروشه جهش می کند. -- به عقب</p>
|
||||
|
||||
<p dir='rtl'>دو علامت کروشه امکان ایجاد حلقه را فراهم میکنند.</p>
|
||||
|
||||
<p dir='rtl'>در اینجا یک برنامه ی ساره برین فاک را مشاهده میکنید.</p>
|
||||
|
||||
```
|
||||
++++++ [ > ++++++++++ < - ] > +++++ .
|
||||
```
|
||||
|
||||
<p dir='rtl'>این برنامه کارکتر A را بر روی خروجی چاپ میکند.</p>
|
||||
<p dir='rtl'>در این برنامه خانه ی اول به عنوان متغیر حلقه و خانه ی دوم برای مقدار عددی A</p>
|
||||
<p dir='rtl'>ابتدا عدد شش در خانه ی اول ایجاد شده. سپس برنامه وارد یک حلقه میشود که در هر بار </p>
|
||||
<p dir='rtl'>تکرار آن اشاره گر به خانه ی دوم رفته و ده بار به خانه ی فعلی اضافه می کند.</p>
|
||||
<p dir='rtl'>-- و در انتهای حلقه به خانه ی اول برگشته تا حلقه کنترل شود</p>
|
||||
<p dir='rtl'>بعد از اتمام حلقه به خانه ی دوم میرود و پنج بار به این خانه اضافه کرده و سپس آنرا چاپ میکند.</p>
|
||||
|
||||
```
|
||||
, [ > + < - ] > .
|
||||
```
|
||||
|
||||
<p dir='rtl'>در این برنامه ابتدا یک کارکتر از ورودی خوانده می شود. سپس یک حلقه به تعداد بار مقدار</p>
|
||||
<p dir='rtl'>عددی کارکتر، یک عدد به خانه ی دوم اضافه می کند. با این کار در واقع برنامه مقدار ورودی را در خانه ی </p>
|
||||
<p dir='rtl'>دوم کپی می کند. و در نهایت آن را برروی خروجی چاپ می کند.</p>
|
||||
|
||||
<p dir='rtl'>توجه داشته باشید که ردر بالا فواصل بین دستور ها فقط برای خوانایی بیشتر گذاشته شده اند.</p>
|
||||
<p dir='rtl'>در واقع برنامه بالا به شکل زیر صحیح می باشد.</p>
|
||||
|
||||
```
|
||||
,[>+<-]>.
|
||||
```
|
||||
|
||||
<p dir='rtl'>حال سعی کنید ببینید که برنامه ی زیر چه کاری انجام می دهد؟</p>
|
||||
|
||||
```
|
||||
,>,< [ > [ >+ >+ << -] >> [- << + >>] <<< -] >>
|
||||
```
|
||||
|
||||
<p dir='rtl'>این برنامه دو عدد را از ورودی خوانده و با هم ضرب می کند.</p>
|
||||
|
||||
<p dir='rtl'>ابتدا دو عدد از ورودی خوانده می شوند. سپس حلقه ی بیرونی بر روی خانه شماره یک شروع میشود.</p>
|
||||
<p dir='rtl'>و درون آن حلقه ی دیگری بر روی خانه ی دوم شروع میشود که خانه ی 3 را زیاد میکند.</p>
|
||||
<p dir='rtl'>ولی مشکلی که در اینجا به وجود می آید اینست که در پایان حلقه ی دوم مقدار خانه ی 2 صفر شده</p>
|
||||
<p dir='rtl'>و مقدار اولیه ی آن از دست رفته است. برای حل این مشکل خانه ی شماره چهار هم زیاد میشود</p>
|
||||
<p dir='rtl'>و در پایان حلقه مقدار آن به خانه 2 کپی میشود.</p>
|
||||
<p dir='rtl'>در پایان خانه ی شماره 2 حاوی حاصلضرب خواهد بود.</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<p dir='rtl'>و این همه ی برین فاک بود! خیلی ساده برای یادگیری ولی سنگین برای به کار بردن.</p>
|
||||
<p dir='rtl'>حال می توانید برای تفریح مشغول نوشتن برنامه ی های مختلف با آن شوید.</p>
|
||||
<p dir='rtl'>و یا یک اجرا کننده برین فاک را با یک زبان دیگر پیاده سازی کنید.</p>
|
||||
<p dir='rtl'>و یا اگر خیلی دوست داشتید یک اجرا کننده ی برین فاک با برین فاک بنویسید!!</p>
|
556
fa-ir/javascript.html.markdown
Normal file
556
fa-ir/javascript.html.markdown
Normal file
@ -0,0 +1,556 @@
|
||||
---
|
||||
language: javascript
|
||||
contributors:
|
||||
- ["Adam Brenecki", "http://adam.brenecki.id.au"]
|
||||
translators:
|
||||
- ["Mohammad Valipour", "https://github.com/mvalipour"]
|
||||
filename: javascript.js
|
||||
lang: fa-ir
|
||||
---
|
||||
|
||||
<p dir='rtl'>
|
||||
جاوااسکریپت توسط برندن ایش از شرکت NetScape در سال 1995 ساخته شد. در ابتدا به عنوان یک زبان اسکریپتنویسی در کنار جاوا (که برای موارد پیچیده تر در طراحی وب در نظر گرفته میشد) مورد استفاده بود، ولی در پی نفوذ بسیار گسترده آن در وب و همچنین پشتیبانی پیش-ساخته آن در مرورگر ها، امروزه به مراتب بیشتر از جاوا در برنامه نویسی سمت-کاربر در وب به کار برده میشود.
|
||||
با این حال جاوااسکریپت فقط محدود به مرورگر های وب نمیشود. Node.js پروژه ایست که یک نسخه ی مستقل از اجراکننده ی موتور جاوااسکریپت V8 از گوگل کروم را در اختیار قرار میده که هر روزه درحال محبوب تر شدن نیز هست.
|
||||
</p>
|
||||
|
||||
<p dir='rtl'>
|
||||
قدر دان نظرات سازنده شما هستم! شما میتوانید از طریق زیر با من تماس بگیرید:
|
||||
</p>
|
||||
|
||||
[@adambrenecki](https://twitter.com/adambrenecki), or
|
||||
[adam@brenecki.id.au](mailto:adam@brenecki.id.au).
|
||||
|
||||
<p dir='rtl'>
|
||||
// توضیحات همانند C هستند. توضیحات یک خطی با دو خط مورب شروع میشوند.,
|
||||
</p>
|
||||
|
||||
<p dir='rtl'>
|
||||
/* و توضیحات چند خطی با خط مورب-ستاره شروع،
|
||||
و با ستاره-خط مورب ختم میشوند */
|
||||
</p>
|
||||
|
||||
```js
|
||||
// Comments are like C. Single-line comments start with two slashes,
|
||||
/* and multiline comments start with slash-star
|
||||
and end with star-slash */
|
||||
```
|
||||
<p dir='rtl'>
|
||||
گزاره ها را میتوانید با نقطه ویرگول پایان دهید ;
|
||||
</p>
|
||||
```js
|
||||
doStuff();
|
||||
```
|
||||
<p dir='rtl'>
|
||||
ولی لزومی به این کار نیست. نقطه ویرگول به صورت خودکار در نظر گرفته میشوند.
|
||||
</p>
|
||||
<p dir='rtl'>
|
||||
وقتی که خط جدیدی شروع میشود. مگر در موارد خاص.
|
||||
</p>
|
||||
```js
|
||||
doStuff()
|
||||
```
|
||||
<p dir='rtl'>برای اینگه درگیر آن موارد خاص نشویم، در اینجا از اون ها </p>
|
||||
<p dir='rtl'>صرف نظر میکنیم.</p>
|
||||
|
||||
<h2 dir='rtl'>1. اعداد، رشته ها و عملگرها</h2>
|
||||
|
||||
<p dir='rtl'>جاوااسکریپت فقط یک نوع عدد دارد و آن عدد اعشاری 64 بیتی IEEE 754 است.</p>
|
||||
<p dir='rtl'>نترسید! و نگران اعداد صحیح نباشید! این اعداد اعشاری دارای 54 بیت مانتیس هستند که قابلیت ذخیره ی </p>
|
||||
<p dir='rtl'>دقیق اعداد صحیح تا مقدار تقریبی 9x10¹⁵ را دارند.</p>
|
||||
```js
|
||||
3; // = 3
|
||||
1.5; // = 1.5
|
||||
```
|
||||
<p dir='rtl'>
|
||||
تمامی عملگر های محاسباتی آن طوری که انتظارش را دارید عمل خواهند کرد.
|
||||
</p>
|
||||
```js
|
||||
1 + 1; // = 2
|
||||
8 - 1; // = 7
|
||||
10 * 2; // = 20
|
||||
35 / 5; // = 7
|
||||
```
|
||||
<p dir='rtl'>و این حتی شامل تقسیم هم میشود.</p>
|
||||
```js
|
||||
5 / 2; // = 2.5
|
||||
```
|
||||
<p dir='rtl'>عملگر های بیتی هم به همین شکل. وقتی از یک عملگر بیتی استفاده میکنید، عدد اعشاری شما</p>
|
||||
<p dir='rtl'>به عدد صحیح علامت دار *تا 32 بیت* تبدیل میشود.</p>
|
||||
```js
|
||||
1 << 2; // = 4
|
||||
```
|
||||
<p dir='rtl'>عملیات داخل پرانتز تقدم بالاتری دارند.</p>
|
||||
```js
|
||||
(1 + 3) * 2; // = 8
|
||||
```
|
||||
<p dir='rtl'>سه مقدار خاص وجود دارند که در واقع مقادیر عددی نیستند:</p>
|
||||
```js
|
||||
Infinity; // result of e.g. 1/0
|
||||
-Infinity; // result of e.g. -1/0
|
||||
NaN; // result of e.g. 0/0
|
||||
```
|
||||
<p dir='rtl'>مقادیر بولی هم تعریف شده هستند:</p>
|
||||
```js
|
||||
true;
|
||||
false;
|
||||
```
|
||||
<p dir='rtl'>رشته ها با آپستروف و یا گیومه تعریف میشوند.</p>
|
||||
```js
|
||||
'abc';
|
||||
"Hello, world";
|
||||
```
|
||||
<p dir='rtl'>و منفی کردن شرط با علامت تعجب</p>
|
||||
```js
|
||||
!true; // = false
|
||||
!false; // = true
|
||||
```
|
||||
<p dir='rtl'>تساوی دو مقدار با ==</p>
|
||||
```js
|
||||
1 == 1; // = true
|
||||
2 == 1; // = false
|
||||
```
|
||||
<p dir='rtl'>و عدم تساوی با !=</p>
|
||||
```js
|
||||
1 != 1; // = false
|
||||
2 != 1; // = true
|
||||
```
|
||||
<p dir='rtl'>و سایر عمیلات های مقایسه</p>
|
||||
```js
|
||||
1 < 10; // = true
|
||||
1 > 10; // = false
|
||||
2 <= 2; // = true
|
||||
2 >= 2; // = true
|
||||
```
|
||||
<p dir='rtl'>رشته ها با علامت جمع به یکدیگر متصل میشوند</p>
|
||||
```js
|
||||
"Hello " + "world!"; // = "Hello world!"
|
||||
```
|
||||
<p dir='rtl'>و با علامت برگتر و یا کوچکتر با یکدیگر مقایسه میشوند.</p>
|
||||
```js
|
||||
"a" < "b"; // = true
|
||||
```
|
||||
<p dir='rtl'>نوع متغیر برای عملیات مقایسه تطبیق داده میشود</p>
|
||||
```js
|
||||
"5" == 5; // = true
|
||||
```
|
||||
<p dir='rtl'>مگر اینکه از سه مساوی استفاده شود!</p>
|
||||
```js
|
||||
"5" === 5; // = false
|
||||
```
|
||||
<p dir='rtl'>با استفاده از charAt میتوانید به کارکتر های یک رشته دسترسی پیدا کنید.</p>
|
||||
```js
|
||||
"This is a string".charAt(0);
|
||||
```
|
||||
<p dir='rtl'>از null برای نشان دادن عمدی مقدار هیج استفاده میشود.</p>
|
||||
<p dir='rtl'>و از undefined برای نشان دادن اینکه در حال حاظر مقدار موجود نمی باشد، هرچند خود undefined یک مقدار محسوب میشود.</p>
|
||||
```js
|
||||
null; // used to indicate a deliberate non-value
|
||||
undefined; // used to indicate a value is not currently present (although undefined
|
||||
// is actually a value itself)
|
||||
```
|
||||
<p dir='rtl'>false, null, undefined, NaN, 0 و "" مقدار نادرست و هر چیز دیگر مقدار درست طلقی میشوند.</p>
|
||||
<p dir='rtl'>توجه داشته باشید که 0 نادرست و "0" درست طلقی میشوند حتی در عبارت 0=="0".</p>
|
||||
|
||||
<h2 dir='rtl'> 2. متغیر ها، آرایه ها و شئ ها </h2>
|
||||
|
||||
<p dir='rtl'>متغیر ها با کلید واژه var تعریف میشوند. اشیا در جاوااسکریپت دارای نوع پویا هستند، </p>
|
||||
<p dir='rtl'>بدین شکل که برای تعریف نیازی به مشخص کردن نوع متعیر نیست. </p>
|
||||
<p dir='rtl'>برای مقدار دهی از علامت مساوی استفاده میشود. </p>
|
||||
```js
|
||||
var someVar = 5;
|
||||
```
|
||||
|
||||
<p dir='rtl'>اگر کلید واژه var را قرار ندهید، هیچ خطایی دریافت نخواهید کرد... </p>
|
||||
```js
|
||||
someOtherVar = 10;
|
||||
```
|
||||
|
||||
<p dir='rtl'>در عوض متغیر شما در گستره ی کل برنامه تعریف شده خواهد بود. </p>
|
||||
|
||||
<p dir='rtl'>متغیر هایی که تعریف شده ولی مقدار دهی نشوند، دارای مقدار undefined خواهند بود. </p>
|
||||
```js
|
||||
var someThirdVar; // = undefined
|
||||
```
|
||||
|
||||
<p dir='rtl'>برای اعمال عملگر های محاسباتی، میانبر هایی وجود دارند: </p>
|
||||
```js
|
||||
someVar += 5; // equivalent to someVar = someVar + 5; someVar is 10 now
|
||||
someVar *= 10; // now someVar is 100
|
||||
```
|
||||
|
||||
<p dir='rtl'>حتی از این هم کوتاهتر برای اضافه یا کم کردن یک عدد با مقدار یک. </p>
|
||||
```js
|
||||
someVar++; // now someVar is 101
|
||||
someVar--; // back to 100
|
||||
```
|
||||
|
||||
<p dir='rtl'>آرایه ها در واقع لیستی مرتب شده از مقادیر مختلف از هر نوعی هستند. </p>
|
||||
```js
|
||||
var myArray = ["Hello", 45, true];
|
||||
```
|
||||
|
||||
<p dir='rtl'>به اعضای یک آرایه میتوان از طریق قرار دادن کروشه در جلوی نام آن دسترسی پیدا کرد. </p>
|
||||
<p dir='rtl'>نمایه ی آرایه از صفر شروع میشود. </p>
|
||||
```js
|
||||
myArray[1]; // = 45
|
||||
```
|
||||
|
||||
<p dir='rtl'>آرایه ها ناپایدار و دارای طول قابل تغییر هستند </p>
|
||||
```js
|
||||
myArray.push("World");
|
||||
myArray.length; // = 4
|
||||
```
|
||||
|
||||
<p dir='rtl'>در جاوااسکریپت، اشیاء چیزی شبیه دیکشنری و یا نقشه در زبان های دیگر هستند: </p>
|
||||
<p dir='rtl'>یک مجموعه ی نامرتب از جفت های کلید-مقدار. </p>
|
||||
```js
|
||||
var myObj = {key1: "Hello", key2: "World"};
|
||||
```
|
||||
|
||||
<p dir='rtl'>کلید ها از نوع رشته هستند ولی در صورتی که مقدار معتبری برای اسم گزاری باشند نیازی به آوردن آنها درون گیومه نیست. </p>
|
||||
```js
|
||||
var myObj = {myKey: "myValue", "my other key": 4};
|
||||
```
|
||||
|
||||
<p dir='rtl'>اعضای یک شئ را نیز میتوانید با استفاده از کروشه در مقابل نام آنها استخراج کنید. </p>
|
||||
```js
|
||||
myObj["my other key"]; // = 4
|
||||
```
|
||||
|
||||
<p dir='rtl'>...و یا از طریق نقطه در صورتی که اسم عضو مورد نظر اسم معتبری برای اسم گزاری باشد.</p>
|
||||
```js
|
||||
myObj.myKey; // = "myValue"
|
||||
```
|
||||
|
||||
<p dir='rtl'>اشیاء ناپایدار و قابل اضافه کردن عضو جدید هستند.</p>
|
||||
```js
|
||||
myObj.myThirdKey = true;
|
||||
```
|
||||
|
||||
<p dir='rtl'>اگر سعی کنید عضوی را که وجود ندارد استخراج کنید، مقدار undefined را دریافت خواهید کرد. </p>
|
||||
```js
|
||||
myObj.myFourthKey; // = undefined
|
||||
```
|
||||
|
||||
<h2 dir='rtl'>3. منطق و ساختار کنترل</h2>
|
||||
|
||||
<p dir='rtl'>ساختار if به شکلی که انتظارش را دارید کار میکند.</p>
|
||||
```js
|
||||
var count = 1;
|
||||
if (count == 3){
|
||||
// evaluated if count is 3
|
||||
} else if (count == 4) {
|
||||
// evaluated if count is 4
|
||||
} else {
|
||||
// evaluated if it's not either 3 or 4
|
||||
}
|
||||
```
|
||||
|
||||
<p dir='rtl'>و همینطور حلقه while</p>
|
||||
```js
|
||||
while (true) {
|
||||
// An infinite loop!
|
||||
}
|
||||
```
|
||||
|
||||
<p dir='rtl'>حلقه do-while شبیه while است با این تفاوت که حداقل یکبار اجرا میشود.</p>
|
||||
```js
|
||||
var input
|
||||
do {
|
||||
input = getInput();
|
||||
} while (!isValid(input))
|
||||
```
|
||||
|
||||
<p dir='rtl'>حلقه for همانند زبان C و جاوا کار می کند.</p>
|
||||
<p dir='rtl'>مقدار دهی اولیه; شرط ادامه; چرخش حلقه</p>
|
||||
```js
|
||||
for (var i = 0; i < 5; i++){
|
||||
// will run 5 times
|
||||
}
|
||||
```
|
||||
|
||||
<p dir='rtl'>عملگر && و || به ترتیب "و" و "یا" ی منطقی هستند.</p>
|
||||
```js
|
||||
if (house.size == "big" && house.colour == "blue"){
|
||||
house.contains = "bear";
|
||||
}
|
||||
if (colour == "red" || colour == "blue"){
|
||||
// colour is either red or blue
|
||||
}
|
||||
```
|
||||
|
||||
<p dir='rtl'>از || همچنین میتوان برای تعیین مقدار پیشفرض استفاده کرد.</p>
|
||||
```js
|
||||
var name = otherName || "default";
|
||||
```
|
||||
|
||||
<h2 dir='rtl'>4. توابع و مفاهیم گستره و بستار</h2>
|
||||
|
||||
<p dir='rtl'>توابع در جاوااسکریپت با استفاده از کلیدواژه ی function تعریف میشوند.</p>
|
||||
```js
|
||||
function myFunction(thing){
|
||||
return thing.toUpperCase();
|
||||
}
|
||||
myFunction("foo"); // = "FOO"
|
||||
```
|
||||
|
||||
<p dir='rtl'>توابع در جاوااسکریپت نوعی شئ پایه محسوب میشوند، بنابر این می توانید آنها را به اشیاء مختلف</p>
|
||||
<p dir='rtl'>اضافه کنید و یا به عنوان پارامتر به توابع دیگر ارسال کنید.</p>
|
||||
<p dir='rtl'>- برای مثال وقتی که با یک رویداد کار میکنید.</p>
|
||||
```js
|
||||
function myFunction(){
|
||||
// this code will be called in 5 seconds' time
|
||||
}
|
||||
setTimeout(myFunction, 5000);
|
||||
```
|
||||
|
||||
<p dir='rtl'>توجه کنید که setTimeout تابعی تعریف شده در جاوااسکریپت نیست، ولی مرورگر ها و node.js از آن پشتیبانی میکنند.</p>
|
||||
|
||||
|
||||
<p dir='rtl'>توابع نیازی به داشتن اسم ندارند. برای مثال وقتی تابعی را به تابعی دیگر ارسال میکنید</p>
|
||||
<p dir='rtl'>میتوانید آنرا به صورت بینام تعریف کنید.</p>
|
||||
```js
|
||||
setTimeout(function(){
|
||||
// this code will be called in 5 seconds' time
|
||||
}, 5000);
|
||||
```
|
||||
|
||||
<p dir='rtl'>توابع دارای محدوده ی متغیر های خود هستند.</p>
|
||||
<p dir='rtl'>بر خلاف دیگر ساختار ها - مانند if</p>
|
||||
```js
|
||||
if (true){
|
||||
var i = 5;
|
||||
}
|
||||
i; // = 5 - not undefined as you'd expect in a block-scoped language
|
||||
```
|
||||
|
||||
<p dir='rtl'>به همین دلیل الگوی خاصی به نام "تابعی که بلافاصله صدا زده میشود" پدید آمده </p>
|
||||
<p dir='rtl'>تا از اضافه شدن متغیر های قسمتی از برنامه به گستره ی کلی برنامه جلوگیری شود.</p>
|
||||
```js
|
||||
(function(){
|
||||
var temporary = 5;
|
||||
// We can access the global scope by assiging to the 'global object', which
|
||||
// in a web browser is always 'window'. The global object may have a
|
||||
// different name in non-browser environments such as Node.js.
|
||||
window.permanent = 10;
|
||||
})();
|
||||
temporary; // raises ReferenceError
|
||||
permanent; // = 10
|
||||
```
|
||||
|
||||
<p dir='rtl'>یکی از برترین ویژگی های جاوااسکریپت مفهومی با نام بستار است</p>
|
||||
<p dir='rtl'>بدین شکل که اگر تابعی درون تابع دیگری تعریف شود، تابع درونی به تمام متغیر های تابع خارجی دسترسی</p>
|
||||
<p dir='rtl'>خواهد داشت، حتی بعد از اینکه تابع خارجی به اتمام رسیده باشد.</p>
|
||||
```js
|
||||
function sayHelloInFiveSeconds(name){
|
||||
var prompt = "Hello, " + name + "!";
|
||||
function inner(){
|
||||
alert(prompt);
|
||||
}
|
||||
setTimeout(inner, 5000);
|
||||
// setTimeout is asynchronous, so the sayHelloInFiveSeconds function will
|
||||
// exit immediately, and setTimeout will call inner afterwards. However,
|
||||
// because inner is "closed over" sayHelloInFiveSeconds, inner still has
|
||||
// access to the 'prompt' variable when it is finally called.
|
||||
}
|
||||
sayHelloInFiveSeconds("Adam"); // will open a popup with "Hello, Adam!" in 5s
|
||||
```
|
||||
|
||||
<h2 dir='rtl'>5. دیگر اشیاء، سازنده ها و پیشنمونه ها</h2>
|
||||
|
||||
<p dir='rtl'>اشیاء میتوانند تابع داشته باشند.</p>
|
||||
```js
|
||||
var myObj = {
|
||||
myFunc: function(){
|
||||
return "Hello world!";
|
||||
}
|
||||
};
|
||||
myObj.myFunc(); // = "Hello world!"
|
||||
```
|
||||
|
||||
<p dir='rtl'>وقتی تابع یک شی صدا زده می شود، تابع میتواند به سایر مقادیر درون آن شی </p>
|
||||
<p dir='rtl'>از طریق کلید واژه ی this دسترسی داشته باشد.</p>
|
||||
```js
|
||||
myObj = {
|
||||
myString: "Hello world!",
|
||||
myFunc: function(){
|
||||
return this.myString;
|
||||
}
|
||||
};
|
||||
myObj.myFunc(); // = "Hello world!"
|
||||
```
|
||||
|
||||
|
||||
<p dir='rtl'>اینکه مقدار this چه باشد بستگی به این دارد که تابع چگونه صدا زده شود</p>
|
||||
<p dir='rtl'>نه اینکه تابع کجا تعریف شده است.</p>
|
||||
<p dir='rtl'>بنابر این تابع بالا اگر بدین شکل صدا زده شود کار نخواهد کرد</p>
|
||||
```js
|
||||
var myFunc = myObj.myFunc;
|
||||
myFunc(); // = undefined
|
||||
```
|
||||
|
||||
|
||||
<p dir='rtl'>به همین شکل، تابعی که در جای دیگر تعریف شده را میتوانید به یک شی الحاق کنید</p>
|
||||
<p dir='rtl'>و بدین ترتیب تابع میتواند به مقادیر درون شی از طریق this دسترسی پیدا کند.</p>
|
||||
```js
|
||||
var myOtherFunc = function(){
|
||||
return this.myString.toUpperCase();
|
||||
}
|
||||
myObj.myOtherFunc = myOtherFunc;
|
||||
myObj.myOtherFunc(); // = "HELLO WORLD!"
|
||||
```
|
||||
|
||||
|
||||
<p dir='rtl'>اگر تابعی با کلید new صدا زده شوند، شی جدیدی ایجاد شده و تابع در گستره ی آن صدا زده میشود.</p>
|
||||
<p dir='rtl'>توابعی که بدین شکل صدا زده شوند در واقع نقش سازنده را ایفا می کنند.</p>
|
||||
```js
|
||||
var MyConstructor = function(){
|
||||
this.myNumber = 5;
|
||||
}
|
||||
myNewObj = new MyConstructor(); // = {myNumber: 5}
|
||||
myNewObj.myNumber; // = 5
|
||||
```
|
||||
|
||||
|
||||
<p dir='rtl'>تمامی اشیاء در جاوااسکریپت دارای یک پیش نمونه هستند</p>
|
||||
<p dir='rtl'>به شکلی که اگر تابع صدا زده شده بر روی شی مستقیما روی آن تعریف نشده باشد</p>
|
||||
<p dir='rtl'>اجرا کننده ی برنامه در لیست پیش نمونه به دنبال آن تابع خواهد گشت</p>
|
||||
|
||||
<p dir='rtl'>برخی اجرا کننده های جاوااسکریپت به شما اجازه ی دسترسی به پیش نمونه های یک شی را از</p>
|
||||
<p dir='rtl'>طریق عضو جادویی __proto__ میدهند.</p>
|
||||
<p dir='rtl'>هرچند این به شناخت پیش نمونه ها کمک میکند ولی در حیطه ی جاوااسکریپت استاندارد قرار نمیگیرد.</p>
|
||||
<p dir='rtl'>در ادامه شکل استاندارد پیش نمونه ها مورد بررسی قرار میگیرند.</p>
|
||||
```js
|
||||
var myObj = {
|
||||
myString: "Hello world!",
|
||||
};
|
||||
var myPrototype = {
|
||||
meaningOfLife: 42,
|
||||
myFunc: function(){
|
||||
return this.myString.toLowerCase()
|
||||
}
|
||||
};
|
||||
myObj.__proto__ = myPrototype;
|
||||
myObj.meaningOfLife; // = 42
|
||||
```
|
||||
|
||||
<p dir='rtl'>این موضوع در مورد توابع نیز صدق میکند.</p>
|
||||
```js
|
||||
myObj.myFunc(); // = "hello world!"
|
||||
```
|
||||
|
||||
|
||||
<p dir='rtl'>اگر عضو مورد نظر در پیش نمونه ی شی یافت نشود، پیش نمونه ی پیش نمونه جستجو شده و الی آخر</p>
|
||||
```js
|
||||
myPrototype.__proto__ = {
|
||||
myBoolean: true
|
||||
};
|
||||
myObj.myBoolean; // = true
|
||||
```
|
||||
|
||||
|
||||
<p dir='rtl'>توجه داشته باشید که پیش نمونه ها کپی نمی شوند و هر شی جدید به پیش نمونه موجود اشاره میکند</p>
|
||||
<p dir='rtl'>بدین ترتیب اگر تابعی به پیش نمونه اضافه شود تمامی اشیاء میتوانند به آن دسترسی پیدا کنند.</p>
|
||||
```js
|
||||
myPrototype.meaningOfLife = 43;
|
||||
myObj.meaningOfLife; // = 43
|
||||
```
|
||||
|
||||
<p dir='rtl'>پیش تر اشاره شد که __proto__ راه استانداردی برای دسترسی به پیش نمونه نیست و هیچ استانداردی نیز برای دسترسی به پیش نمونه ی یک شی موجود پیش بینی نشده است</p>
|
||||
<p dir='rtl'>ولی دو راه برای ارائه پیش نمونه برای اشیاء جدید وجود دارد.</p>
|
||||
|
||||
<p dir='rtl'>اولی وقتیست که از تابع Object.create استفاده میشود - که اخیرا به زبان اضافه شده است و بنابراین بر روی همه ی پیاده سازی های آن وجود ندارد.</p>
|
||||
```js
|
||||
var myObj = Object.create(myPrototype);
|
||||
myObj.meaningOfLife; // = 43
|
||||
```
|
||||
|
||||
|
||||
<p dir='rtl'>راه دوم - که همه جا قابل استفاده است - مربوط به سازنده ها می شود.</p>
|
||||
<p dir='rtl'>سازنده ها دارای عضوی با نام prototype هستند. این پیش نمونه ی خود سازنده نیست</p>
|
||||
<p dir='rtl'>بلکه پیش نمونه ایست که به تمامی اشیاء ساخته شده توسط این سازنده الحاق میشود.</p>
|
||||
```js
|
||||
MyConstructor.prototype = {
|
||||
myNumber: 5,
|
||||
getMyNumber: function(){
|
||||
return this.myNumber;
|
||||
}
|
||||
};
|
||||
var myNewObj2 = new MyConstructor();
|
||||
myNewObj2.getMyNumber(); // = 5
|
||||
myNewObj2.myNumber = 6
|
||||
myNewObj2.getMyNumber(); // = 6
|
||||
```
|
||||
|
||||
|
||||
<p dir='rtl'>رشته ها و سایر سازنده های پیش ساخته ی زبان نیز دارای این ویژگی هستند.</p>
|
||||
```js
|
||||
var myNumber = 12;
|
||||
var myNumberObj = new Number(12);
|
||||
myNumber == myNumberObj; // = true
|
||||
```
|
||||
|
||||
|
||||
<p dir='rtl'>به جز این که این سازنده ها دقیقا مانند سازنده های دیگر نیستند.</p>
|
||||
```js
|
||||
typeof(myNumber); // = 'number'
|
||||
typeof(myNumberObj); // = 'object'
|
||||
myNumber === myNumberObj; // = false
|
||||
if (0){
|
||||
// This code won't execute, because 0 is falsy.
|
||||
}
|
||||
if (Number(0)){
|
||||
// This code *will* execute, because Number(0) is truthy.
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
<p dir='rtl'>ولی به هر حال هم اشیاء عادی و هم اشیاء پیش ساخته هر دو در داشتن پیش نمونه مشترک هستند</p>
|
||||
<p dir='rtl'>بنابر این شما میتوانید ویژگی و تابع جدیدی به رشته ها - به عنوان مثال - اضافه کنید.</p>
|
||||
|
||||
|
||||
<p dir='rtl'>گاها به از این خاصیت با عنوان پلی فیل و برای اضافه کردن ویژگی های جدید به مجموعه ای از اشیاء فعلی زبان استفاده میشود </p>
|
||||
<p dir='rtl'>که کاربرد فراوانی در پشتیبانی از نسخه های قدیمیتر مرورگر ها دارد.</p>
|
||||
```js
|
||||
String.prototype.firstCharacter = function(){
|
||||
return this.charAt(0);
|
||||
}
|
||||
"abc".firstCharacter(); // = "a"
|
||||
```
|
||||
|
||||
|
||||
<p dir='rtl'>برای مثال، پیشتر اشاره کردیم که Object.create در نسخه های جدید پشتیبانی نشده است</p>
|
||||
<p dir='rtl'>ولی میتوان آن را به صورت پلی فیل استفاده کرد.</p>
|
||||
```js
|
||||
if (Object.create === undefined){ // don't overwrite it if it exists
|
||||
Object.create = function(proto){
|
||||
// make a temporary constructor with the right prototype
|
||||
var Constructor = function(){};
|
||||
Constructor.prototype = proto;
|
||||
// then use it to create a new, appropriately-prototyped object
|
||||
return new Constructor();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<h2 dir='rtl'> منابع دیگر </h2>
|
||||
|
||||
The [Mozilla Developer
|
||||
Network](https://developer.mozilla.org/en-US/docs/Web/JavaScript)
|
||||
<p dir='rtl'>مرجعی بسیار خوب برای جاوااسکریپت به شکلی که در مرورگر ها مورد استفاده قرار گرفته است.</p>
|
||||
<p dir='rtl'>از آنجایی که این منبع یک ویکی میباشد همانطور که مطالب بیشتری یاد میگیرید میتوانید به دیگران نیز در یادگیری آن کمک کنید.</p>
|
||||
|
||||
MDN's [A re-introduction to
|
||||
JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript)
|
||||
<p dir='rtl'>مشابه مطالبی که اینجا مطرح شده با جزییات بیشتر. در اینجا به شکل عمدی جاوااسکریپت فقط از دیدگاه زبان برنامه نویسی مورد بررسی قرار گرفته</p>
|
||||
<p dir='rtl'>در حالی که در این منبع میتوانید بیشتر از کاربرد آن در صفحات وب آشنایی پیدا کنید.</p>
|
||||
[Document Object
|
||||
Model](https://developer.mozilla.org/en-US/docs/Using_the_W3C_DOM_Level_1_Core)
|
||||
|
||||
[Javascript Garden](http://bonsaiden.github.io/JavaScript-Garden/)
|
||||
<p dir='rtl'>راهنمای دقیقی از قسمت های غیر ملموس زبان.</p>
|
||||
|
||||
<p dir='rtl'>اضافه بر این در ویرایش این مقاله، قسمت هایی از سایت زیر مورد استفاده قرار گرفته است.</p>
|
||||
Louie Dinh's Python tutorial on this site, and the [JS
|
||||
Tutorial](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript)
|
||||
on the Mozilla Developer Network.
|
398
fr-fr/clojure-fr.html.markdown
Normal file
398
fr-fr/clojure-fr.html.markdown
Normal file
@ -0,0 +1,398 @@
|
||||
---
|
||||
language: clojure
|
||||
filename: learnclojure-fr.clj
|
||||
contributors:
|
||||
- ["Adam Bard", "http://adambard.com/"]
|
||||
translators:
|
||||
- ["Bastien Guerry", "https://github.com/bzg"]
|
||||
lang: fr-fr
|
||||
---
|
||||
|
||||
Clojure est un langage de la famille des Lisp développé pour la machine
|
||||
virtuelle Java. Ce langage insiste beaucoup plus sur la [programmation
|
||||
fonctionnelle](https://fr.wikipedia.org/wiki/Programmation_fonctionnelle) pure
|
||||
que Common Lisp, mais comprend plusieurs outils de gestion de la mémoire
|
||||
transactionnelle
|
||||
[STM](https://en.wikipedia.org/wiki/Software_transactional_memory) pour gérer
|
||||
les changements d'états si besoin.
|
||||
|
||||
Cette combinaison permet de gérer le parallélisme très simplement, et
|
||||
souvent de façon automatique.
|
||||
|
||||
(Vous avez besoin de Clojure 1.2 ou plus récent pour ce tutoriel.)
|
||||
|
||||
```clojure
|
||||
; Les commentaires commencent avec un point-virgule.
|
||||
|
||||
; Clojure est composé de « formes », qui sont simplement des listes
|
||||
; d'expressions entre parenthèses, séparées par une ou des espaces.
|
||||
;
|
||||
; L'interpréteur Clojure suppose que le premier élément est une fonction
|
||||
; ou une macro, et que le reste contient des arguments.
|
||||
|
||||
; Le premier appel dans un fichier doit être ns, pour définir
|
||||
; l'espace de nom
|
||||
(ns learnclojure)
|
||||
|
||||
; D'autres d'exemples basiques:
|
||||
|
||||
; str va créer une chaîne de caractères à partir de tous ses arguments
|
||||
(str "Hello" " " "World") ; => "Hello World"
|
||||
|
||||
; Les opérations mathématiques sont simples
|
||||
(+ 1 1) ; => 2
|
||||
(- 2 1) ; => 1
|
||||
(* 1 2) ; => 2
|
||||
(/ 2 1) ; => 2
|
||||
|
||||
; L'égalité est =
|
||||
(= 1 1) ; => true
|
||||
(= 2 1) ; => false
|
||||
|
||||
; Vous avez aussi besoin de not pour la négation logique
|
||||
(not true) ; => false
|
||||
|
||||
; Les formes imbriquées fonctionnent comme on s'y attend
|
||||
(+ 1 (- 3 2)) ; = 1 + (3 - 2) => 2
|
||||
|
||||
; Types
|
||||
;;;;;;;;;;;;;
|
||||
|
||||
; Clojure utilise les types d'objets Java pour les booléens, les chaînes de
|
||||
; caractères et les nombres.
|
||||
; Utilisez `class` pour inspecter les types.
|
||||
(class 1) ; Les nombres entiers littéraux sont java.lang.Long par défaut
|
||||
(class 1.); Les flottants littéraux sont java.lang.Double
|
||||
(class ""); Les chaînes sont toujours entourées de guillemets doubles, et sont java.lang.String
|
||||
(class false) ; Les booléens sont java.lang.Boolean
|
||||
(class nil); La valeur "null" est appelée nil
|
||||
|
||||
; Si vous voulez créer une liste littérale de données, utilisez ' pour en
|
||||
; empêcher son évaluation
|
||||
'(+ 1 2) ; => (+ 1 2)
|
||||
; (qui est un raccourci pour (quote (+ 1 2)))
|
||||
|
||||
; Vous pouvez évaluer une liste "quotée":
|
||||
(eval '(+ 1 2)) ; => 3
|
||||
|
||||
; Collections & séquences
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
; Les listes sont des structures de données en listes chaînées, alors que les
|
||||
; vecteurs reposent sur des tableaux.
|
||||
; Les vecteurs et les listes sont des classes Java aussi !
|
||||
(class [1 2 3]); => clojure.lang.PersistentVector
|
||||
(class '(1 2 3)); => clojure.lang.PersistentList
|
||||
|
||||
; Une liste serait écrite comme (1 2 3), mais nous devons la quoter
|
||||
; pour empêcher l'interpréteur de penser que c'est une fonction.
|
||||
; Et (list 1 2 3) est la même chose que '(1 2 3)
|
||||
|
||||
; Les "Collections" sont juste des groupes de données
|
||||
; Les listes et les vecteurs sont tous deux des collections:
|
||||
(coll? '(1 2 3)) ; => true
|
||||
(coll? [1 2 3]) ; => true
|
||||
|
||||
; Les "séquences" (seqs) sont des abstractions à partir de listes de données.
|
||||
; Seules les listes sont elles-mêmes des séquences.
|
||||
(seq? '(1 2 3)) ; => true
|
||||
(seq? [1 2 3]) ; => false
|
||||
|
||||
; Une séquence n'a besoin de fournir une entrée que lorsqu'on y accède.
|
||||
; Donc, les séquences peuvent être "lazy" -- et définir une série infinie:
|
||||
(range 4) ; => (0 1 2 3)
|
||||
(range) ; => (0 1 2 3 4 ...) (une série infinie)
|
||||
(take 4 (range)) ; (0 1 2 3)
|
||||
|
||||
; Utilisez cons pour ajouter un item au début d'une liste ou d'un vecteur
|
||||
(cons 4 [1 2 3]) ; => (4 1 2 3)
|
||||
(cons 4 '(1 2 3)) ; => (4 1 2 3)
|
||||
|
||||
; Conj ajoutera un item à une collection de la manière la plus efficace
|
||||
; Pour les listes, conj ajoute l'item au début; pour les vecteurs, à la fin.
|
||||
(conj [1 2 3] 4) ; => [1 2 3 4]
|
||||
(conj '(1 2 3) 4) ; => (4 1 2 3)
|
||||
|
||||
; Utilisez concat pour ajouter des listes ou vecteurs:
|
||||
(concat [1 2] '(3 4)) ; => (1 2 3 4)
|
||||
|
||||
; Utilisez filter, map pour interagir avec des collections
|
||||
(map inc [1 2 3]) ; => (2 3 4)
|
||||
(filter even? [1 2 3]) ; => (2)
|
||||
|
||||
; Utilisez reduce pour les réduire
|
||||
(reduce + [1 2 3 4])
|
||||
; = (+ (+ (+ 1 2) 3) 4)
|
||||
; => 10
|
||||
|
||||
; Reduce peut aussi prendre un argument pour la valeur initiale
|
||||
(reduce conj [] '(3 2 1))
|
||||
; = (conj (conj (conj [] 3) 2) 1)
|
||||
; => [3 2 1]
|
||||
|
||||
; Fonctions
|
||||
;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
; Utilisez fn pour créer de nouvelles fonctions.
|
||||
; Une fonction renvoie toujours sa dernière expression.
|
||||
(fn [] "Hello World") ; => fn
|
||||
|
||||
; (Vous devez ajouter des parenthèses pour l'appeler)
|
||||
((fn [] "Hello World")) ; => "Hello World"
|
||||
|
||||
; Vous pouvez créer une variable en utilisant def
|
||||
(def x 1)
|
||||
x ; => 1
|
||||
|
||||
; Assignez une fonction à une variable
|
||||
(def hello-world (fn [] "Hello World"))
|
||||
(hello-world) ; => "Hello World"
|
||||
|
||||
; Vous pouvez raccourcir le procédé en utilisant defn
|
||||
(defn hello-world [] "Hello World")
|
||||
|
||||
; [] contient la liste des arguments de la fonction
|
||||
(defn hello [name]
|
||||
(str "Hello " name))
|
||||
(hello "Steve") ; => "Hello Steve"
|
||||
|
||||
; Vous pouvez aussi utiliser ce raccourci pour créer des fonctions
|
||||
(def hello2 #(str "Hello " %1))
|
||||
(hello2 "Fanny") ; => "Hello Fanny"
|
||||
|
||||
; Vous pouvez avoir des fonctions multi-variadiques
|
||||
(defn hello3
|
||||
([] "Hello World")
|
||||
([name] (str "Hello " name)))
|
||||
(hello3 "Jake") ; => "Hello Jake"
|
||||
(hello3) ; => "Hello World"
|
||||
|
||||
; Les fonctions peuvent inclure des arguments supplémentaires dans une séquence
|
||||
(defn count-args [& args]
|
||||
(str "You passed " (count args) " args: " args))
|
||||
(count-args 1 2 3) ; => "Vous avez passé 3 args: (1 2 3)"
|
||||
|
||||
; Vous pouvez combiner les arguments normaux et supplémentaires
|
||||
(defn hello-count [name & args]
|
||||
(str "Hello " name ", vous avez passé " (count args) " args supplémentaires"))
|
||||
(hello-count "Finn" 1 2 3)
|
||||
; => "Hello Finn, vous avez passé 3 args supplémentaires"
|
||||
|
||||
|
||||
; Maps
|
||||
;;;;;;;;;;;;;;;
|
||||
|
||||
; Les hashmaps et les arraymaps partagent une interface. Les hashmaps
|
||||
; sont interrogés plus rapidement mais ne retiennent pas l'ordre des clefs.
|
||||
(class {:a 1 :b 2 :c 3}) ; => clojure.lang.PersistentArrayMap
|
||||
(class (hash-map :a 1 :b 2 :c 3)) ; => clojure.lang.PersistentHashMap
|
||||
|
||||
; Les array maps deviennent automatiquement des hashmaps pour la
|
||||
; plupart des opérations si elles deviennent assez larges, donc vous
|
||||
; n'avez pas à vous en faire.
|
||||
|
||||
; Tous les types "hashables" sont acceptés comme clefs, mais en
|
||||
; général on utilise des mots-clefs ("keywords")
|
||||
; Les mots-clefs sont comme les chaînes de caractères mais en plus efficaces
|
||||
(class :a) ; => clojure.lang.Keyword
|
||||
|
||||
(def stringmap {"a" 1, "b" 2, "c" 3})
|
||||
stringmap ; => {"a" 1, "b" 2, "c" 3}
|
||||
|
||||
(def keymap {:a 1, :b 2, :c 3})
|
||||
keymap ; => {:a 1, :c 3, :b 2}
|
||||
|
||||
; Au passage, les virgules sont toujours traitées comme des espaces et
|
||||
; ne font rien.
|
||||
|
||||
; Sélectionnez une valeur dans une map en l'appelant comme fonction
|
||||
(stringmap "a") ; => 1
|
||||
(keymap :a) ; => 1
|
||||
|
||||
; Les mots-clefs peuvent aussi être utilisés pour sélectionner leur
|
||||
; valeur dans une map !
|
||||
(:b keymap) ; => 2
|
||||
|
||||
; N'essayez pas ça avec les chaînes de caractères
|
||||
;("a" stringmap)
|
||||
; => Exception: java.lang.String cannot be cast to clojure.lang.IFn
|
||||
|
||||
; Sélectionner une clef absente renvoie nil
|
||||
(stringmap "d") ; => nil
|
||||
|
||||
; Use assoc to add new keys to hash-maps
|
||||
(def newkeymap (assoc keymap :d 4))
|
||||
newkeymap ; => {:a 1, :b 2, :c 3, :d 4}
|
||||
|
||||
; Mais souvenez-vous, les types en Clojure sont immuables !
|
||||
keymap ; => {:a 1, :b 2, :c 3}
|
||||
|
||||
; Utilisez dissoc pour retirer des clefs
|
||||
(dissoc keymap :a :b) ; => {:c 3}
|
||||
|
||||
; Ensembles
|
||||
;;;;;;;;;;;;;;;
|
||||
|
||||
(class #{1 2 3}) ; => clojure.lang.PersistentHashSet
|
||||
(set [1 2 3 1 2 3 3 2 1 3 2 1]) ; => #{1 2 3}
|
||||
|
||||
; Ajoutez un élément avec conj
|
||||
(conj #{1 2 3} 4) ; => #{1 2 3 4}
|
||||
|
||||
; Retirez-en un avec disj
|
||||
(disj #{1 2 3} 1) ; => #{2 3}
|
||||
|
||||
; Testez la présence en utilisant l'ensemble comme une fonction
|
||||
(#{1 2 3} 1) ; => 1
|
||||
(#{1 2 3} 4) ; => nil
|
||||
|
||||
; Il y a encore d'autres fonctions dans l'espace de nom clojure.sets.
|
||||
|
||||
; Formes utiles
|
||||
;;;;;;;;;;;;;;;
|
||||
|
||||
; Les constructions logiques en Clojure sont juste des macros, et
|
||||
ressemblent à toutes les autres formes:
|
||||
(if false "a" "b") ; => "b"
|
||||
(if false "a") ; => nil
|
||||
|
||||
; Utilisez let pour créer des assignations temporaires
|
||||
(let [a 1 b 2]
|
||||
(> a b)) ; => false
|
||||
|
||||
; Groupez les énoncés ensemble avec do
|
||||
(do
|
||||
(print "Hello")
|
||||
"World") ; => "World" (prints "Hello")
|
||||
|
||||
; Les fonctions ont un do implicit
|
||||
(defn print-and-say-hello [name]
|
||||
(print "Saying hello to " name)
|
||||
(str "Hello " name))
|
||||
(print-and-say-hello "Jeff") ;=> "Hello Jeff" (prints "Saying hello to Jeff")
|
||||
|
||||
; De même pour let
|
||||
(let [name "Urkel"]
|
||||
(print "Saying hello to " name)
|
||||
(str "Hello " name)) ; => "Hello Urkel" (prints "Saying hello to Urkel")
|
||||
|
||||
; Modules
|
||||
;;;;;;;;;;;;;;;
|
||||
|
||||
; Utilisez "use" pour obtenir toutes les fonctions d'un module
|
||||
(use 'clojure.set)
|
||||
|
||||
; Maintenant nous pouvons utiliser les opération de set
|
||||
(intersection #{1 2 3} #{2 3 4}) ; => #{2 3}
|
||||
(difference #{1 2 3} #{2 3 4}) ; => #{1}
|
||||
|
||||
; Vous pouvez aussi choisir un sous-ensemble de fonctions à importer
|
||||
(use '[clojure.set :only [intersection]])
|
||||
|
||||
; Utilisez require pour importer un module
|
||||
(require 'clojure.string)
|
||||
|
||||
; Utilisez / pour appeler les fonctions d'un module
|
||||
; Ici, le module est clojure.string et la fonction est blank?
|
||||
(clojure.string/blank? "") ; => true
|
||||
|
||||
; Vous pouvez associer un nom plus court au module au moment de l'importer
|
||||
(require '[clojure.string :as str])
|
||||
(str/replace "This is a test." #"[a-o]" str/upper-case) ; => "THIs Is A tEst."
|
||||
; (#"" dénote une expression régulière)
|
||||
|
||||
; Vous pouvez utiliser require (et use, mais ne le faites pas) en
|
||||
; appelant :require depuis un espace de noms.
|
||||
; Dans ce cas-là, vous n'avez pas besoin de "quoter" vos modules:
|
||||
(ns test
|
||||
(:require
|
||||
[clojure.string :as str]
|
||||
[clojure.set :as set]))
|
||||
|
||||
; Java
|
||||
;;;;;;;;;;;;;;;;;
|
||||
|
||||
; Java a une librairie standard énorme, donc vous voudrez apprendre à
|
||||
; vous familiariser avec.
|
||||
|
||||
; Utilisez import pour charger un module java
|
||||
(import java.util.Date)
|
||||
|
||||
; Vous pouvez importer depuis un ns aussi.
|
||||
(ns test
|
||||
(:import java.util.Date
|
||||
java.util.Calendar))
|
||||
|
||||
; Utilisez les noms de classes avec "." à la fin pour créer une instance
|
||||
(Date.) ; <un objet date>
|
||||
|
||||
; Utilisez . pour invoquer des méthodes. Ou utilisez le raccourci ".method"
|
||||
(. (Date.) getTime) ; <un timestamp>
|
||||
(.getTime (Date.)) ; exactement la même chose
|
||||
|
||||
; Utilisez / pour appeler des méthodes statiques
|
||||
(System/currentTimeMillis) ; <un timestamp> (system est toujours présent)
|
||||
|
||||
; Utilisez doto to rendre plus tolérable l'interaction avec des
|
||||
; classes (mutables)
|
||||
(import java.util.Calendar)
|
||||
(doto (Calendar/getInstance)
|
||||
(.set 2000 1 1 0 0 0)
|
||||
.getTime) ; => Une classe Date. définie comme 2000-01-01 00:00:00
|
||||
|
||||
; STM
|
||||
;;;;;;;;;;;;;;;;;
|
||||
|
||||
; La mémoire logiciel transactionnelle ("Software Transactional Memory")
|
||||
; est le mécanisme que Clojure utilise pour gérer les états persistents.
|
||||
; Il y a plusieurs formes en Clojure qui utilisent cela.
|
||||
|
||||
; L'atome est la plus simple. Passez-lui une valeur initiale
|
||||
(def my-atom (atom {}))
|
||||
|
||||
; Mettez à jour un atome avec swap!.
|
||||
; swap! prend une fonction en argument et l'appelle avec la valeur
|
||||
; actuelle de l'atome comme premier argument, et les autres arguments
|
||||
; comme second argument.
|
||||
(swap! my-atom assoc :a 1) ; Définit my-atom comme le résultat de (assoc {} :a 1)
|
||||
(swap! my-atom assoc :b 2) ; Définit my-atom comme le résultat de (assoc {:a 1} :b 2)
|
||||
|
||||
; Use '@' to dereference the atom and get the value
|
||||
my-atom ;=> Atom<#...> (Renvoie l'objet Atom)
|
||||
@my-atom ; => {:a 1 :b 2}
|
||||
|
||||
; Voici un simple compteur utilisant un atome
|
||||
(def counter (atom 0))
|
||||
(defn inc-counter []
|
||||
(swap! counter inc))
|
||||
|
||||
(inc-counter)
|
||||
(inc-counter)
|
||||
(inc-counter)
|
||||
(inc-counter)
|
||||
(inc-counter)
|
||||
|
||||
@counter ; => 5
|
||||
|
||||
; Les autres formes STM sont les refs et les agents.
|
||||
; Refs: http://clojure.org/refs
|
||||
; Agents: http://clojure.org/agents
|
||||
```
|
||||
|
||||
### Lectures complémentaires
|
||||
|
||||
C'est loin d'être exhaustif, mais assez pour vous permettre de continuer.
|
||||
|
||||
Clojure.org propose de nombreux articles:
|
||||
[http://clojure.org/](http://clojure.org/)
|
||||
|
||||
Clojuredocs.org a de la documentation avec des exemples pour la
|
||||
plupart des fonctions principales :
|
||||
[http://clojuredocs.org/quickref/Clojure%20Core](http://clojuredocs.org/quickref/Clojure%20Core)
|
||||
|
||||
4Clojure est une super manière d'augmenter vos compétences en Clojure et
|
||||
en programmation fonctionnelle :
|
||||
[http://www.4clojure.com/](http://www.4clojure.com/)
|
||||
|
||||
Clojure-doc.org a pas mal d'article pour débuter :
|
||||
[http://clojure-doc.org/](http://clojure-doc.org/)
|
430
fr-fr/haskell.html.markdown
Normal file
430
fr-fr/haskell.html.markdown
Normal file
@ -0,0 +1,430 @@
|
||||
---
|
||||
language: haskell
|
||||
contributors:
|
||||
- ["Adit Bhargava", "http://adit.io"]
|
||||
translators:
|
||||
- ["David Baumgartner", "http://davidbaumgartner.ch"]
|
||||
lang: fr-fr
|
||||
---
|
||||
|
||||
Haskell a été conçu pour être un langage fonctionnel pur et maniable. Il est connu pour ses monades et son système de types, mais je n'ai cesse d'y revenir pour son élégance. Pour moi, Haskell fait de la programmation une joie.
|
||||
|
||||
```haskell
|
||||
-- Un commentaire en une ligne commence avec deux tirets.
|
||||
{- Un commentaire sur plusieurs lignes peut être contenu dans
|
||||
un bloc de cette façon.
|
||||
-}
|
||||
|
||||
----------------------------------------------------
|
||||
-- 1. Types de données primitifs et opérateurs
|
||||
----------------------------------------------------
|
||||
|
||||
-- Vous avez les nombres
|
||||
3 -- 3
|
||||
|
||||
-- Les maths sont comme vous vous y attendez
|
||||
1 + 1 -- 2
|
||||
8 - 1 -- 7
|
||||
10 * 2 -- 20
|
||||
35 / 5 -- 7.0
|
||||
|
||||
-- La division n'est pas entière par défaut
|
||||
35 / 4 -- 8.75
|
||||
|
||||
-- division entière
|
||||
35 `div` 4 -- 8
|
||||
|
||||
-- Les booléens sont primitifs
|
||||
True
|
||||
False
|
||||
|
||||
-- Opérations avec les booléens
|
||||
not True -- False
|
||||
not False -- True
|
||||
1 == 1 -- True
|
||||
1 /= 1 -- False
|
||||
1 < 10 -- True
|
||||
|
||||
-- Dans les exemples plus hauts, `not` est une fonction qui prend une valeur.
|
||||
-- Haskell n'a pas besoin de parenthèses pour appeler une fonction... tous
|
||||
-- les arguments sont juste listés après la fonction. Le schéma général est
|
||||
-- donc :
|
||||
-- func arg1 arg2 arg3...
|
||||
-- Voyez la section sur les fonctions pour savoir comment écrire les vôtres.
|
||||
|
||||
-- Caractères et chaînes de caractère
|
||||
"Ceci est une chaîne de caractère."
|
||||
'a' -- caractère
|
||||
'Vous ne pouvez pas utiliser des apostrophes pour les chaînes de caractère.' -- erreur !
|
||||
|
||||
-- Les chaînes peuvent être concaténées
|
||||
"Hello " ++ "world!" -- "Hello world!"
|
||||
|
||||
-- Une chaîne de caractère est *réellement* une liste
|
||||
"Ceci est une chaîne." !! 0 -- 'C'
|
||||
|
||||
|
||||
----------------------------------------------------
|
||||
-- Listes et tuples
|
||||
----------------------------------------------------
|
||||
|
||||
-- Tous les éléments d'une liste doit avoir le même type.
|
||||
-- les deux lignes suivantes sont semblables
|
||||
[1, 2, 3, 4, 5]
|
||||
[1..5]
|
||||
|
||||
-- Il y a aussi des listes infinies en Haskell !
|
||||
[1..] -- une liste de tous les nombres naturels
|
||||
|
||||
-- Les listes infinies fonctionnent parce que Haskell est « paresseux »:
|
||||
-- ça veut dire qu'il n'évalue que ce qui a besoin de l'être. Vous pouvez
|
||||
-- donc vous demander le 1000e élément de votre liste et il vous le donnera :
|
||||
|
||||
[1..] !! 999 -- 1000
|
||||
|
||||
-- Et là, Haskell a évalué les éléments 1 à 1000 de la liste... mais le reste
|
||||
-- de cette liste « infinie » n'existe pas encore ! En fait, Haskell ne va jamais
|
||||
-- le faire à moins qu'il ne le doive.
|
||||
|
||||
-- Adjoindre deux listes
|
||||
[1..5] ++ [6..10]
|
||||
|
||||
-- ajouter au début de la liste
|
||||
0:[1..5] -- [0, 1, 2, 3, 4, 5]
|
||||
|
||||
-- l'indice d'une liste
|
||||
[0..] !! 5 -- 5
|
||||
|
||||
-- d'autres opérations sur les listes
|
||||
head [1..5] -- 1
|
||||
tail [1..5] -- [2, 3, 4, 5]
|
||||
init [1..5] -- [1, 2, 3, 4]
|
||||
last [1..5] -- 5
|
||||
|
||||
--liste en compréhension
|
||||
[x*2 | x <- [1..5]] -- [2, 4, 6, 8, 10]
|
||||
|
||||
--avec un conditionnel
|
||||
[x*2 | x <- [1..5], x*2 > 4] -- [6, 8, 10]
|
||||
|
||||
-- Chaque élément d'un tuple peut être d'un type différent, mais un
|
||||
-- tuple a une longueur fixée.
|
||||
-- Un tuple :
|
||||
("haskell", 1)
|
||||
|
||||
-- accéder aux éléments d'un tuple
|
||||
fst ("haskell", 1) -- "haskell"
|
||||
snd ("haskell", 1) -- 1
|
||||
|
||||
----------------------------------------------------
|
||||
-- 3. Functions
|
||||
----------------------------------------------------
|
||||
-- Une simple fonction qui prend deux paramètres
|
||||
add a b = a + b
|
||||
|
||||
-- Notez que si vous utilisez ghci (l'interpréteur Haskell)
|
||||
-- vous devrez utiliser `let`. Par exemple :
|
||||
-- let add a b = a + b
|
||||
|
||||
-- Utiliser une fonction
|
||||
add 1 2 -- 3
|
||||
|
||||
-- Vous pouvez également mettre le nom de la fonction entre les
|
||||
-- deux arguments avec des accents graves :
|
||||
1 `add` 2 -- 3
|
||||
|
||||
-- Vous pouvez également définir des fonctions qui n'ont pas de
|
||||
-- lettres ! Ça vous laisse créer vos propres opérateurs ! Voilà
|
||||
-- un opérateur qui fait une division entière :
|
||||
(//) a b = a `div` b
|
||||
35 // 4 -- 8
|
||||
|
||||
-- Gardes : Une façon de gérer la valeur de vos arguments en amont
|
||||
fib x
|
||||
| x < 2 = x
|
||||
| otherwise = fib (x - 1) + fib (x - 2)
|
||||
|
||||
-- Le filtrage par motif est similaire. Là, on a donné trois
|
||||
-- définitions différentes de `fib`. Haskell appellera automatiquement
|
||||
-- la première fonction qui correspond au motif de la valeur.
|
||||
fib 1 = 1
|
||||
fib 2 = 2
|
||||
fib x = fib (x - 1) + fib (x - 2)
|
||||
|
||||
-- Filtrage par motif sur un tuple.
|
||||
foo (x, y) = (x + 1, y + 2)
|
||||
|
||||
-- Filtrage par motif sur des listes. Ici, `x` est le premier
|
||||
-- élément de la liste, et `xs` le reste. On peut écrire notre
|
||||
-- propre fonction `map` :
|
||||
myMap func [] = []
|
||||
myMap func (x:xs) = func x:(myMap func xs)
|
||||
|
||||
-- Les fonctions anonymes sont créées avec des barres obliques
|
||||
-- inverses, suivies de tous les arguments.
|
||||
myMap (\x -> x + 2) [1..5] -- [3, 4, 5, 6, 7]
|
||||
|
||||
-- Une utilisation de fold (appelée `inject` dans quelques autres
|
||||
-- langages) avec comme paramètre une fonction anonyme.
|
||||
-- `foldl1` veut dire fold left -- soit littéralement pli gauche --
|
||||
-- et utilise la première valeur de la liste comme accumulateur.
|
||||
foldl1 (\acc x -> acc + x) [1..5] -- 15
|
||||
|
||||
----------------------------------------------------
|
||||
-- 4. Plus de fonctions
|
||||
----------------------------------------------------
|
||||
|
||||
-- curryfication : si vous n'appliquez pas tous les arguments à une
|
||||
-- fonction, elle devient « curryfiée ». Ça veut dire qu'elle retourne
|
||||
-- une fonction qui prend le reste des arguments.
|
||||
|
||||
add a b = a + b
|
||||
foo = add 10 -- foo est une fonction qui prend un nombre et y ajoute 10
|
||||
foo 5 -- 15
|
||||
|
||||
-- Une autre façon de l'écrire
|
||||
foo = (+10)
|
||||
foo 5 -- 15
|
||||
|
||||
-- Composition de fonctions
|
||||
-- la fonction (.) enchaîne deux fonctions.
|
||||
-- Par exemple, on a foo qui est une fonction qui prend une valeur, y ajoute
|
||||
-- 10 et multiplie ce résultat par 5, et ensuite retourne la valeur finale.
|
||||
foo = (*5) . (+10)
|
||||
|
||||
-- (5 + 10) * 5 = 75
|
||||
foo 5 -- 75
|
||||
|
||||
-- fixation de priorité
|
||||
-- Haskell a une autre fonction appelée `$`. Elle peut changer la priorité
|
||||
-- de sorte que tout ce qu'il y a à sa gauche est calculé d'abord et ensuite
|
||||
-- appliqué à tout ce qu'il y a à droite. Vous pouvez utiliser `.` et `$`
|
||||
-- pour vous débarrasser de beaucoup de parenthèses :
|
||||
|
||||
-- avant
|
||||
(even (fib 7)) -- False
|
||||
|
||||
-- ensuite
|
||||
even . fib $ 7 -- False
|
||||
|
||||
----------------------------------------------------
|
||||
-- 5. Signature de type
|
||||
----------------------------------------------------
|
||||
|
||||
-- Haskell a un système de types très strict : par exemple, tout a un type.
|
||||
|
||||
-- Quelques types simples :
|
||||
5 :: Integer
|
||||
"hello" :: String
|
||||
True :: Bool
|
||||
|
||||
-- Les fonctions ont également des types.
|
||||
-- `not` prend un booléen et retourne un booléen.
|
||||
-- not :: Bool -> Bool
|
||||
|
||||
-- Voilà une fonction qui prend deux paramètres.
|
||||
-- add :: Integer -> Integer -> Integer
|
||||
|
||||
-- Quand vous définissez une valeur (souvenez-vous, tout est valeur en
|
||||
-- Haskell), une bonne pratique est d'écrire son type explicitement
|
||||
double :: Integer -> Integer
|
||||
double x = x * 2
|
||||
|
||||
----------------------------------------------------
|
||||
-- 6. Flux de contrôle et structures conditionnelles
|
||||
----------------------------------------------------
|
||||
|
||||
-- structure conditionnelle if
|
||||
haskell = if 1 == 1 then "awesome" else "awful" -- haskell = "awesome"
|
||||
|
||||
-- les structures if peuvent être écrites sur plusieurs lignes
|
||||
haskell = if 1 == 1
|
||||
then "awesome"
|
||||
else "awful"
|
||||
|
||||
-- les structures case : voilà comment vous pourriez analyser les arguments de
|
||||
-- ligne de commande
|
||||
case args of
|
||||
"help" -> printHelp
|
||||
"start" -> startProgram
|
||||
_ -> putStrLn "bad args"
|
||||
|
||||
|
||||
-- Haskell n'a pas de boucles parce qu'il utilise la récursion.
|
||||
-- `map` applique une fonction sur chaque élément d'une liste
|
||||
|
||||
map (*2) [1..5] -- [2, 4, 6, 8, 10]
|
||||
|
||||
-- vous pouvez créer une fonction `for` en utilisant `map`
|
||||
for array func = map func array
|
||||
|
||||
-- et l'utiliser
|
||||
for [0..5] $ \i -> show i
|
||||
|
||||
-- nous aurions pu l'écrire également ainsi
|
||||
for [0..5] show
|
||||
|
||||
-- vous pouvez utiliser foldl et foldr pour
|
||||
-- réduire une liste
|
||||
-- foldl <fonction> <valeur initiale> <liste>
|
||||
foldl (\x y -> 2*x + y) 4 [1,2,3] -- 43
|
||||
|
||||
-- C'est donc la même chose que
|
||||
(2 * (2 * (2 * 4 + 1) + 2) + 3)
|
||||
|
||||
-- foldl évalue de gauche à droite, foldr
|
||||
-- de droite à gauche
|
||||
foldr (\x y -> 2*x + y) 4 [1,2,3] -- 16
|
||||
|
||||
-- Et c'est équivalent à
|
||||
(2 * 3 + (2 * 2 + (2 * 1 + 4)))
|
||||
|
||||
----------------------------------------------------
|
||||
-- 7. Types de données
|
||||
----------------------------------------------------
|
||||
|
||||
-- Vous pouvez écrire vos propres types de données en Haskell
|
||||
|
||||
data Couleur = Rouge | Bleu | Vert
|
||||
|
||||
-- Et maintenant l'utiliser dans une fonction
|
||||
|
||||
|
||||
say :: Couleur -> String
|
||||
say Rouge = "Vous êtes Rouge !"
|
||||
say Bleu = "Vous êtes Bleu !"
|
||||
say Vert = "Vous êtes Vert !"
|
||||
|
||||
-- Vos types peuvent également avoir des paramètres
|
||||
|
||||
data Maybe a = Nothing | Just a
|
||||
|
||||
-- Tous les exemples ci-dessous sont issus du type Maybe
|
||||
Just "hello" -- of type `Maybe String`
|
||||
Just 1 -- of type `Maybe Int`
|
||||
Nothing -- of type `Maybe a` for any `a`
|
||||
|
||||
----------------------------------------------------
|
||||
-- 8. Haskell IO
|
||||
----------------------------------------------------
|
||||
|
||||
-- Tandis que l'IO ne peut pas être totalement expliqué pleinement
|
||||
-- sans que les monades ne le soient, il n'est pas difficile
|
||||
-- d'expliquer suffisamment pour commencer.
|
||||
|
||||
-- Quand un programme en Haskell est exécuté, la fonction `main`
|
||||
-- est appelée. Il doit retourner une valeur de type `IO ()`.
|
||||
-- Par exemple :
|
||||
|
||||
main :: IO ()
|
||||
main = putStrLn $ "Bonjour, le ciel ! " ++ (say Blue)
|
||||
-- putStrLn a comme type String -> IO ()
|
||||
|
||||
-- La façon la plus simple pour faire de l'IO est de faire un programme
|
||||
-- fonction de String vers String. La fonction
|
||||
-- interact :: (String -> String) -> IO ()
|
||||
-- prend un texte, applique une fonction et affiche le résultat.
|
||||
|
||||
countLines :: String -> String
|
||||
countLines = show . length . lines
|
||||
|
||||
main' = interact countLines
|
||||
|
||||
-- Vous pouvez considérer qu'une valeur de type `IO ()` représente
|
||||
-- une séquence d'actions que l'ordinateur exécute, un peu comme
|
||||
-- dans un langage impératif. On peut utiliser la structure `do`
|
||||
-- pour enchaîner des actions. Par exemple :
|
||||
|
||||
sayHello :: IO ()
|
||||
sayHello = do
|
||||
putStrLn "Quel est ton nom ?"
|
||||
name <- getLine -- prend une ligne et assigne sa valeur à `name`
|
||||
putStrLn $ "Salut, " ++ name
|
||||
|
||||
-- Exercice : écrire votre propre version d'`interact` qui ne fait
|
||||
-- que de lire une ligne d'entrée.
|
||||
|
||||
-- Le code de `sayHello` ne sera jamais exécuté, cependant. La seule
|
||||
-- action qui sera exécutée est la valeur de `main`.
|
||||
-- Pour lancer `sayHello`, commentez l'ancienne définition de `main`
|
||||
-- et remplacez-le par :
|
||||
-- main = sayHello
|
||||
|
||||
-- Essaions de mieux comprendre comment la fonction `getLine` que
|
||||
-- nous venons d'utiliser. Son type est :
|
||||
-- getLine :: IO String
|
||||
-- vous pouvez considérer le type `IO a` comme un programme que
|
||||
-- le programme va générer comme une valeur de type `a` quand
|
||||
-- il sera exécuté. On peut l'enregistrer et la réutiliser en
|
||||
-- utilisant `<-`. On peut aussi faire nos propres actions
|
||||
-- de type `IO String` :
|
||||
|
||||
action :: IO String
|
||||
action = do
|
||||
putStrLn "C'est une ligne. Heu"
|
||||
input1 <- getLine
|
||||
input2 <- getLine
|
||||
-- Le type de la structure `do` est celui de sa dernière ligne.
|
||||
-- `return` n'est pas un mot clef, mais simplement une fonction.
|
||||
return (input1 ++ "\n" ++ input2) -- return :: String -> IO String
|
||||
|
||||
-- On peut maintenant l'utiliser comme on a utilisé `getLine`
|
||||
-- tout à l'heure
|
||||
|
||||
main'' = do
|
||||
putStrLn "Je vais afficher deux lignes !"
|
||||
result <- action
|
||||
putStrLn result
|
||||
putStrLn "C'était tout !"
|
||||
|
||||
-- Le type `IO` est un exemple de « monade ». La façon dont Haskell utilise
|
||||
-- une monade pour faire de l'IO lui permet d'être purement fonctionnel. N'importe
|
||||
-- quelle fonction qui interagit avec le « monde extérieur » (c'est à dire fait de l'IO)
|
||||
-- devient marqué comme `IO` dans la signature de son type. Ça nous montre
|
||||
-- quelles fonctions sont « pures » (n'interagissent pas avec le monde extérieur
|
||||
-- ou ne changent pas d'état) et quelles fonctions ne le sont pas.
|
||||
|
||||
-- C'est une fonctionnalité très puissante, car il est facile d'exécuter
|
||||
-- des fonctions pures simultanément, et donc la concurrence en Haskell
|
||||
-- est très facile.
|
||||
|
||||
|
||||
----------------------------------------------------
|
||||
-- 9. Le REPL de Haskell
|
||||
----------------------------------------------------
|
||||
|
||||
-- Lancer le REPL en tapant `ghci`.
|
||||
-- Vous pouvez maintenant taper du code Haskell.
|
||||
-- Toutes les nouvelles valeurs peuvent être crées
|
||||
-- avec `let` :
|
||||
|
||||
let foo = 5
|
||||
|
||||
-- Vous pouvez voir le type de n'importe quelle valeur avec `:t` :
|
||||
|
||||
>:t foo
|
||||
foo :: Integer
|
||||
|
||||
-- Vous pouvez également lancer des actions de type `IO ()`
|
||||
|
||||
> sayHello
|
||||
Quel est ton nom ?
|
||||
Ami
|
||||
Salut, Ami !
|
||||
|
||||
```
|
||||
|
||||
Et Haskell ne se limite pas à ça, on trouve encore par exemple les classes de types et les monades. Il y a beaucoup de raisons qui font que coder en Haskell est si *fun*. Je vous laisse avec un dernier exemple : une implémentation de quicksort :
|
||||
|
||||
```haskell
|
||||
qsort [] = []
|
||||
qsort (p:xs) = qsort lesser ++ [p] ++ qsort greater
|
||||
where lesser = filter (< p) xs
|
||||
greater = filter (>= p) xs
|
||||
```
|
||||
|
||||
Haskell facile à installer. Téléchargez-le [ici](http://www.haskell.org/platform/).
|
||||
|
||||
Vous pouvez trouver une approche beaucoup plus douce avec les excellents
|
||||
[Learn you a Haskell](http://lyah.haskell.fr/) ou
|
||||
[Real World Haskell (en)](http://book.realworldhaskell.org/).
|
489
fr-fr/python-fr.html.markdown
Normal file
489
fr-fr/python-fr.html.markdown
Normal file
@ -0,0 +1,489 @@
|
||||
---
|
||||
language: python
|
||||
filename: learnpython-fr.py
|
||||
contributors:
|
||||
- ["Louie Dinh", "http://ldinh.ca"]
|
||||
translators:
|
||||
- ["Sylvain Zyssman", "https://github.com/sylzys"]
|
||||
- ["Nami-Doc", "https://github.com/Nami-Doc"]
|
||||
lang: fr-fr
|
||||
---
|
||||
|
||||
Python a été créé par Guido Van Rossum au début des années 90. C'est maintenant un des langages de programmation les plus populaires.
|
||||
Je suis tombé amoureux de Python de par la clarté de sa syntaxe. C'est pratiquement du pseudo-code exécutable.
|
||||
|
||||
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!
|
||||
|
||||
```python
|
||||
# Une ligne simple de commentaire commence par un dièse
|
||||
""" Les lignes de commenatires multipes peuvent être écrites
|
||||
en utilisant 3 guillemets ("), et sont souvent utilisées
|
||||
pour les commentaires
|
||||
"""
|
||||
|
||||
####################################################
|
||||
## 1. Types Primaires et Opérateurs
|
||||
####################################################
|
||||
|
||||
# Les nombres
|
||||
3 #=> 3
|
||||
|
||||
# Les calculs produisent les résultats mathématiques escomptés
|
||||
1 + 1 #=> 2
|
||||
8 - 1 #=> 7
|
||||
10 * 2 #=> 20
|
||||
35 / 5 #=> 7
|
||||
|
||||
# La division est un peu spéciale. C'est une division d'entiers, et Python arrondi le résultat par défaut automatiquement.
|
||||
5 / 2 #=> 2
|
||||
|
||||
# Pour corriger ce problème, on utilise les float.
|
||||
2.0 # Voici un float
|
||||
11.0 / 4.0 #=> 2.75 ahhh... beaucoup mieux
|
||||
|
||||
# Forcer la priorité avec les parenthèses
|
||||
(1 + 3) * 2 #=> 8
|
||||
|
||||
# Les valeurs booléenes sont de type primitif
|
||||
True
|
||||
False
|
||||
|
||||
# Pour la négation, on utilise "not"
|
||||
not True #=> False
|
||||
not False #=> True
|
||||
|
||||
# Pour l'égalité, ==
|
||||
1 == 1 #=> True
|
||||
2 == 1 #=> False
|
||||
|
||||
# L'inégalité est symbolisée par !=
|
||||
1 != 1 #=> False
|
||||
2 != 1 #=> True
|
||||
|
||||
# D'autres comparateurs
|
||||
1 < 10 #=> True
|
||||
1 > 10 #=> False
|
||||
2 <= 2 #=> True
|
||||
2 >= 2 #=> True
|
||||
|
||||
# On peut enchaîner les comparateurs !
|
||||
1 < 2 < 3 #=> True
|
||||
2 < 3 < 2 #=> False
|
||||
|
||||
# Les chaînes de caractères sont créées avec " ou '
|
||||
"C'est une chaîne."
|
||||
'C'est aussi une chaîne.'
|
||||
|
||||
# On peut aussi les "additioner" !
|
||||
"Hello " + "world!" #=> "Hello world!"
|
||||
|
||||
# Une chaîne peut être traitée comme une liste de caractères
|
||||
"C'est une chaîne"[0] #=> 'C'
|
||||
|
||||
# % peut être utilisé pour formatter des chaîne, comme ceci:
|
||||
"%s can be %s" % ("strings", "interpolated")
|
||||
|
||||
# Une autre manière de formatter les chaînes de caractères est d'utiliser la méthode 'format'
|
||||
# C'est la méthode à privilégier
|
||||
"{0} peut être {1}".format("La chaîne", "formattée")
|
||||
# On peut utiliser des mot-clés au lieu des chiffres.
|
||||
"{name} veut manger des {food}".format(name="Bob", food="lasagnes")
|
||||
|
||||
# None est un objet
|
||||
None #=> None
|
||||
|
||||
# Ne pas utiliser le symbole d'inégalité "==" pour comparer des objet à None
|
||||
# Il faut utiliser "is"
|
||||
"etc" is None #=> False
|
||||
None is None #=> True
|
||||
|
||||
# L'opérateur 'is' teste l'identité de l'objet.
|
||||
# Ce n'est pas très utilisé avec les types primitifs, mais cela peut être très utile
|
||||
# lorsque l'on utilise des objets.
|
||||
|
||||
# None, 0, et les chaînes de caractères vides valent False.
|
||||
# Toutes les autres valeurs valent True
|
||||
0 == False #=> True
|
||||
"" == False #=> True
|
||||
|
||||
|
||||
####################################################
|
||||
## 2. Variables et Collections
|
||||
####################################################
|
||||
|
||||
# Afficher du texte, c'est facile
|
||||
print "Je suis Python. Enchanté!"
|
||||
|
||||
|
||||
# Il n'y a pas besoin de déclarer les variables avant de les assigner.
|
||||
some_var = 5 # La convention veut que l'on utilise des minuscules_avec_underscores
|
||||
some_var #=> 5
|
||||
|
||||
# Accéder à une variable non assignée lève une exception
|
||||
# Voyez les structures de contrôle pour en apprendre plus sur la gestion des exceptions.
|
||||
some_other_var # Lève une exception
|
||||
|
||||
# 'if' peut être utilisé comme expression
|
||||
"yahoo!" if 3 > 2 else 2 #=> "yahoo!"
|
||||
|
||||
# Listes
|
||||
li = []
|
||||
# On peut remplir liste dès l'instanciation
|
||||
other_li = [4, 5, 6]
|
||||
|
||||
# On ajoute des éléments avec 'append'
|
||||
li.append(1) #li contient [1]
|
||||
li.append(2) #li contient [1, 2]
|
||||
li.append(4) #li contient [1, 2, 4]
|
||||
li.append(3) #li contient [1, 2, 4, 3]
|
||||
|
||||
# Et on les supprime avec 'pop'
|
||||
li.pop() #=> 3 et li contient [1, 2, 4]
|
||||
# Remettons-le dans la liste
|
||||
li.append(3) # li contient [1, 2, 4, 3] de nouveau.
|
||||
|
||||
# On accède aux éléments d'une liste comme à ceux un tableau.
|
||||
li[0] #=> 1
|
||||
# Le dernier élément
|
||||
li[-1] #=> 3
|
||||
|
||||
# Accèder aux indices hors limite lève une exception
|
||||
li[4] # Lève un 'IndexError'
|
||||
|
||||
# On peut accèder à des rangs de valeurs avec la syntaxe "slice"
|
||||
# (C'est un rang de type 'fermé/ouvert' pour les plus matheux)
|
||||
li[1:3] #=> [2, 4]
|
||||
# Sans spécifier de fin de rang, on "saute" le début de la liste
|
||||
li[2:] #=> [4, 3]
|
||||
# Sans spécifier de début de rang, on "saute" la fin de la liste
|
||||
li[:3] #=> [1, 2, 4]
|
||||
|
||||
# Retirer un élément spécifique dee la liste avec "del"
|
||||
del li[2] # li contient [1, 2, 3]
|
||||
|
||||
# On peut additionner des listes entre elles
|
||||
li + other_li #=> [1, 2, 3, 4, 5, 6] - Note: li et other_li existent toujours à part entière
|
||||
|
||||
# Concaténer des listes avec "extend()"
|
||||
li.extend(other_li) # li vaut maintenant [1, 2, 3, 4, 5, 6]
|
||||
|
||||
# Vérifier l'existence d'un élément dans une liste avec "in"
|
||||
1 in li #=> True
|
||||
|
||||
# Récupérer la longueur avec "len()"
|
||||
len(li) #=> 6
|
||||
|
||||
|
||||
# Les "tuples" sont comme des listes, mais sont immuables.
|
||||
tup = (1, 2, 3)
|
||||
tup[0] #=> 1
|
||||
tup[0] = 3 # Lève un 'TypeError'
|
||||
|
||||
# Mais vous pouvez faire tout ceci sur les tuples:
|
||||
len(tup) #=> 3
|
||||
tup + (4, 5, 6) #=> (1, 2, 3, 4, 5, 6)
|
||||
tup[:2] #=> (1, 2)
|
||||
2 in tup #=> True
|
||||
|
||||
# Vous pouvez "dé-packager" les tuples (ou les listes) dans des variables
|
||||
a, b, c = (1, 2, 3) # a vaut maintenant 1, b vaut maintenant 2 and c vaut maintenant 3
|
||||
# Sans parenthèses, un tuple est créé par défaut
|
||||
d, e, f = 4, 5, 6
|
||||
# Voyez maintenant comme il est facile d'inverser 2 valeurs
|
||||
e, d = d, e # d is now 5 and e is now 4
|
||||
|
||||
|
||||
# Dictionnaires
|
||||
empty_dict = {}
|
||||
# Un dictionnaire pré-rempli
|
||||
filled_dict = {"one": 1, "two": 2, "three": 3}
|
||||
|
||||
# Trouver des valeurs avec []
|
||||
filled_dict["one"] #=> 1
|
||||
|
||||
# Récupérer toutes les clés sous forme de liste avec "keys()"
|
||||
filled_dict.keys() #=> ["three", "two", "one"]
|
||||
# Note - l'ordre des clés du dictionnaire n'est pas garanti.
|
||||
# Vos résultats peuvent différer de ceux ci-dessus.
|
||||
|
||||
# Récupérer toutes les valeurs sous forme de liste avec "values()"
|
||||
filled_dict.values() #=> [3, 2, 1]
|
||||
# Note - Même remarque qu'au-dessus concernant l'ordre des valeurs.
|
||||
|
||||
# Vérifier l'existence d'une clé dans le dictionnaire avec "in"
|
||||
"one" in filled_dict #=> True
|
||||
1 in filled_dict #=> False
|
||||
|
||||
# Chercher une clé non existante lève une 'KeyError'
|
||||
filled_dict["four"] # KeyError
|
||||
|
||||
# Utiliser la méthode "get()" pour éviter 'KeyError'
|
||||
filled_dict.get("one") #=> 1
|
||||
filled_dict.get("four") #=> None
|
||||
# La méthode get() prend un argument par défaut quand la valeur est inexistante
|
||||
filled_dict.get("one", 4) #=> 1
|
||||
filled_dict.get("four", 4) #=> 4
|
||||
|
||||
# La méthode "setdefault()" permet d'ajouter de manière sécuris une paire clé-valeur dans le dictionnnaire
|
||||
filled_dict.setdefault("five", 5) #filled_dict["five"] vaut 5
|
||||
filled_dict.setdefault("five", 6) #filled_dict["five"] is toujours 5
|
||||
|
||||
|
||||
# Les sets stockent ... des sets
|
||||
empty_set = set()
|
||||
# On initialise un "set()" avec tout un tas de valeurs
|
||||
some_set = set([1,2,2,3,4]) # some_set vaut maintenant set([1, 2, 3, 4])
|
||||
|
||||
# Depuis Python 2.7, {} peut être utilisé pour déclarer un 'set'
|
||||
filled_set = {1, 2, 2, 3, 4} # => {1 2 3 4}
|
||||
|
||||
# Ajouter plus d'éléments au set
|
||||
filled_set.add(5) # filled_set contient maintenant {1, 2, 3, 4, 5}
|
||||
|
||||
# Intersection de sets avec &
|
||||
other_set = {3, 4, 5, 6}
|
||||
filled_set & other_set #=> {3, 4, 5}
|
||||
|
||||
# Union de sets avec |
|
||||
filled_set | other_set #=> {1, 2, 3, 4, 5, 6}
|
||||
|
||||
# Différence de sets avec -
|
||||
{1,2,3,4} - {2,3,5} #=> {1, 4}
|
||||
|
||||
# Vérifier l'existence d'une valeur dans un set avec "in"
|
||||
2 in filled_set #=> True
|
||||
10 in filled_set #=> False
|
||||
|
||||
|
||||
####################################################
|
||||
## 3. Structure de contrôle
|
||||
####################################################
|
||||
|
||||
# Initialisons une variable
|
||||
some_var = 5
|
||||
|
||||
# Voici une condition 'if'. L'indentation est significative en Python !
|
||||
# Affiche "some_var est inférieur à 10"
|
||||
if some_var > 10:
|
||||
print "some_var est supérieur à 10."
|
||||
elif some_var < 10: # La clause elif est optionnelle
|
||||
print "some_var iinférieur à 10."
|
||||
else: # La clause else également
|
||||
print "some_var vaut 10."
|
||||
|
||||
|
||||
"""
|
||||
Les boucles "for" permettent d'itérer sur les listes
|
||||
Affiche:
|
||||
chien : mammifère
|
||||
chat : mammifère
|
||||
souris : mammifère
|
||||
"""
|
||||
for animal in ["chien", "chat", "souris"]:
|
||||
# On peut utiliser % pour l'interpolation des chaînes formattées
|
||||
print "%s : mammifère" % animal
|
||||
|
||||
"""
|
||||
"range(number)" retourne une liste de nombres
|
||||
de 0 au nombre donné
|
||||
Affiche:
|
||||
0
|
||||
1
|
||||
2
|
||||
3
|
||||
"""
|
||||
for i in range(4):
|
||||
print i
|
||||
|
||||
"""
|
||||
Les boucles "while" boucle jusqu'à ce que leur condition ne soit plus vraie
|
||||
Affiche:
|
||||
0
|
||||
1
|
||||
2
|
||||
3
|
||||
"""
|
||||
x = 0
|
||||
while x < 4:
|
||||
print x
|
||||
x += 1 # Raccourci pour x = x + 1
|
||||
|
||||
# Gérer les exceptions avec un bloc try/except
|
||||
|
||||
# Fonctionne pour Python 2.6 et ultérieur:
|
||||
try:
|
||||
# Utiliser "raise" pour lever une exception
|
||||
raise IndexError("This is an index error")
|
||||
except IndexError as e:
|
||||
pass # Pass ne prend pas d'arguments. Généralement, on gère l'erreur ici.
|
||||
|
||||
|
||||
####################################################
|
||||
## 4. Fonctions
|
||||
####################################################
|
||||
|
||||
# Utiliser "def" pour créer une nouvelle fonction
|
||||
def add(x, y):
|
||||
print "x vaut %s et y vaur %s" % (x, y)
|
||||
return x + y # Renvoi de valeur avec 'return'
|
||||
|
||||
# Appeller une fonction avec des paramètres
|
||||
add(5, 6) #=> Affichet "x is 5 et y vaut 6" et renvoie 11
|
||||
|
||||
# Une autre manière d'appeller une fonction, avec les arguments
|
||||
add(y=6, x=5) # Les arguments peuvent venir dans n'importe quel ordre.
|
||||
|
||||
# On peut définir une foncion qui prend un nombre variable de paramètres
|
||||
def varargs(*args):
|
||||
return args
|
||||
|
||||
varargs(1, 2, 3) #=> (1,2,3)
|
||||
|
||||
|
||||
# On peut également définir une fonction qui prend un nombre
|
||||
# variable d'arguments
|
||||
def keyword_args(**kwargs):
|
||||
return kwargs
|
||||
|
||||
# Appelons-là et voyons ce qu'il se passe
|
||||
keyword_args(big="foot", loch="ness") #=> {"big": "foot", "loch": "ness"}
|
||||
|
||||
# On peut faire les deux à la fois si on le souhaite
|
||||
def all_the_args(*args, **kwargs):
|
||||
print args
|
||||
print kwargs
|
||||
"""
|
||||
all_the_args(1, 2, a=3, b=4) affiche:
|
||||
(1, 2)
|
||||
{"a": 3, "b": 4}
|
||||
"""
|
||||
|
||||
# En appellant les fonctions, on peut faire l'inverse des paramètres / arguments !
|
||||
# Utiliser * pour développer les paramètres, et ** pour développer les arguments
|
||||
params = (1, 2, 3, 4)
|
||||
args = {"a": 3, "b": 4}
|
||||
all_the_args(*args) # equivaut à foo(1, 2, 3, 4)
|
||||
all_the_args(**kwargs) # equivaut à foo(a=3, b=4)
|
||||
all_the_args(*args, **kwargs) # equivaut à foo(1, 2, 3, 4, a=3, b=4)
|
||||
|
||||
# Python a des fonctions de première classe
|
||||
def create_adder(x):
|
||||
def adder(y):
|
||||
return x + y
|
||||
return adder
|
||||
|
||||
add_10 = create_adder(10)
|
||||
add_10(3) #=> 13
|
||||
|
||||
# Mais également des fonctions anonymes
|
||||
(lambda x: x > 2)(3) #=> True
|
||||
|
||||
# On trouve aussi des fonctions intégrées plus évoluées
|
||||
map(add_10, [1,2,3]) #=> [11, 12, 13]
|
||||
filter(lambda x: x > 5, [3, 4, 5, 6, 7]) #=> [6, 7]
|
||||
|
||||
# On peut utiliser la syntaxe des liste pour construire les "maps" et les "filters"
|
||||
[add_10(i) for i in [1, 2, 3]] #=> [11, 12, 13]
|
||||
[x for x in [3, 4, 5, 6, 7] if x > 5] #=> [6, 7]
|
||||
|
||||
####################################################
|
||||
## 5. Classes
|
||||
####################################################
|
||||
|
||||
# Une classe est un objet
|
||||
class Human(object):
|
||||
|
||||
# Un attribut de classe. Il est partagé par toutes les instances de cette classe.
|
||||
species = "H. sapiens"
|
||||
|
||||
# Initialiseur basique
|
||||
def __init__(self, name):
|
||||
# Assigne le paramètre à l'attribut de l'instance de classe.
|
||||
self.name = name
|
||||
|
||||
# Une méthode de l'instance. Toutes les méthodes prennent "self" comme 1er paramètre.
|
||||
def say(self, msg):
|
||||
return "%s: %s" % (self.name, msg)
|
||||
|
||||
# Une méthode de classe est partagée par toutes les instances.
|
||||
# On les appelle avec le nom de la classe en premier paramètre
|
||||
@classmethod
|
||||
def get_species(cls):
|
||||
return cls.species
|
||||
|
||||
# Une méthode statique est appellée sans référence à une classe ou à une instance
|
||||
@staticmethod
|
||||
def grunt():
|
||||
return "*grunt*"
|
||||
|
||||
|
||||
# Instancier une classe
|
||||
i = Human(name="Ian")
|
||||
print i.say("hi") # Affiche "Ian: hi"
|
||||
|
||||
j = Human("Joel")
|
||||
print j.say("hello") #Affiche "Joel: hello"
|
||||
|
||||
# Appeller notre méthode de classe
|
||||
i.get_species() #=> "H. sapiens"
|
||||
|
||||
# Changer les attributs partagés
|
||||
Human.species = "H. neanderthalensis"
|
||||
i.get_species() #=> "H. neanderthalensis"
|
||||
j.get_species() #=> "H. neanderthalensis"
|
||||
|
||||
# Appeller la méthode statique
|
||||
Human.grunt() #=> "*grunt*"
|
||||
|
||||
|
||||
####################################################
|
||||
## 6. Modules
|
||||
####################################################
|
||||
|
||||
# On peut importer des modules
|
||||
import math
|
||||
print math.sqrt(16) #=> 4
|
||||
|
||||
# Et récupérer des fonctions spécifiques d'un module
|
||||
from math import ceil, floor
|
||||
print ceil(3.7) #=> 4.0
|
||||
print floor(3.7) #=> 3.0
|
||||
|
||||
# Récuperer toutes les fonctions d'un module
|
||||
# Attention, ce n'est pas recommandé.
|
||||
from math import *
|
||||
|
||||
# On peut raccourcir le nom d'un module
|
||||
import math as m
|
||||
math.sqrt(16) == m.sqrt(16) #=> True
|
||||
|
||||
# Les modules Python sont juste des fichiers Python ordinaires.
|
||||
# On peut écrire ses propres modules et les importer.
|
||||
# Le nom du module doit être le même que le nom du fichier.
|
||||
|
||||
# On peut trouver quelle fonction et attributs déterminent un module
|
||||
import math
|
||||
dir(math)
|
||||
|
||||
|
||||
```
|
||||
|
||||
## Prêt à aller plus loin?
|
||||
|
||||
### En ligne gratuitement
|
||||
|
||||
* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/)
|
||||
* [Dive Into Python](http://www.diveintopython.net/)
|
||||
* [The Official Docs](http://docs.python.org/2.6/)
|
||||
* [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/)
|
||||
* [Python Module of the Week](http://pymotw.com/2/)
|
||||
|
||||
### Format papier
|
||||
|
||||
* [Programming Python](http://www.amazon.com/gp/product/0596158106/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596158106&linkCode=as2&tag=homebits04-20)
|
||||
* [Dive Into Python](http://www.amazon.com/gp/product/1441413022/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1441413022&linkCode=as2&tag=homebits04-20)
|
||||
* [Python Essential Reference](http://www.amazon.com/gp/product/0672329786/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0672329786&linkCode=as2&tag=homebits04-20)
|
||||
|
@ -2,9 +2,8 @@
|
||||
category: tool
|
||||
tool: git
|
||||
contributors:
|
||||
- ["Jake Prather", "http:#github.com/JakeHP"]
|
||||
- ["Jake Prather", "http://github.com/JakeHP"]
|
||||
filename: LearnGit.txt
|
||||
|
||||
---
|
||||
|
||||
Git is a distributed version control and source code management system.
|
||||
@ -41,7 +40,7 @@ Version control is a system that records changes to a file, or set of files, ove
|
||||
|
||||
### Repository
|
||||
|
||||
A set of files, directories, historical records, commits, and heads. Imagine it as a source code datastructure,
|
||||
A set of files, directories, historical records, commits, and heads. Imagine it as a source code data structure,
|
||||
with the attribute that each source code "element" gives you access to its revision history, among other things.
|
||||
|
||||
A git repository is comprised of the .git directory & working tree.
|
||||
|
@ -46,7 +46,7 @@ func main() {
|
||||
}
|
||||
|
||||
// Functions have parameters in parentheses.
|
||||
// If there are no parameters, empty parens are still required.
|
||||
// If there are no parameters, empty parentheses are still required.
|
||||
func beyondHello() {
|
||||
var x int // Variable declaration. Variables must be declared before use.
|
||||
x = 3 // Variable assignment.
|
||||
@ -71,7 +71,7 @@ func learnTypes() {
|
||||
can include line breaks.` // same string type
|
||||
|
||||
// non-ASCII literal. Go source is UTF-8.
|
||||
g := 'Σ' // rune type, an alias for uint32, holds a UTF-8 code point
|
||||
g := 'Σ' // rune type, an alias for uint32, holds a unicode code point
|
||||
|
||||
f := 3.14195 // float64, an IEEE-754 64-bit floating point number
|
||||
c := 3 + 4i // complex128, represented internally with two float64s
|
||||
@ -251,7 +251,7 @@ func learnConcurrency() {
|
||||
fmt.Println(<-c, <-c, <-c) // channel on right, <- is "receive" operator.
|
||||
|
||||
cs := make(chan string) // another channel, this one handles strings.
|
||||
cc := make(chan chan string) // a channel of channels.
|
||||
cc := make(chan chan string) // a channel of string channels.
|
||||
go func() { c <- 84 }() // start a new goroutine just to send a value
|
||||
go func() { cs <- "wordy" }() // again, for cs this time
|
||||
// Select has syntax like a switch statement but each case involves
|
||||
@ -259,7 +259,7 @@ func learnConcurrency() {
|
||||
// that are ready to communicate.
|
||||
select {
|
||||
case i := <-c: // the value received can be assigned to a variable
|
||||
fmt.Println("it's a", i)
|
||||
fmt.Printf("it's a %T", i)
|
||||
case <-cs: // or the value received can be discarded
|
||||
fmt.Println("it's a string")
|
||||
case <-cc: // empty channel, not ready for communication.
|
||||
@ -294,8 +294,9 @@ There you can follow the tutorial, play interactively, and read lots.
|
||||
The language definition itself is highly recommended. It's easy to read
|
||||
and amazingly short (as language definitions go these days.)
|
||||
|
||||
On the reading list for students of Go is the source code to the standard
|
||||
library. Comprehensively documented, it demonstrates the best of readable
|
||||
and understandable Go, Go style, and Go idioms. Click on a function name
|
||||
in the documentation and the source code comes up!
|
||||
On the reading list for students of Go is the [source code to the standard
|
||||
library](http://golang.org/src/pkg/). Comprehensively documented, it
|
||||
demonstrates the best of readable and understandable Go, Go style, and Go
|
||||
idioms. Or you can click on a function name in [the
|
||||
documentation](http://golang.org/pkg/) and the source code comes up!
|
||||
|
||||
|
@ -8,7 +8,7 @@ filename: learngroovy.groovy
|
||||
|
||||
Groovy - A dynamic language for the Java platform [Read more here.](http://groovy.codehaus.org)
|
||||
|
||||
```cpp
|
||||
```groovy
|
||||
|
||||
/*
|
||||
Set yourself up:
|
||||
@ -51,28 +51,56 @@ println x
|
||||
/*
|
||||
Collections and maps
|
||||
*/
|
||||
|
||||
//Creating an empty list
|
||||
def technologies = []
|
||||
|
||||
//Add an element to the list
|
||||
technologies << "Groovy"
|
||||
/*** Adding a elements to the list ***/
|
||||
|
||||
// As with Java
|
||||
technologies.add("Grails")
|
||||
|
||||
// Left shift adds, and returns the list
|
||||
technologies << "Groovy"
|
||||
|
||||
// Add multiple elements
|
||||
technologies.addAll(["Gradle","Griffon"])
|
||||
|
||||
//Remove an element from the list
|
||||
/*** Removing elements from the list ***/
|
||||
|
||||
// As with Java
|
||||
technologies.remove("Griffon")
|
||||
|
||||
//Iterate over elements of a list
|
||||
// Subtraction works also
|
||||
technologies = technologies - 'Grails'
|
||||
|
||||
/*** Iterating Lists ***/
|
||||
|
||||
// Iterate over elements of a list
|
||||
technologies.each { println "Technology: $it"}
|
||||
technologies.eachWithIndex { it, i -> println "$i: $it"}
|
||||
|
||||
/*** Checking List contents ***/
|
||||
|
||||
//Evaluate if a list contains element(s) (boolean)
|
||||
technologies.contains('Groovy')
|
||||
contained = technologies.contains( 'Groovy' )
|
||||
|
||||
// Or
|
||||
contained = 'Groovy' in technologies
|
||||
|
||||
// Check for multiple contents
|
||||
technologies.containsAll(['Groovy','Grails'])
|
||||
|
||||
//Sort a list
|
||||
/*** Sorting Lists ***/
|
||||
|
||||
// Sort a list (mutates original list)
|
||||
technologies.sort()
|
||||
|
||||
// To sort without mutating original, you can do:
|
||||
sortedTechnologies = technologies.sort( false )
|
||||
|
||||
/*** Manipulating Lists ***/
|
||||
|
||||
//Replace all elements in the list
|
||||
Collections.replaceAll(technologies, 'Gradle', 'gradle')
|
||||
|
||||
|
@ -11,7 +11,7 @@ makes coding a real joy for me.
|
||||
```haskell
|
||||
-- Single line comments start with two dashes.
|
||||
{- Multiline comments can be enclosed
|
||||
en a block like this.
|
||||
in a block like this.
|
||||
-}
|
||||
|
||||
----------------------------------------------------
|
||||
@ -329,7 +329,7 @@ main' = interact countLines
|
||||
sayHello :: IO ()
|
||||
sayHello = do
|
||||
putStrLn "What is your name?"
|
||||
name <- getLine -- this gets a line and gives it the name "input"
|
||||
name <- getLine -- this gets a line and gives it the name "name"
|
||||
putStrLn $ "Hello, " ++ name
|
||||
|
||||
-- Exercise: write your own version of `interact` that only reads
|
||||
|
@ -11,45 +11,67 @@ Haxe author). Note that this guide is for Haxe version 3. Some of the guide
|
||||
may be applicable to older versions, but it is recommended to use other
|
||||
references.
|
||||
|
||||
```haxe
|
||||
```csharp
|
||||
/*
|
||||
Welcome to Learn Haxe 3 in 15 minutes. http://www.haxe.org
|
||||
This is an executable tutorial. You can compile and run it using the haxe
|
||||
compiler, while in the same directory as LearnHaxe.hx:
|
||||
haxe -main LearnHaxe3 -x out
|
||||
$> haxe -main LearnHaxe3 -x out
|
||||
|
||||
Look for the slash-star marks surrounding these paragraphs. We are inside
|
||||
a "Multiline comment". We can leave some notes here that will get ignored
|
||||
by the compiler.
|
||||
|
||||
Multiline comments are also used to generate javadoc-style documentation for
|
||||
haxedoc. They will be used for haxedoc if they immediately precede a class,
|
||||
class function, or class variable.
|
||||
|
||||
*/
|
||||
|
||||
// Let's start with comments... this is a single line comment
|
||||
// Double slashes like this will give a single-line comment
|
||||
|
||||
|
||||
/*
|
||||
And this is multiline. Multiline comments are also used to generate
|
||||
javadoc-style documentation for haxedoc. They will be used if they precede
|
||||
a class, class function, or class variable.
|
||||
*/
|
||||
|
||||
/*
|
||||
A package declaration isn't necessary, but it's useful if you want to
|
||||
organize your code into modules later on. Also worth mentioning, all
|
||||
expressions in Haxe must end in a semicolon:
|
||||
This is your first actual haxe code coming up, it's declaring an empty
|
||||
package. A package isn't necessary, but it's useful if you want to create a
|
||||
namespace for your code (e.g. org.module.ClassName).
|
||||
*/
|
||||
package; // empty package, no namespace.
|
||||
|
||||
/*
|
||||
Packages define modules for your code. Each module (e.g. org.module) must
|
||||
be lower case, and should exist as a folder structure containing the class.
|
||||
Class (and type) names must be capitalized. E.g, the class "org.module.Foo"
|
||||
should have the folder structure org/module/Foo.hx, as accessible from the
|
||||
compiler's working directory or class path.
|
||||
|
||||
// if you import code from other files, it must be declared before the rest of
|
||||
// the code.
|
||||
If you import code from other files, it must be declared before the rest of
|
||||
the code. Haxe provides a lot of common default classes to get you started:
|
||||
*/
|
||||
import haxe.ds.ArraySort;
|
||||
|
||||
// you can import many classes/modules at once with "*"
|
||||
import haxe.ds.*;
|
||||
|
||||
// you can also import classes in a special way, enabling them to extend the
|
||||
// functionality of other classes. More on this later.
|
||||
/*
|
||||
You can also import classes in a special way, enabling them to extend the
|
||||
functionality of other classes like a "mixin". More on 'using' later.
|
||||
*/
|
||||
using StringTools;
|
||||
|
||||
// Haxe files typically define classes, although they can also define other
|
||||
// types of code... more on that later.
|
||||
/*
|
||||
Typedefs are like variables... for types. They must be declared before any
|
||||
code. More on this later.
|
||||
*/
|
||||
typedef FooString = String;
|
||||
|
||||
// Typedefs can also reference "structural" types, more on that later as well.
|
||||
typedef FooObject = { foo: String };
|
||||
|
||||
/*
|
||||
Here's the class definition. It's the main class for the file, since it has
|
||||
the same name (LearnHaxe3).
|
||||
*/
|
||||
class LearnHaxe3{
|
||||
/*
|
||||
If you want certain code to run automatically, you need to put it in
|
||||
@ -58,6 +80,7 @@ class LearnHaxe3{
|
||||
arguments above.
|
||||
*/
|
||||
static function main(){
|
||||
|
||||
/*
|
||||
Trace is the default method of printing haxe expressions to the
|
||||
screen. Different targets will have different methods of
|
||||
@ -67,8 +90,6 @@ class LearnHaxe3{
|
||||
Finally, It's possible to prevent traces from showing by using the
|
||||
"--no-traces" argument on the compiler.
|
||||
*/
|
||||
|
||||
|
||||
trace("Hello World, with trace()!");
|
||||
|
||||
/*
|
||||
@ -76,16 +97,11 @@ class LearnHaxe3{
|
||||
a representation of the expression as best it can. You can also
|
||||
concatenate strings with the "+" operator:
|
||||
*/
|
||||
trace(
|
||||
" Integer: " + 10 +
|
||||
" Float: " + 3.14 +
|
||||
" Boolean: " + true
|
||||
);
|
||||
|
||||
trace( " Integer: " + 10 + " Float: " + 3.14 + " Boolean: " + true);
|
||||
|
||||
/*
|
||||
Remember what I said about expressions needing semicolons? You
|
||||
can put more than one expression on a line if you want.
|
||||
In Haxe, it's required to separate expressions in the same block with
|
||||
semicolons. But, you can put two expressions on one line:
|
||||
*/
|
||||
trace('two expressions..'); trace('one line');
|
||||
|
||||
@ -99,7 +115,6 @@ class LearnHaxe3{
|
||||
You can save values and references to data structures using the
|
||||
"var" keyword:
|
||||
*/
|
||||
|
||||
var an_integer:Int = 1;
|
||||
trace(an_integer + " is the value for an_integer");
|
||||
|
||||
@ -111,7 +126,6 @@ class LearnHaxe3{
|
||||
the haxe compiler is inferring that the type of another_integer
|
||||
should be "Int".
|
||||
*/
|
||||
|
||||
var another_integer = 2;
|
||||
trace(another_integer + " is the value for another_integer");
|
||||
|
||||
@ -137,8 +151,14 @@ class LearnHaxe3{
|
||||
var a_string = "some" + 'string'; // strings can have double or single quotes
|
||||
trace(a_string + " is the value for a_string");
|
||||
|
||||
/*
|
||||
Strings can be "interpolated" by inserting variables into specific
|
||||
positions. The string must be single quoted, and the variable must
|
||||
be preceded with "$". Expressions can be enclosed in ${...}.
|
||||
*/
|
||||
var x = 1;
|
||||
var an_interpolated_string = 'the value of x is $x';
|
||||
var another_interpolated_string = 'the value of x + 1 is ${x + 1}';
|
||||
|
||||
/*
|
||||
Strings are immutable, instance methods will return a copy of
|
||||
@ -148,6 +168,12 @@ class LearnHaxe3{
|
||||
var a_sub_string = a_string.substr(0,4);
|
||||
trace(a_sub_string + " is the value for a_sub_string");
|
||||
|
||||
/*
|
||||
Regexes are also supported, but there's not enough space to go into
|
||||
much detail.
|
||||
*/
|
||||
trace((~/foobar/.match('foo')) + " is the value for (~/foobar/.match('foo')))");
|
||||
|
||||
/*
|
||||
Arrays are zero-indexed, dynamic, and mutable. Missing values are
|
||||
defined as null.
|
||||
@ -191,7 +217,7 @@ class LearnHaxe3{
|
||||
trace(m3 + " is the value for m3");
|
||||
|
||||
/*
|
||||
Haxe has many more common datastructures in the haxe.ds module, such as
|
||||
Haxe has some more common datastructures in the haxe.ds module, such as
|
||||
List, Stack, and BalancedTree
|
||||
*/
|
||||
|
||||
@ -199,7 +225,6 @@ class LearnHaxe3{
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Operators
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
trace("***OPERATORS***");
|
||||
|
||||
// basic arithmetic
|
||||
@ -218,7 +243,7 @@ class LearnHaxe3{
|
||||
trace((3 >= 2) + " is the value for 3 >= 2");
|
||||
trace((3 <= 2) + " is the value for 3 <= 2");
|
||||
|
||||
//bitwise operators
|
||||
// standard bitwise operators
|
||||
/*
|
||||
~ Unary bitwise complement
|
||||
<< Signed left shift
|
||||
@ -252,6 +277,27 @@ class LearnHaxe3{
|
||||
trace("also not printed.");
|
||||
}
|
||||
|
||||
// there is also a "ternary" if:
|
||||
(j == 10) ? trace("equals 10") : trace("not equals 10");
|
||||
|
||||
/*
|
||||
Finally, there is another form of control structures that operates
|
||||
at compile time: conditional compilation.
|
||||
*/
|
||||
#if neko
|
||||
trace('hello from neko');
|
||||
#elseif js
|
||||
trace('hello from js');
|
||||
#else
|
||||
trace('hello from another platform!');
|
||||
#end
|
||||
/*
|
||||
The compiled code will change depending on the platform target.
|
||||
Since we're compiling for neko (-x or -neko), we only get the neko
|
||||
greeting.
|
||||
*/
|
||||
|
||||
|
||||
trace("Looping and Iteration");
|
||||
|
||||
// while loop
|
||||
@ -310,13 +356,14 @@ class LearnHaxe3{
|
||||
generalized algebraic data types in enums (more on enums later).
|
||||
Here's some basic value examples for now:
|
||||
*/
|
||||
var my_dog_name = 'fido';
|
||||
var favorite_thing = '';
|
||||
var my_dog_name = "fido";
|
||||
var favorite_thing = "";
|
||||
switch(my_dog_name){
|
||||
case "fido" : favorite_thing = 'bone';
|
||||
case "rex" : favorite_thing = 'shoe';
|
||||
case "spot" : favorite_thing = 'tennis ball';
|
||||
case _ : favorite_thing = 'some unknown treat';
|
||||
case "fido" : favorite_thing = "bone";
|
||||
case "rex" : favorite_thing = "shoe";
|
||||
case "spot" : favorite_thing = "tennis ball";
|
||||
default : favorite_thing = "some unknown treat";
|
||||
// case _ : "some unknown treat"; // same as default
|
||||
}
|
||||
// The "_" case above is a "wildcard" value
|
||||
// that will match anything.
|
||||
@ -345,10 +392,10 @@ class LearnHaxe3{
|
||||
trace("K equals ", k); // outputs 10
|
||||
|
||||
var other_favorite_thing = switch(my_dog_name) {
|
||||
case "fido" : 'teddy';
|
||||
case "rex" : 'stick';
|
||||
case "spot" : 'football';
|
||||
case _ : 'some unknown treat';
|
||||
case "fido" : "teddy";
|
||||
case "rex" : "stick";
|
||||
case "spot" : "football";
|
||||
default : "some unknown treat";
|
||||
}
|
||||
|
||||
trace("My dog's name is" + my_dog_name
|
||||
@ -358,6 +405,7 @@ class LearnHaxe3{
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Converting Value Types
|
||||
//////////////////////////////////////////////////////////////////
|
||||
trace("***CONVERTING VALUE TYPES***");
|
||||
|
||||
// You can convert strings to ints fairly easily.
|
||||
|
||||
@ -372,33 +420,93 @@ class LearnHaxe3{
|
||||
true + ""; // returns "true";
|
||||
// See documentation for parsing in Std for more details.
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Dealing with Types
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
/*
|
||||
|
||||
As mentioned before, Haxe is a statically typed language. All in
|
||||
all, static typing is a wonderful thing. It enables
|
||||
precise autocompletions, and can be used to thoroughly check the
|
||||
correctness of a program. Plus, the Haxe compiler is super fast.
|
||||
|
||||
*HOWEVER*, there are times when you just wish the compiler would let
|
||||
something slide, and not throw a type error in a given case.
|
||||
|
||||
To do this, Haxe has two separate keywords. The first is the
|
||||
"Dynamic" type:
|
||||
*/
|
||||
var dyn: Dynamic = "any type of variable, such as this string";
|
||||
|
||||
/*
|
||||
All that you know for certain with a Dynamic variable is that the
|
||||
compiler will no longer worry about what type it is. It is like a
|
||||
wildcard variable: You can pass it instead of any variable type,
|
||||
and you can assign any variable type you want.
|
||||
|
||||
The other more extreme option is the "untyped" keyword:
|
||||
*/
|
||||
|
||||
untyped {
|
||||
var x:Int = 'foo'; // this can't be right!
|
||||
var y:String = 4; // madness!
|
||||
}
|
||||
|
||||
/*
|
||||
The untyped keyword operates on entire *blocks* of code, skipping
|
||||
any type checks that might be otherwise required. This keyword should
|
||||
be used very sparingly, such as in limited conditionally-compiled
|
||||
situations where type checking is a hinderance.
|
||||
|
||||
In general, skipping type checks is *not* recommended. Use the
|
||||
enum, inheritance, or structural type models in order to help ensure
|
||||
the correctness of your program. Only when you're certain that none
|
||||
of the type models work should you resort to "Dynamic" or "untyped".
|
||||
*/
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Basic Object Oriented Programming
|
||||
//////////////////////////////////////////////////////////////////
|
||||
trace("***BASIC OBJECT ORIENTED PROGRAMMING***");
|
||||
|
||||
|
||||
// create an instance of FooClass. The classes for this are at the
|
||||
// end of the file.
|
||||
var instance = new FooClass(3);
|
||||
/*
|
||||
Create an instance of FooClass. The classes for this are at the
|
||||
end of the file.
|
||||
*/
|
||||
var foo_instance = new FooClass(3);
|
||||
|
||||
// read the public variable normally
|
||||
trace(instance.public_any + " is the value for instance.public_any");
|
||||
trace(foo_instance.public_any + " is the value for foo_instance.public_any");
|
||||
|
||||
// we can read this variable
|
||||
trace(instance.public_read + " is the value for instance.public_read");
|
||||
trace(foo_instance.public_read + " is the value for foo_instance.public_read");
|
||||
// but not write it
|
||||
// instance.public_write = 4; // this will throw an error if uncommented:
|
||||
// trace(instance.public_write); // as will this.
|
||||
// foo_instance.public_write = 4; // this will throw an error if uncommented:
|
||||
// trace(foo_instance.public_write); // as will this.
|
||||
|
||||
trace(instance + " is the value for instance"); // calls the toString method
|
||||
trace(instance.toString() + " is the value for instance.toString()"); // same thing
|
||||
trace(foo_instance + " is the value for foo_instance"); // calls the toString method
|
||||
trace(foo_instance.toString() + " is the value for foo_instance.toString()"); // same thing
|
||||
|
||||
|
||||
// instance has the "FooClass" type, while acceptBaseFoo has the
|
||||
// BaseFooClass type. However, since FooClass extends BaseFooClass,
|
||||
// it is accepted.
|
||||
BaseFooClass.acceptBaseFoo(instance);
|
||||
/*
|
||||
The foo_instance has the "FooClass" type, while acceptBarInstance
|
||||
has the BarClass type. However, since FooClass extends BarClass, it
|
||||
is accepted.
|
||||
*/
|
||||
BarClass.acceptBarInstance(foo_instance);
|
||||
|
||||
/*
|
||||
The classes below have some more advanced examples, the "example()"
|
||||
method will just run them here.
|
||||
*/
|
||||
SimpleEnumTest.example();
|
||||
ComplexEnumTest.example();
|
||||
TypedefsAndStructuralTypes.example();
|
||||
UsingExample.example();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -406,7 +514,7 @@ class LearnHaxe3{
|
||||
/*
|
||||
This is the "child class" of the main LearnHaxe3 Class
|
||||
*/
|
||||
class FooClass extends BaseFooClass implements BaseFooInterface{
|
||||
class FooClass extends BarClass implements BarInterface{
|
||||
public var public_any:Int; // public variables are accessible anywhere
|
||||
public var public_read (default,null): Int; // use this style to only enable public read
|
||||
public var public_write (null, default): Int; // or public write
|
||||
@ -418,7 +526,7 @@ class FooClass extends BaseFooClass implements BaseFooInterface{
|
||||
|
||||
// a public constructor
|
||||
public function new(arg:Int){
|
||||
super(); // call the constructor of the parent object, since we extended BaseFooClass
|
||||
super(); // call the constructor of the parent object, since we extended BarClass
|
||||
|
||||
this.public_any= 0;
|
||||
this._private = arg;
|
||||
@ -442,7 +550,7 @@ class FooClass extends BaseFooClass implements BaseFooInterface{
|
||||
}
|
||||
|
||||
// this class needs to have this function defined, since it implements
|
||||
// the BaseFooInterface interface.
|
||||
// the BarInterface interface.
|
||||
public function baseFunction(x: Int) : String{
|
||||
// convert the int to string automatically
|
||||
return x + " was passed into baseFunction!";
|
||||
@ -452,21 +560,217 @@ class FooClass extends BaseFooClass implements BaseFooInterface{
|
||||
/*
|
||||
A simple class to extend
|
||||
*/
|
||||
class BaseFooClass {
|
||||
class BarClass {
|
||||
var base_variable:Int;
|
||||
public function new(){
|
||||
base_variable = 4;
|
||||
}
|
||||
public static function acceptBaseFoo(b:BaseFooClass){
|
||||
public static function acceptBarInstance(b:BarClass){
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
A simple interface to implement
|
||||
*/
|
||||
interface BaseFooInterface{
|
||||
interface BarInterface{
|
||||
public function baseFunction(x:Int):String;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Enums and Switch Statements
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
/*
|
||||
Enums in Haxe are very powerful. In their simplest form, enums
|
||||
are a type with a limited number of states:
|
||||
*/
|
||||
|
||||
enum SimpleEnum {
|
||||
Foo;
|
||||
Bar;
|
||||
Baz;
|
||||
}
|
||||
|
||||
// Here's a class that uses it:
|
||||
|
||||
class SimpleEnumTest{
|
||||
public static function example(){
|
||||
var e_explicit:SimpleEnum = SimpleEnum.Foo; // you can specify the "full" name
|
||||
var e = Foo; // but inference will work as well.
|
||||
switch(e){
|
||||
case Foo: trace("e was Foo");
|
||||
case Bar: trace("e was Bar");
|
||||
case Baz: trace("e was Baz"); // comment this line to throw an error.
|
||||
}
|
||||
|
||||
/*
|
||||
This doesn't seem so different from simple value switches on strings.
|
||||
However, if we don't include *all* of the states, the compiler will
|
||||
complain. You can try it by commenting out a line above.
|
||||
|
||||
You can also specify a default for enum switches as well:
|
||||
*/
|
||||
switch(e){
|
||||
case Foo: trace("e was Foo again");
|
||||
default : trace("default works here too");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Enums go much further than simple states, we can also enumerate
|
||||
*constructors*, but we'll need a more complex enum example
|
||||
*/
|
||||
enum ComplexEnum{
|
||||
IntEnum(i:Int);
|
||||
MultiEnum(i:Int, j:String, k:Float);
|
||||
SimpleEnumEnum(s:SimpleEnum);
|
||||
ComplexEnumEnum(c:ComplexEnum);
|
||||
}
|
||||
// Note: The enum above can include *other* enums as well, including itself!
|
||||
|
||||
class ComplexEnumTest{
|
||||
public static function example(){
|
||||
var e1:ComplexEnum = IntEnum(4); // specifying the enum parameter
|
||||
/*
|
||||
Now we can switch on the enum, as well as extract any parameters
|
||||
it might of had.
|
||||
*/
|
||||
switch(e1){
|
||||
case IntEnum(x) : trace('$x was the parameter passed to e1');
|
||||
default: trace("Shouldn't be printed");
|
||||
}
|
||||
|
||||
// another parameter here that is itself an enum... an enum enum?
|
||||
var e2 = SimpleEnumEnum(Foo);
|
||||
switch(e2){
|
||||
case SimpleEnumEnum(s): trace('$s was the parameter passed to e2');
|
||||
default: trace("Shouldn't be printed");
|
||||
}
|
||||
|
||||
// enums all the way down
|
||||
var e3 = ComplexEnumEnum(ComplexEnumEnum(MultiEnum(4, 'hi', 4.3)));
|
||||
switch(e3){
|
||||
// You can look for certain nested enums by specifying them explicitly:
|
||||
case ComplexEnumEnum(ComplexEnumEnum(MultiEnum(i,j,k))) : {
|
||||
trace('$i, $j, and $k were passed into this nested monster');
|
||||
}
|
||||
default: trace("Shouldn't be printed");
|
||||
}
|
||||
/*
|
||||
Check out "generalized algebraic data types" (GADT) for more details
|
||||
on why these are so great.
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
class TypedefsAndStructuralTypes {
|
||||
public static function example(){
|
||||
/*
|
||||
Here we're going to use typedef types, instead of base types.
|
||||
At the top we've declared the type "FooString" to mean a "String" type.
|
||||
*/
|
||||
var t1:FooString = "some string";
|
||||
|
||||
/*
|
||||
We can use typedefs for "structural types" as well. These types are
|
||||
defined by their field structure, not by class inheritance. Here's
|
||||
an anonymous object with a String field named "foo":
|
||||
*/
|
||||
|
||||
var anon_obj = { foo: 'hi' };
|
||||
|
||||
/*
|
||||
The anon_obj variable doesn't have a type declared, and is an
|
||||
anonymous object according to the compiler. However, remember back at
|
||||
the top where we declared the FooObj typedef? Since anon_obj matches
|
||||
that structure, we can use it anywhere that a "FooObject" type is
|
||||
expected.
|
||||
*/
|
||||
|
||||
var f = function(fo:FooObject){
|
||||
trace('$fo was passed in to this function');
|
||||
}
|
||||
f(anon_obj); // call the FooObject signature function with anon_obj.
|
||||
|
||||
/*
|
||||
Note that typedefs can have optional fields as well, marked with "?"
|
||||
|
||||
typedef OptionalFooObj = {
|
||||
?optionalString: String,
|
||||
requiredInt: Int
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
Typedefs work well with conditional compilation. For instance,
|
||||
we could have included this at the top of the file:
|
||||
|
||||
#if( js )
|
||||
typedef Surface = js.html.CanvasRenderingContext2D;
|
||||
#elseif( nme )
|
||||
typedef Surface = nme.display.Graphics;
|
||||
#elseif( !flash9 )
|
||||
typedef Surface = flash8.MovieClip;
|
||||
#elseif( java )
|
||||
typedef Surface = java.awt.geom.GeneralPath;
|
||||
#end
|
||||
|
||||
That would give us a single "Surface" type to work with across
|
||||
all of those platforms.
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
class UsingExample {
|
||||
public static function example() {
|
||||
|
||||
/*
|
||||
The "using" import keyword is a special type of class import that
|
||||
alters the behavior of any static methods in the class.
|
||||
|
||||
In this file, we've applied "using" to "StringTools", which contains
|
||||
a number of static methods for dealing with String types.
|
||||
*/
|
||||
trace(StringTools.endsWith("foobar", "bar") + " should be true!");
|
||||
|
||||
/*
|
||||
With a "using" import, the first argument type is extended with the
|
||||
method. What does that mean? Well, since "endsWith" has a first
|
||||
argument type of "String", that means all String types now have the
|
||||
"endsWith" method:
|
||||
*/
|
||||
trace("foobar".endsWith("bar") + " should be true!");
|
||||
|
||||
/*
|
||||
This technique enables a good deal of expression for certain types,
|
||||
while limiting the scope of modifications to a single file.
|
||||
|
||||
Note that the String instance is *not* modified in the run time.
|
||||
The newly attached method is not really part of the attached
|
||||
instance, and the compiler still generates code equivalent to a
|
||||
static method.
|
||||
*/
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
We're still only scratching the surface here of what Haxe can do. For a formal
|
||||
overiew of all Haxe features, checkout the [online
|
||||
manual](http://haxe.org/manual), the [online api](http://api.haxe.org/), and
|
||||
"haxelib", the [haxe library repo] (http://lib.haxe.org/).
|
||||
|
||||
For more advanced topics, consider checking out:
|
||||
|
||||
* [Abstract types](http://haxe.org/manual/abstracts)
|
||||
* [Macros](http://haxe.org/manual/macros), and [Compiler Macros](http://haxe.org/manual/macros_compiler)
|
||||
* [Tips and Tricks](http://haxe.org/manual/tips_and_tricks)
|
||||
|
||||
|
||||
Finally, please join us on [the mailing list](https://groups.google.com/forum/#!forum/haxelang), on IRC [#haxe on
|
||||
freenode](http://webchat.freenode.net/), or on
|
||||
[Google+](https://plus.google.com/communities/103302587329918132234).
|
||||
|
||||
|
||||
|
@ -38,7 +38,7 @@ import (
|
||||
"strconv" // Stringek átalakítására szolgáló csomag
|
||||
)
|
||||
|
||||
// Funkció deklarás, a main nevű funkció a program kezdőpontja.
|
||||
// Funkció deklarálás, a main nevű funkció a program kezdőpontja.
|
||||
func main() {
|
||||
// Println kiírja a beadott paramétereket a standard kimenetre.
|
||||
// Ha más csomagot funkcióját akarjuk használni, akkor azt jelezni kell a
|
||||
|
@ -3,6 +3,7 @@
|
||||
language: java
|
||||
contributors:
|
||||
- ["Jake Prather", "http://github.com/JakeHP"]
|
||||
- ["Madison Dickson", "http://github.com/mix3d"]
|
||||
filename: LearnJava.java
|
||||
|
||||
---
|
||||
@ -25,7 +26,8 @@ import java.util.ArrayList;
|
||||
// Import all classes inside of java.security package
|
||||
import java.security.*;
|
||||
|
||||
// Each .java file contains one public class, with the same name as the file.
|
||||
// Each .java file contains one outer-level public class, with the same name as
|
||||
// the file.
|
||||
public class LearnJava {
|
||||
|
||||
// A program must have a main method as an entry point
|
||||
@ -83,7 +85,7 @@ public class LearnJava {
|
||||
// Char - A single 16-bit Unicode character
|
||||
char fooChar = 'A';
|
||||
|
||||
// Use final to make a variable immutable
|
||||
// final variables can't be reassigned to another object
|
||||
final int HOURS_I_WORK_PER_WEEK = 9001;
|
||||
|
||||
// Strings
|
||||
@ -98,7 +100,7 @@ public class LearnJava {
|
||||
System.out.println(bazString);
|
||||
|
||||
// Arrays
|
||||
//The array size must be decided upon declaration
|
||||
//The array size must be decided upon instantiation
|
||||
//The format for declaring an array is follows:
|
||||
//<datatype> [] <var name> = new <datatype>[<array size>];
|
||||
int [] intArray = new int[10];
|
||||
@ -160,10 +162,13 @@ public class LearnJava {
|
||||
// Incrementations
|
||||
int i = 0;
|
||||
System.out.println("\n->Inc/Dec-rementation");
|
||||
System.out.println(i++); //i = 1. Post-Incrementation
|
||||
System.out.println(++i); //i = 2. Pre-Incrementation
|
||||
System.out.println(i--); //i = 1. Post-Decrementation
|
||||
System.out.println(--i); //i = 0. Pre-Decrementation
|
||||
// The ++ and -- operators increment and decrement by 1 respectively.
|
||||
// If they are placed before the variable, they increment then return;
|
||||
// after the variable they return then increment.
|
||||
System.out.println(i++); //i = 1, prints 0 (post-increment)
|
||||
System.out.println(++i); //i = 2, prints 2 (pre-increment)
|
||||
System.out.println(i--); //i = 1, prints 2 (post-decrement)
|
||||
System.out.println(--i); //i = 0, prints 0 (pre-decrement)
|
||||
|
||||
///////////////////////////////////////
|
||||
// Control Structures
|
||||
@ -211,6 +216,18 @@ public class LearnJava {
|
||||
}
|
||||
System.out.println("fooFor Value: " + fooFor);
|
||||
|
||||
// For Each Loop
|
||||
// An automatic iteration through an array or list of objects.
|
||||
int[] fooList = {1,2,3,4,5,6,7,8,9};
|
||||
//for each loop structure => for(<object> : <array_object>)
|
||||
//reads as: for each object in the array
|
||||
//note: the object type must match the array.
|
||||
|
||||
for( int bar : fooList ){
|
||||
//System.out.println(bar);
|
||||
//Iterates 9 times and prints 1-9 on new lines
|
||||
}
|
||||
|
||||
// Switch Case
|
||||
// A switch works with the byte, short, char, and int data types.
|
||||
// It also works with enumerated types (discussed in Enum Types),
|
||||
@ -234,6 +251,13 @@ public class LearnJava {
|
||||
}
|
||||
System.out.println("Switch Case Result: " + monthString);
|
||||
|
||||
// Conditional Shorthand
|
||||
// You can use the '?' operator for quick assignments or logic forks.
|
||||
// Reads as "If (statement) is true, use <first value>, otherwise, use <second value>"
|
||||
int foo = 5;
|
||||
String bar = (foo < 10) ? "A" : "B";
|
||||
System.out.println(bar); // Prints A, because the statement is true
|
||||
|
||||
|
||||
///////////////////////////////////////
|
||||
// Converting Data Types And Typcasting
|
||||
@ -274,14 +298,14 @@ public class LearnJava {
|
||||
trek.speedUp(3); // You should always use setter and getter methods
|
||||
trek.setCadence(100);
|
||||
|
||||
// toString is a convention to display the value of this Object.
|
||||
// toString returns this Object's string representation.
|
||||
System.out.println("trek info: " + trek.toString());
|
||||
|
||||
} // End main method
|
||||
} // End LearnJava class
|
||||
|
||||
|
||||
// You can include other, non-public classes in a .java file
|
||||
// You can include other, non-public outer-level classes in a .java file
|
||||
|
||||
|
||||
// Class Declaration Syntax:
|
||||
@ -299,7 +323,7 @@ class Bicycle {
|
||||
String name; // default: Only accessible from within this package
|
||||
|
||||
// Constructors are a way of creating classes
|
||||
// This is a default constructor
|
||||
// This is a constructor
|
||||
public Bicycle() {
|
||||
gear = 1;
|
||||
cadence = 50;
|
||||
@ -307,7 +331,7 @@ class Bicycle {
|
||||
name = "Bontrager";
|
||||
}
|
||||
|
||||
// This is a specified constructor (it contains arguments)
|
||||
// This is a constructor that takes arguments
|
||||
public Bicycle(int startCadence, int startSpeed, int startGear, String name) {
|
||||
this.gear = startGear;
|
||||
this.cadence = startCadence;
|
||||
|
@ -1,7 +1,8 @@
|
||||
---
|
||||
language: javascript
|
||||
author: Adam Brenecki
|
||||
author_url: http://adam.brenecki.id.au
|
||||
contributors:
|
||||
- ["Adam Brenecki", "http://adam.brenecki.id.au"]
|
||||
filename: javascript.js
|
||||
---
|
||||
|
||||
Javascript was created by Netscape's Brendan Eich in 1995. It was originally
|
||||
@ -37,6 +38,8 @@ doStuff()
|
||||
// 1. Numbers, Strings and Operators
|
||||
|
||||
// Javascript has one number type (which is a 64-bit IEEE 754 double).
|
||||
// As with Lua, don't freak out about the lack of ints: doubles have a 52-bit
|
||||
// mantissa, which is enough to store integers up to about 9✕10¹⁵ precisely.
|
||||
3; // = 3
|
||||
1.5; // = 1.5
|
||||
|
||||
@ -104,10 +107,10 @@ false;
|
||||
|
||||
// There's also null and undefined
|
||||
null; // used to indicate a deliberate non-value
|
||||
undefined; // used to indicate a value is not currently present (although undefined
|
||||
// is actually a value itself)
|
||||
undefined; // used to indicate a value is not currently present (although
|
||||
// undefined is actually a value itself)
|
||||
|
||||
// false, null, undefined, NaN, 0 and "" are falsy, and everything else is truthy.
|
||||
// false, null, undefined, NaN, 0 and "" are falsy; everything else is truthy.
|
||||
// Note that 0 is falsy and "0" is truthy, even though 0 == "0".
|
||||
|
||||
///////////////////////////////////
|
||||
@ -141,6 +144,10 @@ var myArray = ["Hello", 45, true];
|
||||
// Array indices start at zero.
|
||||
myArray[1]; // = 45
|
||||
|
||||
// Arrays are mutable and of variable length.
|
||||
myArray.push("World");
|
||||
myArray.length; // = 4
|
||||
|
||||
// JavaScript's objects are equivalent to 'dictionaries' or 'maps' in other
|
||||
// languages: an unordered collection of key-value pairs.
|
||||
var myObj = {key1: "Hello", key2: "World"};
|
||||
@ -218,6 +225,8 @@ function myFunction(){
|
||||
// this code will be called in 5 seconds' time
|
||||
}
|
||||
setTimeout(myFunction, 5000);
|
||||
// Note: setTimeout isn't part of the JS language, but is provided by browsers
|
||||
// and Node.js.
|
||||
|
||||
// Function objects don't even have to be declared with a name - you can write
|
||||
// an anonymous function definition directly into the arguments of another.
|
||||
@ -297,8 +306,8 @@ myObj.myOtherFunc = myOtherFunc;
|
||||
myObj.myOtherFunc(); // = "HELLO WORLD!"
|
||||
|
||||
// When you call a function with the new keyword, a new object is created, and
|
||||
// made available to the function via this. Functions designed to be called
|
||||
// like this are called constructors.
|
||||
// made available to the function via the this keyword. Functions designed to be
|
||||
// called like that are called constructors.
|
||||
|
||||
var MyConstructor = function(){
|
||||
this.myNumber = 5;
|
||||
@ -314,7 +323,7 @@ myNewObj.myNumber; // = 5
|
||||
// property __proto__. While this is useful for explaining prototypes it's not
|
||||
// part of the standard; we'll get to standard ways of using prototypes later.
|
||||
var myObj = {
|
||||
myString: "Hello world!",
|
||||
myString: "Hello world!"
|
||||
};
|
||||
var myPrototype = {
|
||||
meaningOfLife: 42,
|
||||
@ -322,6 +331,7 @@ var myPrototype = {
|
||||
return this.myString.toLowerCase()
|
||||
}
|
||||
};
|
||||
|
||||
myObj.__proto__ = myPrototype;
|
||||
myObj.meaningOfLife; // = 42
|
||||
|
||||
@ -354,13 +364,16 @@ myObj.meaningOfLife; // = 43
|
||||
// Constructors have a property called prototype. This is *not* the prototype of
|
||||
// the constructor function itself; instead, it's the prototype that new objects
|
||||
// are given when they're created with that constructor and the new keyword.
|
||||
myConstructor.prototype = {
|
||||
MyConstructor.prototype = {
|
||||
myNumber: 5,
|
||||
getMyNumber: function(){
|
||||
return this.myNumber
|
||||
return this.myNumber;
|
||||
}
|
||||
};
|
||||
var myNewObj2 = new myConstructor();
|
||||
var myNewObj2 = new MyConstructor();
|
||||
myNewObj2.getMyNumber(); // = 5
|
||||
myNewObj2.myNumber = 6
|
||||
myNewObj2.getMyNumber(); // = 6
|
||||
|
||||
// Built-in types like strings and numbers also have constructors that create
|
||||
// equivalent wrapper objects.
|
||||
|
@ -8,7 +8,7 @@ filename: learnjulia.jl
|
||||
Julia is a new homoiconic functional language focused on technical computing.
|
||||
While having the full power of homoiconic macros, first-class functions, and low-level control, Julia is as easy to learn and use as Python.
|
||||
|
||||
This is based on the current development version of Julia, as of June 29th, 2013.
|
||||
This is based on the current development version of Julia, as of October 18th, 2013.
|
||||
|
||||
```ruby
|
||||
|
||||
@ -20,20 +20,20 @@ This is based on the current development version of Julia, as of June 29th, 2013
|
||||
|
||||
# Everything in Julia is a expression.
|
||||
|
||||
# You have numbers
|
||||
# There are several basic types of numbers.
|
||||
3 #=> 3 (Int64)
|
||||
3.2 #=> 3.2 (Float64)
|
||||
2 + 1im #=> 2 + 1im (Complex{Int64})
|
||||
2//3 #=> 2//3 (Rational{Int64})
|
||||
|
||||
# Math is what you would expect
|
||||
# All of the normal infix operators are available.
|
||||
1 + 1 #=> 2
|
||||
8 - 1 #=> 7
|
||||
10 * 2 #=> 20
|
||||
35 / 5 #=> 7.0
|
||||
5 / 2 #=> 2.5 # dividing an Int by an Int always results in a Float
|
||||
div(5, 2) #=> 2 # for a truncated result, use div
|
||||
5 \ 35 #=> 7.0
|
||||
5 / 2 #=> 2.5
|
||||
div(5, 2) #=> 2
|
||||
2 ^ 2 #=> 4 # power, not bitwise xor
|
||||
12 % 10 #=> 2
|
||||
|
||||
@ -77,11 +77,13 @@ false
|
||||
# Strings are created with "
|
||||
"This is a string."
|
||||
|
||||
# Character literals written with '
|
||||
# Character literals are written with '
|
||||
'a'
|
||||
|
||||
# A string can be treated like a list of characters
|
||||
# A string can be indexed like an array of characters
|
||||
"This is a string"[1] #=> 'T' # Julia indexes from 1
|
||||
# However, this is will not work well for UTF8 strings,
|
||||
# so iterating over strings is reccommended (map, for loops, etc).
|
||||
|
||||
# $ can be used for string interpolation:
|
||||
"2 + 2 = $(2 + 2)" #=> "2 + 2 = 4"
|
||||
@ -94,11 +96,11 @@ false
|
||||
## 2. Variables and Collections
|
||||
####################################################
|
||||
|
||||
# Printing is pretty easy
|
||||
# Printing is easy
|
||||
println("I'm Julia. Nice to meet you!")
|
||||
|
||||
# No need to declare variables before assigning to them.
|
||||
some_var = 5 #=> 5
|
||||
# You don't declare variables before assigning to them.
|
||||
some_var = 5 #=> 5
|
||||
some_var #=> 5
|
||||
|
||||
# Accessing a previously unassigned variable is an error
|
||||
@ -108,12 +110,14 @@ catch e
|
||||
println(e)
|
||||
end
|
||||
|
||||
# Variable name start with a letter. You can use uppercase letters, digits,
|
||||
# and exclamation points as well after the initial alphabetic character.
|
||||
# Variable names start with a letter.
|
||||
# After that, you can use letters, digits, underscores, and exclamation points.
|
||||
SomeOtherVar123! = 6 #=> 6
|
||||
|
||||
# You can also use unicode characters
|
||||
☃ = 8 #=> 8
|
||||
# These are especially handy for mathematical notation
|
||||
2 * π #=> 6.283185307179586
|
||||
|
||||
# A note on naming conventions in Julia:
|
||||
#
|
||||
@ -147,7 +151,7 @@ push!(a,3) #=> [1,2,4,3]
|
||||
append!(a,b) #=> [1,2,4,3,4,5,6]
|
||||
|
||||
# Remove from the end with pop
|
||||
pop!(a) #=> 6 and b is now [4,5]
|
||||
pop!(b) #=> 6 and b is now [4,5]
|
||||
|
||||
# Let's put it back
|
||||
push!(b,6) # b is now [4,5,6] again.
|
||||
@ -158,6 +162,10 @@ a[1] #=> 1 # remember that Julia indexes from 1, not 0!
|
||||
# indexing expression
|
||||
a[end] #=> 6
|
||||
|
||||
# we also have shift and unshift
|
||||
shift!(a) #=> 1 and a is now [2,4,3,4,5,6]
|
||||
unshift!(a,7) #=> [7,2,4,3,4,5,6]
|
||||
|
||||
# Function names that end in exclamations points indicate that they modify
|
||||
# their argument.
|
||||
arr = [5,4,6] #=> 3-element Int64 Array: [5,4,6]
|
||||
@ -182,23 +190,24 @@ a = [1:5] #=> 5-element Int64 Array: [1,2,3,4,5]
|
||||
# You can look at ranges with slice syntax.
|
||||
a[1:3] #=> [1, 2, 3]
|
||||
a[2:] #=> [2, 3, 4, 5]
|
||||
a[2:end] #=> [2, 3, 4, 5]
|
||||
|
||||
# Remove arbitrary elements from a list with splice!
|
||||
# Remove elements from an array by index with splice!
|
||||
arr = [3,4,5]
|
||||
splice!(arr,2) #=> 4 ; arr is now [3,5]
|
||||
|
||||
# Concatenate lists with append!
|
||||
b = [1,2,3]
|
||||
append!(a,b) # Now a is [1, 3, 4, 5, 1, 2, 3]
|
||||
append!(a,b) # Now a is [1, 2, 3, 4, 5, 1, 2, 3]
|
||||
|
||||
# Check for existence in a list with contains
|
||||
contains(a,1) #=> true
|
||||
# Check for existence in a list with in
|
||||
in(1, a) #=> true
|
||||
|
||||
# Examine the length with length
|
||||
length(a) #=> 7
|
||||
length(a) #=> 8
|
||||
|
||||
# Tuples are immutable.
|
||||
tup = (1, 2, 3) #=>(1,2,3) # an (Int64,Int64,Int64) tuple.
|
||||
tup = (1, 2, 3) #=> (1,2,3) # an (Int64,Int64,Int64) tuple.
|
||||
tup[1] #=> 1
|
||||
try:
|
||||
tup[0] = 3 #=> ERROR: no method setindex!((Int64,Int64,Int64),Int64,Int64)
|
||||
@ -209,22 +218,26 @@ end
|
||||
# Many list functions also work on tuples
|
||||
length(tup) #=> 3
|
||||
tup[1:2] #=> (1,2)
|
||||
contains(tup,2) #=> true
|
||||
in(2, tup) #=> true
|
||||
|
||||
# You can unpack tuples into variables
|
||||
a, b, c = (1, 2, 3) #=> (1,2,3) # a is now 1, b is now 2 and c is now 3
|
||||
|
||||
# Tuples are created by default if you leave out the parentheses
|
||||
# Tuples are created even if you leave out the parentheses
|
||||
d, e, f = 4, 5, 6 #=> (4,5,6)
|
||||
|
||||
# Now look how easy it is to swap two values
|
||||
# A 1-element tuple is distinct from the value it contains
|
||||
(1,) == 1 #=> false
|
||||
(1) == 1 #=> true
|
||||
|
||||
# Look how easy it is to swap two values
|
||||
e, d = d, e #=> (5,4) # d is now 5 and e is now 4
|
||||
|
||||
|
||||
# Dictionaries store mappings
|
||||
empty_dict = Dict() #=> Dict{Any,Any}()
|
||||
|
||||
# Here is a prefilled dictionary
|
||||
# You can create a dictionary using a literal
|
||||
filled_dict = ["one"=> 1, "two"=> 2, "three"=> 3]
|
||||
# => Dict{ASCIIString,Int64}
|
||||
|
||||
@ -236,36 +249,40 @@ keys(filled_dict)
|
||||
#=> KeyIterator{Dict{ASCIIString,Int64}}(["three"=>3,"one"=>1,"two"=>2])
|
||||
# Note - dictionary keys are not sorted or in the order you inserted them.
|
||||
|
||||
# Get all values
|
||||
# Get all values
|
||||
values(filled_dict)
|
||||
#=> ValueIterator{Dict{ASCIIString,Int64}}(["three"=>3,"one"=>1,"two"=>2])
|
||||
# Note - Same as above regarding key ordering.
|
||||
|
||||
# Check for existence of keys in a dictionary with contains, haskey
|
||||
contains(filled_dict, ("one", 1)) #=> true
|
||||
contains(filled_dict, ("two", 3)) #=> false
|
||||
# Check for existence of keys in a dictionary with in, haskey
|
||||
in(("one", 1), filled_dict) #=> true
|
||||
in(("two", 3), filled_dict) #=> false
|
||||
haskey(filled_dict, "one") #=> true
|
||||
haskey(filled_dict, 1) #=> false
|
||||
|
||||
# Trying to look up a non-existing key will raise an error
|
||||
# Trying to look up a non-existant key will raise an error
|
||||
try
|
||||
filled_dict["four"] #=> ERROR: key not found: four in getindex at dict.jl:489
|
||||
catch e
|
||||
println(e)
|
||||
end
|
||||
|
||||
# Use get method to avoid the error
|
||||
# Use the get method to avoid that error by providing a default value
|
||||
# get(dictionary,key,default_value)
|
||||
get(filled_dict,"one",4) #=> 1
|
||||
get(filled_dict,"four",4) #=> 4
|
||||
|
||||
# Sets store sets
|
||||
# Use Sets to represent collections of unordered, unique values
|
||||
empty_set = Set() #=> Set{Any}()
|
||||
# Initialize a set with a bunch of values
|
||||
# Initialize a set with values
|
||||
filled_set = Set(1,2,2,3,4) #=> Set{Int64}(1,2,3,4)
|
||||
|
||||
# Add more items to a set
|
||||
add!(filled_set,5) #=> Set{Int64}(5,4,2,3,1)
|
||||
# Add more values to a set
|
||||
push!(filled_set,5) #=> Set{Int64}(5,4,2,3,1)
|
||||
|
||||
# Check if the values are in the set
|
||||
in(2, filled_set) #=> true
|
||||
in(10, filled_set) #=> false
|
||||
|
||||
# There are functions for set intersection, union, and difference.
|
||||
other_set = Set(3, 4, 5, 6) #=> Set{Int64}(6,4,5,3)
|
||||
@ -273,10 +290,6 @@ intersect(filled_set, other_set) #=> Set{Int64}(3,4,5)
|
||||
union(filled_set, other_set) #=> Set{Int64}(1,2,3,4,5,6)
|
||||
setdiff(Set(1,2,3,4),Set(2,3,5)) #=> Set{Int64}(1,4)
|
||||
|
||||
# Check for existence in a set with contains
|
||||
contains(filled_set,2) #=> true
|
||||
contains(filled_set,10) #=> false
|
||||
|
||||
|
||||
####################################################
|
||||
## 3. Control Flow
|
||||
@ -285,8 +298,7 @@ contains(filled_set,10) #=> false
|
||||
# Let's make a variable
|
||||
some_var = 5
|
||||
|
||||
# Here is an if statement. Indentation is NOT meaningful in Julia.
|
||||
# prints "some var is smaller than 10"
|
||||
# Here is an if statement. Indentation is not meaningful in Julia.
|
||||
if some_var > 10
|
||||
println("some_var is totally bigger than 10.")
|
||||
elseif some_var < 10 # This elseif clause is optional.
|
||||
@ -294,12 +306,22 @@ elseif some_var < 10 # This elseif clause is optional.
|
||||
else # The else clause is optional too.
|
||||
println("some_var is indeed 10.")
|
||||
end
|
||||
#=> prints "some var is smaller than 10"
|
||||
|
||||
|
||||
# For loops iterate over iterables, such as ranges, lists, sets, dicts, strings.
|
||||
|
||||
# For loops iterate over iterables.
|
||||
# Iterable types include Range, Array, Set, Dict, and String.
|
||||
for animal=["dog", "cat", "mouse"]
|
||||
# You can use $ to interpolate into strings
|
||||
println("$animal is a mammal")
|
||||
# You can use $ to interpolate variables or expression into strings
|
||||
end
|
||||
# prints:
|
||||
# dog is a mammal
|
||||
# cat is a mammal
|
||||
# mouse is a mammal
|
||||
|
||||
# You can use 'in' instead of '='.
|
||||
for animal in ["dog", "cat", "mouse"]
|
||||
println("$animal is a mammal")
|
||||
end
|
||||
# prints:
|
||||
@ -307,31 +329,33 @@ end
|
||||
# cat is a mammal
|
||||
# mouse is a mammal
|
||||
|
||||
# You can use in instead of =, if you want.
|
||||
for animal in ["dog", "cat", "mouse"]
|
||||
println("$animal is a mammal")
|
||||
end
|
||||
|
||||
for a in ["dog"=>"mammal","cat"=>"mammal","mouse"=>"mammal"]
|
||||
println("$(a[1]) is $(a[2])")
|
||||
println("$(a[1]) is a $(a[2])")
|
||||
end
|
||||
# prints:
|
||||
# dog is a mammal
|
||||
# cat is a mammal
|
||||
# mouse is a mammal
|
||||
|
||||
for (k,v) in ["dog"=>"mammal","cat"=>"mammal","mouse"=>"mammal"]
|
||||
println("$k is $v")
|
||||
println("$k is a $v")
|
||||
end
|
||||
|
||||
|
||||
# While loops go until a condition is no longer met.
|
||||
# prints:
|
||||
# 0
|
||||
# 1
|
||||
# 2
|
||||
# 3
|
||||
# dog is a mammal
|
||||
# cat is a mammal
|
||||
# mouse is a mammal
|
||||
|
||||
# While loops loop while a condition is true
|
||||
x = 0
|
||||
while x < 4
|
||||
println(x)
|
||||
x += 1 # Shorthand for x = x + 1
|
||||
end
|
||||
# prints:
|
||||
# 0
|
||||
# 1
|
||||
# 2
|
||||
# 3
|
||||
|
||||
# Handle exceptions with a try/except block
|
||||
try
|
||||
@ -346,11 +370,14 @@ end
|
||||
## 4. Functions
|
||||
####################################################
|
||||
|
||||
# Use the keyword function to create new functions
|
||||
# The keyword 'function' creates new functions
|
||||
#function name(arglist)
|
||||
# body...
|
||||
#end
|
||||
function add(x, y)
|
||||
println("x is $x and y is $y")
|
||||
|
||||
# Functions implicitly return the value of their last statement
|
||||
# Functions return the value of their last statement
|
||||
x + y
|
||||
end
|
||||
|
||||
@ -360,13 +387,16 @@ add(5, 6) #=> 11 after printing out "x is 5 and y is 6"
|
||||
# positional arguments
|
||||
function varargs(args...)
|
||||
return args
|
||||
# use the keyword return to return anywhere in the function
|
||||
end
|
||||
#=> varargs (generic function with 1 method)
|
||||
|
||||
varargs(1,2,3) #=> (1,2,3)
|
||||
|
||||
# The ... is called a splat.
|
||||
# It can also be used in a fuction call
|
||||
# to splat a list or tuple out to be the arguments
|
||||
# We just used it in a function definition.
|
||||
# It can also be used in a fuction call,
|
||||
# where it will splat an Array or Tuple's contents into the argument list.
|
||||
Set([1,2,3]) #=> Set{Array{Int64,1}}([1,2,3]) # produces a Set of Arrays
|
||||
Set([1,2,3]...) #=> Set{Int64}(1,2,3) # this is equivalent to Set(1,2,3)
|
||||
|
||||
@ -393,13 +423,13 @@ end
|
||||
# You can define functions that take keyword arguments
|
||||
function keyword_args(;k1=4,name2="hello") # note the ;
|
||||
return ["k1"=>k1,"name2"=>name2]
|
||||
end
|
||||
end
|
||||
|
||||
keyword_args(name2="ness") #=> ["name2"=>"ness","k1"=>4]
|
||||
keyword_args(k1="mine") #=> ["k1"=>"mine","name2"=>"hello"]
|
||||
keyword_args() #=> ["name2"=>"hello","k2"=>4]
|
||||
|
||||
# You can also do both at once
|
||||
# You can combine all kinds of arguments in the same function
|
||||
function all_the_args(normal_arg, optional_positional_arg=2; keyword_arg="foo")
|
||||
println("normal arg: $normal_arg")
|
||||
println("optional arg: $optional_positional_arg")
|
||||
@ -420,12 +450,15 @@ function create_adder(x)
|
||||
return adder
|
||||
end
|
||||
|
||||
# or equivalently
|
||||
# This is "stabby lambda syntax" for creating anonymous functions
|
||||
(x -> x > 2)(3) #=> true
|
||||
|
||||
# This function is identical to create_adder implementation above.
|
||||
function create_adder(x)
|
||||
y -> x + y
|
||||
end
|
||||
|
||||
# you can also name the internal function, if you want
|
||||
# You can also name the internal function, if you want
|
||||
function create_adder(x)
|
||||
function adder(y)
|
||||
x + y
|
||||
@ -436,61 +469,114 @@ end
|
||||
add_10 = create_adder(10)
|
||||
add_10(3) #=> 13
|
||||
|
||||
# The first two inner functions above are anonymous functions
|
||||
(x -> x > 2)(3) #=> true
|
||||
|
||||
# There are built-in higher order functions
|
||||
map(add_10, [1,2,3]) #=> [11, 12, 13]
|
||||
filter(x -> x > 5, [3, 4, 5, 6, 7]) #=> [6, 7]
|
||||
|
||||
# We can use list comprehensions for nice maps and filters
|
||||
# We can use list comprehensions for nicer maps
|
||||
[add_10(i) for i=[1, 2, 3]] #=> [11, 12, 13]
|
||||
[add_10(i) for i in [1, 2, 3]] #=> [11, 12, 13]
|
||||
|
||||
####################################################
|
||||
## 5. Types and Multiple-Dispatch
|
||||
## 5. Types
|
||||
####################################################
|
||||
|
||||
# Type definition
|
||||
# Julia has a type system.
|
||||
# Every value has a type; variables do not have types themselves.
|
||||
# You can use the `typeof` function to get the type of a value.
|
||||
typeof(5) #=> Int64
|
||||
|
||||
# Types are first-class values
|
||||
typeof(Int64) #=> DataType
|
||||
typeof(DataType) #=> DataType
|
||||
# DataType is the type that represents types, including itself.
|
||||
|
||||
# Types are used for documentation, optimizations, and dispatch.
|
||||
# They are not statically checked.
|
||||
|
||||
# Users can define types
|
||||
# They are like records or structs in other languages.
|
||||
# New types are defined used the `type` keyword.
|
||||
|
||||
# type Name
|
||||
# field::OptionalType
|
||||
# ...
|
||||
# end
|
||||
type Tiger
|
||||
taillength::Float64
|
||||
coatcolor # no type annotation is implicitly Any
|
||||
coatcolor # not including a type annotation is the same as `::Any`
|
||||
end
|
||||
# default constructor is the properties in order
|
||||
# so, Tiger(taillength,coatcolor)
|
||||
|
||||
# Type instantiation
|
||||
tigger = Tiger(3.5,"orange") # the type doubles as the constructor function
|
||||
# The default constructor's arguments are the properties
|
||||
# of the tyep, in order the order they are listed in the definition
|
||||
tigger = Tiger(3.5,"orange") #=> Tiger(3.5,"orange")
|
||||
|
||||
# Abtract Types
|
||||
# The type doubles as the constructor function for values of that type
|
||||
sherekhan = typeof(tigger)(5.6,"fire") #=> Tiger(5.6,"fire")
|
||||
|
||||
# These struct-style types are called concrete types
|
||||
# They can be instantiated, but cannot have subtypes.
|
||||
# The other kind of types is abstract types.
|
||||
|
||||
# abstract Name
|
||||
abstract Cat # just a name and point in the type hierarchy
|
||||
|
||||
# * types defined with the type keyword are concrete types; they can be
|
||||
# instantiated
|
||||
#
|
||||
# * types defined with the abstract keyword are abstract types; they can
|
||||
# have subtypes.
|
||||
#
|
||||
# * each type has one supertype; a supertype can have zero or more subtypes.
|
||||
# Abstract types cannot be instantiated, but can have subtypes.
|
||||
# For example, Number is an abstract type
|
||||
subtypes(Number) #=> 6-element Array{Any,1}:
|
||||
# Complex{Float16}
|
||||
# Complex{Float32}
|
||||
# Complex{Float64}
|
||||
# Complex{T<:Real}
|
||||
# ImaginaryUnit
|
||||
# Real
|
||||
subtypes(Cat) #=> 0-element Array{Any,1}
|
||||
|
||||
# Every type has a super type; use the `super` function to get it.
|
||||
typeof(5) #=> Int64
|
||||
super(Int64) #=> Signed
|
||||
super(Signed) #=> Real
|
||||
super(Real) #=> Number
|
||||
super(Number) #=> Any
|
||||
super(super(Signed)) #=> Number
|
||||
super(Any) #=> Any
|
||||
# All of these type, except for Int64, are abstract.
|
||||
|
||||
# <: is the subtyping operator
|
||||
type Lion <: Cat # Lion is a subtype of Cat
|
||||
mane_color
|
||||
roar::String
|
||||
end
|
||||
|
||||
# You can define more constructors for your type
|
||||
# Just define a function of the same name as the type
|
||||
# and call an existing constructor to get a value of the correct type
|
||||
Lion(roar::String) = Lion("green",roar)
|
||||
# This is an outer constructor because it's outside the type definition
|
||||
|
||||
type Panther <: Cat # Panther is also a subtype of Cat
|
||||
eye_color
|
||||
Panther() = new("green")
|
||||
# Panthers will only have this constructor, and no default constructor.
|
||||
end
|
||||
# Using inner constructors, like Panter does, gives you control
|
||||
# over how values of the type can be created.
|
||||
# When possible, you should use outer constructors rather than inner ones.
|
||||
|
||||
# Multiple Dispatch
|
||||
####################################################
|
||||
## 6. Multiple-Dispatch
|
||||
####################################################
|
||||
|
||||
# In Julia, all named functions are generic functions
|
||||
# This means that they are built up from many small methods
|
||||
# For example, let's make a function meow:
|
||||
# Each constructor for Lion is a method of the generic function Lion.
|
||||
|
||||
# For a non-constructor example, let's make a function meow:
|
||||
|
||||
# Definitions for Lion, Panther, Tiger
|
||||
function meow(cat::Lion)
|
||||
cat.roar # access properties using dot notation
|
||||
cat.roar # access type properties using dot notation
|
||||
end
|
||||
|
||||
function meow(cat::Panther)
|
||||
@ -501,21 +587,75 @@ function meow(cat::Tiger)
|
||||
"rawwwr"
|
||||
end
|
||||
|
||||
# Testing the meow function
|
||||
meow(tigger) #=> "rawwr"
|
||||
meow(Lion("brown","ROAAR")) #=> "ROAAR"
|
||||
meow(Panther()) #=> "grrr"
|
||||
|
||||
# Review the local type hierarchy
|
||||
issubtype(Tiger,Cat) #=> false
|
||||
issubtype(Lion,Cat) #=> true
|
||||
issubtype(Panther,Cat) #=> true
|
||||
|
||||
# Defining a function that takes Cats
|
||||
function pet_cat(cat::Cat)
|
||||
println("The cat says $(meow(cat))")
|
||||
end
|
||||
|
||||
pet_cat(Lion("42")) #=> prints "The cat says 42"
|
||||
try
|
||||
pet_cat(tigger) #=> ERROR: no method pet_cat(Tiger,)
|
||||
catch e
|
||||
println(e)
|
||||
end
|
||||
|
||||
pet_cat(Lion(Panther(),"42")) #=> prints "The cat says 42"
|
||||
# In OO languages, single dispatch is common;
|
||||
# this means that the method is picked based on the type of the first argument.
|
||||
# In Julia, all of the argument types contribute to selecting the best method.
|
||||
|
||||
# Let's define a function with more arguments, so we can see the difference
|
||||
function fight(t::Tiger,c::Cat)
|
||||
println("The $(t.coatcolor) tiger wins!")
|
||||
end
|
||||
#=> fight (generic function with 1 method)
|
||||
|
||||
fight(tigger,Panther()) #=> prints The orange tiger wins!
|
||||
fight(tigger,Lion("ROAR")) #=> prints The orange tiger wins!
|
||||
|
||||
# Let's change the behavior when the Cat is specifically a Lion
|
||||
fight(t::Tiger,l::Lion) = println("The $(l.mane_color)-maned lion wins!")
|
||||
#=> fight (generic function with 2 methods)
|
||||
|
||||
fight(tigger,Panther()) #=> prints The orange tiger wins!
|
||||
fight(tigger,Lion("ROAR")) #=> prints The green-maned lion wins!
|
||||
|
||||
# We don't need a Tiger in order to fight
|
||||
fight(l::Lion,c::Cat) = println("The victorious cat says $(meow(c))")
|
||||
#=> fight (generic function with 3 methods)
|
||||
|
||||
fight(Lion("balooga!"),Panther()) #=> prints The victorious cat says grrr
|
||||
try
|
||||
fight(Panther(),Lion("RAWR")) #=> ERROR: no method fight(Panther,Lion)
|
||||
catch
|
||||
end
|
||||
|
||||
# Also let the cat go first
|
||||
fight(c::Cat,l::Lion) = println("The cat beats the Lion")
|
||||
#=> Warning: New definition
|
||||
# fight(Cat,Lion) at none:1
|
||||
# is ambiguous with
|
||||
# fight(Lion,Cat) at none:2.
|
||||
# Make sure
|
||||
# fight(Lion,Lion)
|
||||
# is defined first.
|
||||
#fight (generic function with 4 methods)
|
||||
|
||||
# This warning is because it's unclear which fight will be called in:
|
||||
fight(Lion("RAR"),Lion("brown","rarrr")) #=> prints The victorious cat says rarrr
|
||||
# The result may be different in other versions of Julia
|
||||
|
||||
fight(l::Lion,l2::Lion) = println("The lions come to a tie")
|
||||
fight(Lion("RAR"),Lion("brown","rarrr")) #=> prints The lions come to a tie
|
||||
|
||||
```
|
||||
|
||||
@ -523,3 +663,4 @@ pet_cat(Lion(Panther(),"42")) #=> prints "The cat says 42"
|
||||
|
||||
You can get a lot more detail from [The Julia Manual](http://docs.julialang.org/en/latest/manual/)
|
||||
|
||||
The best place to get help with Julia is the (very friendly) [mailing list](https://groups.google.com/forum/#!forum/julia-users).
|
||||
|
84
ko-kr/brainfuck-kr.html.markdown
Normal file
84
ko-kr/brainfuck-kr.html.markdown
Normal file
@ -0,0 +1,84 @@
|
||||
---
|
||||
language: brainfuck
|
||||
contributors:
|
||||
- ["Prajit Ramachandran", "http://prajitr.github.io/"]
|
||||
- ["Mathias Bynens", "http://mathiasbynens.be/"]
|
||||
translators:
|
||||
- ["JongChan Choi", "http://0xABCDEF.com/"]
|
||||
- ["Peter Lee", "http://peterjlee.com/"]
|
||||
lang: ko-kr
|
||||
---
|
||||
|
||||
Brainfuck(문장을 시작하는 단어가 아닌이상 첫글자는 대문자를 사용하지 않습니다)은
|
||||
여덟가지 명령어만으로 튜링-완전한 최소주의 프로그래밍 언어입니다.
|
||||
|
||||
```
|
||||
"><+-.,[]" 이외의 문자들은 무시됩니다. (쌍따옴표는 제외)
|
||||
|
||||
브레인퍽은 30,000 칸 짜리의 0으로 초기화된 배열과,
|
||||
현재 칸을 가르키는 포인터로 표현됩니다.
|
||||
|
||||
여덟가지의 명령어는 다음과 같습니다:
|
||||
+ : 포인터가 가르키는 현재 칸의 값을 1 증가시킵니다.
|
||||
- : 포인터가 가르키는 현재 칸의 값을 1 감소시킵니다.
|
||||
> : 포인터가 다음 칸(오른쪽 칸)을 가르키도록 이동시킵니다.
|
||||
< : 포인터가 이전 칸(왼쪽 칸)을 가르키도록 이동시킵니다.
|
||||
. : 현재 칸의 값을 ASCII 문자로 출력합니다. (즉, 65 = 'A')
|
||||
, : 하나의 문자를 입력받고 그 값을 현재 칸에 대입합니다.
|
||||
[ : 현재 칸의 값이 0이면 짝이 맞는 ] 명령으로 넘어갑니다.
|
||||
0이 아니면 다음 명령어로 넘어갑니다.
|
||||
] : 현재 칸의 값이 0이면 다음 명령어로 넘어갑니다.
|
||||
0이 아니면 짝이 맞는 [ 명령으로 다시 돌아갑니다.
|
||||
|
||||
[이랑 ]은 while 루프를 만들어냅니다. 무조건, 짝이 맞아야 합니다.
|
||||
|
||||
몇가지 간단한 브레인퍽 프로그램을 보겠습니다.
|
||||
|
||||
++++++ [ > ++++++++++ < - ] > +++++ .
|
||||
|
||||
이 프로그램은 문자 'A'를 출력합니다. 처음에는, 반복할 횟수를 정하기 위한 값을
|
||||
만들기 위해 첫번째 칸의 값을 6으로 증가시킵니다. 그리고 루프로 들어가서([)
|
||||
두번째 칸으로 넘어갑니다. 루프 안에서는 두번째 칸의 값을 10 증가시키고,
|
||||
다시 첫번째 칸으로 넘어가서 값을 1 감소시킵니다. 이 루프는 여섯번 돕니다.
|
||||
(첫번째 칸의 값을 6번 감소시켜서 0이 될 때 까지는 ] 명령을 만날 때마다
|
||||
루프의 시작 지점으로 돌아갑니다)
|
||||
|
||||
이 시점에서, 두번째 칸의 값은 60이고, 포인터는 값이 0인 첫번째 칸에 위치합니다.
|
||||
여기서 두번째 칸으로 넘어간 다음 값을 5 증가시키면 두번째 칸의 값이 65가 되고,
|
||||
65는 문자 'A'에 대응하는 아스키 코드이기 때문에, 두번째 칸의 값을 출력하면
|
||||
터미널에 'A'가 출력됩니다.
|
||||
|
||||
, [ > + < - ] > .
|
||||
|
||||
이 프로그램은 사용자로부터 문자 하나를 입력받아 첫번째 칸에 집어넣습니다.
|
||||
그리고 루프에 들어가서, 두번째 칸으로 넘어가 값을 한 번 증가시킨 다음,
|
||||
다시 첫번째 칸으로 넘어가서 값을 한 번 감소시킵니다.
|
||||
이는 첫번째 칸의 값이 0이 될 때까지 지속되며,
|
||||
두번째 칸은 첫번째 칸이 갖고있던 값을 가지게 됩니다.
|
||||
루프가 종료되면 포인터는 첫번째 칸을 가르키기 때문에 두번째 칸으로 넘어가고,
|
||||
해당 아스키 코드에 대응하는 문자를 출력합니다.
|
||||
|
||||
또한 공백문자는 순전히 가독성을 위해서 작성되었다는 것을 기억하세요.
|
||||
다음과 같이 작성해도 똑같이 돌아갑니다:
|
||||
|
||||
,[>+<-]>.
|
||||
|
||||
한 번 돌려보고 아래의 프로그램이 실제로 무슨 일을 하는지 맞춰보세요:
|
||||
|
||||
,>,< [ > [ >+ >+ << -] >> [- << + >>] <<< -] >>
|
||||
|
||||
이 프로그램은 두 개의 숫자를 입력받은 뒤, 그 둘을 곱합니다.
|
||||
|
||||
위 코드는 일단 두 번의 입력을 받고, 첫번째 칸의 값만큼 바깥 루프를 돕니다.
|
||||
그리고 루프 안에서 다시 두번째 칸의 값만큼 안쪽의 루프를 돕니다.
|
||||
그리고 그 루프에서는 세번째 칸의 값을 증가시키는데, 문제가 하나 있습니다:
|
||||
내부 루프가 한 번 끝나게 되면 두번째 칸의 값은 0이 됩니다.
|
||||
그럼 다시 바깥 루프를 돌 때에 안쪽의 루프를 돌지 않게 되는데, 이를 해결하려면
|
||||
네번째 칸의 값도 같이 증가시킨 다음, 그 값을 두번째 칸으로 옮기면 됩니다.
|
||||
그러면 세번째 칸에 곱셈의 결과가 남습니다.
|
||||
```
|
||||
|
||||
여기까지 브레인퍽이었습니다. 참 쉽죠?
|
||||
재미삼아 브레인퍽 프로그램이나 다른 언어로 브레인퍽 인터프리터를 작성해보세요.
|
||||
인터프리터 구현은 간단한 편인데,
|
||||
사서 고생하는 것을 즐기는 편이라면 한 번 작성해보세요… 브레인퍽으로.
|
383
ko-kr/clojure-kr.html.markdown
Normal file
383
ko-kr/clojure-kr.html.markdown
Normal file
@ -0,0 +1,383 @@
|
||||
---
|
||||
language: clojure
|
||||
filename: learnclojure-kr.clj
|
||||
contributors:
|
||||
- ["Adam Bard", "http://adambard.com/"]
|
||||
translators:
|
||||
- ["netpyoung", "http://netpyoung.github.io/"]
|
||||
lang: ko-kr
|
||||
---
|
||||
|
||||
Clojure는 Java 가상머신을 위해 개발된 Lisp 계통의 언어입니다
|
||||
이는 Common Lisp보다 순수 [함수형 프로그래밍](https://en.wikipedia.org/wiki/Functional_programming)을 더욱 강조했으며,
|
||||
상태를 있는 그대로 다루기 위해 다양한 [STM](https://en.wikipedia.org/wiki/Software_transactional_memory) 을 지원하는 프로그램들을 갖췄습니다.
|
||||
|
||||
이를 조합하여, 병행처리(concurrent processing)를 매우 단순하게 처리할 수 있으며,
|
||||
대게 자동으로 처리될 수 있도록 만들 수 있습니다.
|
||||
|
||||
(Clojure 1.2 이상의 버전이 필요로 합니다.)
|
||||
|
||||
|
||||
```clojure
|
||||
; 주석은 세미콜론(;)으로 시작합니다.
|
||||
|
||||
; Clojure는 "폼(forms)"으로 구성되었으며,
|
||||
; 폼은 괄호로 감싸져있으며, 공백으로 구분된 것들이 나열된 것입니다.
|
||||
;
|
||||
; clojure의 reader는 첫번째로 오는 것을
|
||||
; 함수 혹은 매크로를 호출하는 것, 그리고 나머지를 인자라고 가정합니다.
|
||||
|
||||
; namespace를 지정하기 위해, 파일에서 우선적으로 호출해야될 것은 ns입니다.
|
||||
(ns learnclojure)
|
||||
|
||||
; 간단한 예제들:
|
||||
|
||||
; str 은 인자로 받은 것들을 하나의 문자열로 만들어줍니다.
|
||||
(str "Hello" " " "World") ; => "Hello World"
|
||||
|
||||
; 직관적인 수학 함수들을 갖고 있습니다.
|
||||
(+ 1 1) ; => 2
|
||||
(- 2 1) ; => 1
|
||||
(* 1 2) ; => 2
|
||||
(/ 2 1) ; => 2
|
||||
|
||||
; = 로 동일성을 판별할 수 있습니다.
|
||||
(= 1 1) ; => true
|
||||
(= 2 1) ; => false
|
||||
|
||||
; 논리연산을 위한 not 역시 필요합니다.
|
||||
(not true) ; => false
|
||||
|
||||
; 중첩된 폼(forms)은 기대한대로 동작합니다.
|
||||
(+ 1 (- 3 2)) ; = 1 + (3 - 2) => 2
|
||||
|
||||
; 타입
|
||||
;;;;;;;;;;;;;
|
||||
|
||||
; Clojure는 부울(boolean), 문자열, 숫자를 위해 Java의 object 타입을 이용합니다.
|
||||
; `class` 를 이용하여 이를 확인할 수 있습니다.
|
||||
(class 1) ; 정수는 기본적으로 java.lang.Long입니다.
|
||||
(class 1.); 소수는 java.lang.Double입니다.
|
||||
(class ""); 문자열은 쌍따옴표로 감싸져 있으며, java.lang.String입니다.
|
||||
(class false) ; 부울값은 java.lang.Boolean입니다.
|
||||
(class nil); nil은 "null"값입니다.
|
||||
|
||||
; 데이터 리스트 자체를 만들고자 한다면,
|
||||
; '를 이용하여 평가(evaluate)되지 않도록 막아야 합니다.
|
||||
'(+ 1 2) ; => (+ 1 2)
|
||||
; (quote (+ 1 2)) 를 줄여서 쓴것
|
||||
|
||||
; quote 가 된 리스트를 평가할 수 도 있습니다.
|
||||
(eval '(+ 1 2)) ; => 3
|
||||
|
||||
; 컬렉션(Collections) & 시퀀스(Sequences)
|
||||
;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
; 리스트(List)는 연결된(linked-list) 자료구조이며, 벡터(Vector)는 배열이 뒤로붙는(array-backed) 자료구조입니다.
|
||||
; 리스트와 벡터 모두 java 클래스입니다!
|
||||
(class [1 2 3]); => clojure.lang.PersistentVector
|
||||
(class '(1 2 3)); => clojure.lang.PersistentList
|
||||
|
||||
; 간단하게 (1 2 3)로 리스트를 나타낼 수 있지만,
|
||||
; reader가 함수라고 여기지 못하게 quote(')를 해줘야 합니다.
|
||||
; 따라서, (list 1 2 3)는 '(1 2 3)와 같습니다.
|
||||
|
||||
; "컬렉션"은 단순하게 데이터의 그룹입니다.
|
||||
; 리스트와 벡터 모두 컬렉션입니다:
|
||||
(coll? '(1 2 3)) ; => true
|
||||
(coll? [1 2 3]) ; => true
|
||||
|
||||
; "시퀀스" (seq) 는 데이터 리스트를 추상적으로 기술한 것입니다.
|
||||
; 리스트는 시퀀스입니다.
|
||||
(seq? '(1 2 3)) ; => true
|
||||
(seq? [1 2 3]) ; => false
|
||||
|
||||
; 시퀀스는 접근하고자 하는 항목만 제공해주면 됩니다.
|
||||
; 따라서, 시퀀스는 lazy 할 수 있습니다 -- 무한하게 늘어나는 것을 정의할 수 있습니다:
|
||||
(range 4) ; => (0 1 2 3)
|
||||
(range) ; => (0 1 2 3 4 ...) (an infinite series)
|
||||
(take 4 (range)) ; (0 1 2 3)
|
||||
|
||||
; cons 를 이용하여 리스트나 벡터의 시작부에 항목을 추가할 수 있습니다.
|
||||
(cons 4 [1 2 3]) ; => (4 1 2 3)
|
||||
(cons 4 '(1 2 3)) ; => (4 1 2 3)
|
||||
|
||||
; conj 는 컬렉션에 가장 효율적인 방식으로 항목을 추가합니다.
|
||||
; 리스트는 시작부분에 삽입하고, 벡터는 끝부분에 삽입합니다.
|
||||
(conj [1 2 3] 4) ; => [1 2 3 4]
|
||||
(conj '(1 2 3) 4) ; => (4 1 2 3)
|
||||
|
||||
; concat 을 이용하여 리스트와 벡터를 서로 합칠 수 있습니다.
|
||||
(concat [1 2] '(3 4)) ; => (1 2 3 4)
|
||||
|
||||
; filter, map 을 이용하여 컬렉션을 다룰 수 있습니다.
|
||||
(map inc [1 2 3]) ; => (2 3 4)
|
||||
(filter even? [1 2 3]) ; => (2)
|
||||
|
||||
; reduce 를 이용하여 줄여나갈 수 있습니다.
|
||||
(reduce + [1 2 3 4])
|
||||
; = (+ (+ (+ 1 2) 3) 4)
|
||||
; => 10
|
||||
|
||||
; reduce 는 초기 값을 인자로 취할 수 도 있습니다.
|
||||
(reduce conj [] '(3 2 1))
|
||||
; = (conj (conj (conj [] 3) 2) 1)
|
||||
; => [3 2 1]
|
||||
|
||||
; 함수
|
||||
;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
; fn 을 이용하여 함수를 만들 수 있습니다 .
|
||||
; 함수는 항상 마지막 문장을 반환합니다.
|
||||
(fn [] "Hello World") ; => fn
|
||||
|
||||
; (정의한 것을 호출하기 위해선, 괄호가 더 필요합니다.)
|
||||
((fn [] "Hello World")) ; => "Hello World"
|
||||
|
||||
; def 를 이용하여 var 를 만들 수 있습니다.
|
||||
(def x 1)
|
||||
x ; => 1
|
||||
|
||||
; var 에 함수를 할당시켜보겠습니다.
|
||||
(def hello-world (fn [] "Hello World"))
|
||||
(hello-world) ; => "Hello World"
|
||||
|
||||
; defn 을 이용하여 짧게 쓸 수 도 있습니다.
|
||||
(defn hello-world [] "Hello World")
|
||||
|
||||
; [] 는 함수의 인자 목록을 나타냅니다.
|
||||
(defn hello [name]
|
||||
(str "Hello " name))
|
||||
(hello "Steve") ; => "Hello Steve"
|
||||
|
||||
; 약자(shorthand)를 써서 함수를 만들 수 도 있습니다:
|
||||
(def hello2 #(str "Hello " %1))
|
||||
(hello2 "Fanny") ; => "Hello Fanny"
|
||||
|
||||
; 함수가 다양한 인자를 받도록 정의할 수 도 있습니다.
|
||||
(defn hello3
|
||||
([] "Hello World")
|
||||
([name] (str "Hello " name)))
|
||||
(hello3 "Jake") ; => "Hello Jake"
|
||||
(hello3) ; => "Hello World"
|
||||
|
||||
; 함수는 여러 인자를 시퀀스로 취할 수 있습니다.
|
||||
(defn count-args [& args]
|
||||
(str "You passed " (count args) " args: " args))
|
||||
(count-args 1 2 3) ; => "You passed 3 args: (1 2 3)"
|
||||
|
||||
; 개별적으로 받는 것과, 시퀀스로 취하는 것을 같이 쓸 수 도 있습니다.
|
||||
(defn hello-count [name & args]
|
||||
(str "Hello " name ", you passed " (count args) " extra args"))
|
||||
(hello-count "Finn" 1 2 3)
|
||||
; => "Hello Finn, you passed 3 extra args"
|
||||
|
||||
|
||||
; 맵(Maps)
|
||||
;;;;;;;;;;
|
||||
|
||||
; 해쉬맵(hash map)과 배열맵(array map)은 공통된 인터페이스를 공유합니다.
|
||||
; 해쉬맵은 찾기가 빠르지만, 키의 순서가 유지되지 않습니다.
|
||||
(class {:a 1 :b 2 :c 3}) ; => clojure.lang.PersistentArrayMap
|
||||
(class (hash-map :a 1 :b 2 :c 3)) ; => clojure.lang.PersistentHashMap
|
||||
|
||||
; 배열맵은 여러 연산을 거쳐 자연스레 해쉬맵이 됩니다.
|
||||
; 만일 이게 커진다 하더라도, 걱정할 필요가 없습니다.
|
||||
|
||||
; 맵은 해쉬가 가능한 타입이라면 어떠한 것이든 키로써 활용이 가능하지만, 보통 키워드를 이용하는 것이 가장 좋습니다.
|
||||
; 키워드(Keyword)는 문자열과 비슷하지만, 보다 효율적인 면이 있습니다.
|
||||
(class :a) ; => clojure.lang.Keyword
|
||||
|
||||
(def stringmap {"a" 1, "b" 2, "c" 3})
|
||||
stringmap ; => {"a" 1, "b" 2, "c" 3}
|
||||
|
||||
(def keymap {:a 1, :b 2, :c 3})
|
||||
keymap ; => {:a 1, :c 3, :b 2}
|
||||
|
||||
; 여기서, 쉽표가 공백으로 취급되며, 아무 일도 하지 않는다는 것을 주목하시기 바랍니다.
|
||||
|
||||
; 맵에서 값을 얻어오기 위해선, 함수로써 맵을 호출해야 합니다.
|
||||
(stringmap "a") ; => 1
|
||||
(keymap :a) ; => 1
|
||||
|
||||
; 키워드 역시 맵에서 함수를 얻어올 때 사용할 수 있습니다!
|
||||
(:b keymap) ; => 2
|
||||
|
||||
; 하지만, 문자열로는 하면 안됩니다.
|
||||
;("a" stringmap)
|
||||
; => Exception: java.lang.String cannot be cast to clojure.lang.IFn
|
||||
|
||||
; 없는 값을 얻어오고자 하면, nil이 반환됩니다.
|
||||
(stringmap "d") ; => nil
|
||||
|
||||
; assoc 를 이용하여 해쉬맵에 새로운 키를 추가할 수 있습니다.
|
||||
(def newkeymap (assoc keymap :d 4))
|
||||
newkeymap ; => {:a 1, :b 2, :c 3, :d 4}
|
||||
|
||||
; 하지만, 변경할 수 없는(immutable) clojure 타입이라는 것을 기억해야 합니다!
|
||||
keymap ; => {:a 1, :b 2, :c 3}
|
||||
|
||||
; dissoc 를 이용하여 키를 제거할 수 있습니다.
|
||||
(dissoc keymap :a :b) ; => {:c 3}
|
||||
|
||||
; 쎗(Set:집합)
|
||||
;;;;;;
|
||||
|
||||
(class #{1 2 3}) ; => clojure.lang.PersistentHashSet
|
||||
(set [1 2 3 1 2 3 3 2 1 3 2 1]) ; => #{1 2 3}
|
||||
|
||||
; conj 로 항목을 추가할 수 있습니다.
|
||||
(conj #{1 2 3} 4) ; => #{1 2 3 4}
|
||||
|
||||
; disj 로 제거할 수 도 있습니다.
|
||||
(disj #{1 2 3} 1) ; => #{2 3}
|
||||
|
||||
; 존재하는지 확인할 목적으로, 쎗을 함수로 사용할 수 도 있습니다.
|
||||
(#{1 2 3} 1) ; => 1
|
||||
(#{1 2 3} 4) ; => nil
|
||||
|
||||
; clojure.sets 네임스페이스(namespace)에는 더 많은 함수들이 있습니다.
|
||||
|
||||
; 유용한 폼(forms)
|
||||
;;;;;;;;;;;;;;;;;
|
||||
|
||||
; clojure에선, if 와 매크로(macro)를 가지고,
|
||||
; 다른 여러 논리 연산들을 만들 수 있습니다.
|
||||
(if false "a" "b") ; => "b"
|
||||
(if false "a") ; => nil
|
||||
|
||||
; let 을 이용하여 임시적으로 바인딩(binding)을 구축할 수 있습니다.
|
||||
(let [a 1 b 2]
|
||||
(> a b)) ; => false
|
||||
|
||||
; do 로 문단을 묶을 수 도 있습니다.
|
||||
(do
|
||||
(print "Hello")
|
||||
"World") ; => "World" (prints "Hello")
|
||||
|
||||
; 함수는 암시적으로 do 를 가지고 있습니다.
|
||||
(defn print-and-say-hello [name]
|
||||
(print "Saying hello to " name)
|
||||
(str "Hello " name))
|
||||
(print-and-say-hello "Jeff") ;=> "Hello Jeff" (prints "Saying hello to Jeff")
|
||||
|
||||
; let 역시 그러합니다.
|
||||
(let [name "Urkel"]
|
||||
(print "Saying hello to " name)
|
||||
(str "Hello " name)) ; => "Hello Urkel" (prints "Saying hello to Urkel")
|
||||
|
||||
; 모듈(Modules)
|
||||
;;;;;;;;;;;;;;;
|
||||
|
||||
; "use" 를 이용하여 module에 있는 모든 함수들을 얻어올 수 있습니다.
|
||||
(use 'clojure.set)
|
||||
|
||||
; 이제 쎗(set:집합)연산을 사용 할 수 있습니다.
|
||||
(intersection #{1 2 3} #{2 3 4}) ; => #{2 3}
|
||||
(difference #{1 2 3} #{2 3 4}) ; => #{1}
|
||||
|
||||
; 함수들 중에 일 부분만을 가져올 수 도 있습니다.
|
||||
(use '[clojure.set :only [intersection]])
|
||||
|
||||
; require 를 이용하여 모듈을 import할 수 있습니다.
|
||||
(require 'clojure.string)
|
||||
|
||||
; / 를 이용하여 모듈에 있는 함수를 호출 할 수 있습니다.
|
||||
; 여기, clojure.string 라는 모듈에, blank? 라는 함수가 있습니다.
|
||||
(clojure.string/blank? "") ; => true
|
||||
|
||||
; import시, 모듈에 짧은 이름을 붙여줄 수 있습니다.
|
||||
(require '[clojure.string :as str])
|
||||
(str/replace "This is a test." #"[a-o]" str/upper-case) ; => "THIs Is A tEst."
|
||||
; (#"" denotes a regular expression literal)
|
||||
|
||||
; :require 를 이용하여, 네임스페이스에서 require 를 사용할 수 있습니다.
|
||||
; 아레와 같은 방법을 이용하면, 모듈을 quote하지 않아도 됩니다.
|
||||
(ns test
|
||||
(:require
|
||||
[clojure.string :as str]
|
||||
[clojure.set :as set]))
|
||||
|
||||
; Java
|
||||
;;;;;;;;;;;;;;;;;
|
||||
|
||||
; Java는 유용한 많은 표준 라이브러리를 가지고 있으며,
|
||||
; 이를 어떻게 활용할 수 있는지 알아보도록 하겠습니다.
|
||||
|
||||
; import 로 java 모듈을 불러올 수 있습니다.
|
||||
(import java.util.Date)
|
||||
|
||||
; ns 와 함께 import 를 할 수 도 있습니다.
|
||||
(ns test
|
||||
(:import java.util.Date
|
||||
java.util.Calendar))
|
||||
|
||||
; 새로운 인스턴스를 만들기 위해선, 클래스 이름 끝에 "."을 찍습니다.
|
||||
(Date.) ; <a date object>
|
||||
|
||||
; . 을 이용하여 메소드를 호출할 수 있습니다.
|
||||
; 아니면, 줄여서 ".메소드"로도 호출 할 수 있습니다.
|
||||
(. (Date.) getTime) ; <a timestamp>
|
||||
(.getTime (Date.)) ; exactly the same thing.
|
||||
|
||||
; / 를 이용하여 정적메소드를 호출 할 수 있습니다.
|
||||
(System/currentTimeMillis) ; <a timestamp> (system is always present)
|
||||
|
||||
; doto 를 이용하여 상태가 변하는(mutable) 클래스들을 좀 더 편하게(tolerable) 다룰 수 있습니다.
|
||||
(import java.util.Calendar)
|
||||
(doto (Calendar/getInstance)
|
||||
(.set 2000 1 1 0 0 0)
|
||||
.getTime) ; => A Date. set to 2000-01-01 00:00:00
|
||||
|
||||
; STM
|
||||
;;;;;;;;;;;;;;;;;
|
||||
|
||||
; Software Transactional Memory 는 clojure가 영구적인(persistent) 상태를 다루는 방식입니다.
|
||||
; clojure가 이용하는 몇몇 자료형(construct)이 있습니다.
|
||||
|
||||
; 가장 단순한 것은 atom 입니다. 초기 값을 넣어보도록 하겠습니다.
|
||||
(def my-atom (atom {}))
|
||||
|
||||
; swap! 으로 atom을 갱신(update)할 수 있습니다!
|
||||
; swap! 은 함수를 인자로 받아, 그 함수에 대해 현재 atom에 들어있는 값을 첫번째 인자로,
|
||||
; 나머지를 두번째 인자로 하여 호출합니다.
|
||||
(swap! my-atom assoc :a 1) ; Sets my-atom to the result of (assoc {} :a 1)
|
||||
(swap! my-atom assoc :b 2) ; Sets my-atom to the result of (assoc {:a 1} :b 2)
|
||||
|
||||
; '@' 를 이용하여 atom을 역참조(dereference)하여 값을 얻을 수 있습니다.
|
||||
my-atom ;=> Atom<#...> (atom 객체가 반환됩니다.)
|
||||
@my-atom ; => {:a 1 :b 2}
|
||||
|
||||
; 여기 atom을 이용한 단순한 카운터가 있습니다.
|
||||
(def counter (atom 0))
|
||||
(defn inc-counter []
|
||||
(swap! counter inc))
|
||||
|
||||
(inc-counter)
|
||||
(inc-counter)
|
||||
(inc-counter)
|
||||
(inc-counter)
|
||||
(inc-counter)
|
||||
|
||||
@counter ; => 5
|
||||
|
||||
; STM을 구성하는 다른 것들에는 ref 와 agent 가 있습니다.
|
||||
; Refs: http://clojure.org/refs
|
||||
; Agents: http://clojure.org/agents
|
||||
```
|
||||
|
||||
### 읽어볼거리
|
||||
|
||||
부족한 것이 많았지만, 다행히도 채울 수 있는 것들이 많이 있습니다.
|
||||
|
||||
Clojure.org에 많은 문서들이 보관되어 있습니다:
|
||||
[http://clojure.org/](http://clojure.org/)
|
||||
|
||||
Clojuredocs.org는 core 함수들에 대해 다양한 예제와 문서를 보유하고 있습니다:
|
||||
[http://clojuredocs.org/quickref/Clojure%20Core](http://clojuredocs.org/quickref/Clojure%20Core)
|
||||
|
||||
4Clojure는 clojure/FP 스킬을 올릴 수 있는 좋은 길입니다:
|
||||
[http://www.4clojure.com/](http://www.4clojure.com/)
|
||||
|
||||
Clojure-doc.org는 많고 많은 문서들을 보유하고 있습니다:
|
||||
[http://clojure-doc.org/](http://clojure-doc.org/)
|
58
ko-kr/coffeescript-kr.html.markdown
Normal file
58
ko-kr/coffeescript-kr.html.markdown
Normal file
@ -0,0 +1,58 @@
|
||||
---
|
||||
language: coffeescript
|
||||
category: language
|
||||
contributors:
|
||||
- ["Tenor Biel", "http://github.com/L8D"]
|
||||
filename: coffeescript.coffee
|
||||
translators:
|
||||
- ["wikibook", "http://wikibook.co.kr"]
|
||||
lang: ko-kr
|
||||
---
|
||||
|
||||
``` coffeescript
|
||||
# 커피스크립트(CoffeeScript)는 최신 유행을 따르는 언어입니다.
|
||||
# 커피스크립트는 여러 현대 언어의 트렌드를 따르는데,
|
||||
# 그래서 주석을 작성할 때는 루비나 파이썬과 같이 해시를 씁니다.
|
||||
|
||||
###
|
||||
블록 주석은 이처럼 작성하며, 자바스크립트 코드로 만들어지도록
|
||||
'/ *'와 '* /'로 직접적으로 변환됩니다.
|
||||
|
||||
계속하기에 앞서 자바스크립트 시맨틱을 대부분 이해하고 있어야 합니다.
|
||||
###
|
||||
|
||||
# 할당:
|
||||
number = 42 #=> var number = 42;
|
||||
opposite = true #=> var opposite = true;
|
||||
|
||||
# 조건문:
|
||||
number = -42 if opposite #=> if(opposite) { number = -42; }
|
||||
|
||||
# 함수:
|
||||
square = (x) -> x * x #=> var square = function(x) { return x * x; }
|
||||
|
||||
# 범위:
|
||||
list = [1..5] #=> var list = [1, 2, 3, 4, 5];
|
||||
|
||||
# 객체:
|
||||
math =
|
||||
root: Math.sqrt
|
||||
square: square
|
||||
cube: (x) -> x * square x
|
||||
#=> var math = {
|
||||
# "root": Math.sqrt,
|
||||
# "square": square,
|
||||
# "cube": function(x) { return x * square(x); }
|
||||
#}
|
||||
|
||||
# 가변 인자(splat):
|
||||
race = (winner, runners...) ->
|
||||
print winner, runners
|
||||
|
||||
# 존재 여부 확인:
|
||||
alert "I knew it!" if elvis?
|
||||
#=> if(typeof elvis !== "undefined" && elvis !== null) { alert("I knew it!"); }
|
||||
|
||||
# 배열 조건 제시법(comprehensions):
|
||||
cubes = (math.cube num for num in list) #=> ...
|
||||
```
|
@ -169,7 +169,7 @@ public class LearnJava {
|
||||
System.out.println(--i); //i = 0. 전치 감소 연산
|
||||
|
||||
///////////////////////////////////////
|
||||
// 에저 구조
|
||||
// 제어 구조
|
||||
///////////////////////////////////////
|
||||
System.out.println("\n->Control Structures");
|
||||
|
||||
@ -255,7 +255,7 @@ public class LearnJava {
|
||||
// String
|
||||
|
||||
// 형변환
|
||||
// 자바 객채 또한 형변환할 수 있으며, 이와 관련해서 알아야 할 세부사항이
|
||||
// 자바 객체 또한 형변환할 수 있으며, 이와 관련해서 알아야 할 세부사항이
|
||||
// 많을뿐더러 다소 중급 수준에 해당하는 개념들도 다뤄야 합니다.
|
||||
// 이와 관련된 사항은 아래 링크를 참고하세요.
|
||||
// http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html
|
||||
|
@ -1,4 +1,4 @@
|
||||
---
|
||||
---
|
||||
language: lua
|
||||
category: language
|
||||
contributors:
|
||||
@ -361,9 +361,6 @@ local mod = require('mod') -- mod.lua 파일을 실행
|
||||
|
||||
-- require는 모듈을 포함시키는 표준화된 방법입니다.
|
||||
-- require는 다음과 같이 동작합니다: (캐싱돼 있지 않을 경우. 하단 참조)
|
||||
local mod = (function ()
|
||||
<mod.lua의 내용>
|
||||
end)()
|
||||
-- mod.lua가 함수의 본문처럼 되므로 mod.lua 안의 지역 멤버는
|
||||
-- 밖에서 볼 수 없습니다.
|
||||
|
||||
|
662
ko-kr/php-kr.html.markdown
Normal file
662
ko-kr/php-kr.html.markdown
Normal file
@ -0,0 +1,662 @@
|
||||
---
|
||||
language: php
|
||||
category: language
|
||||
contributors:
|
||||
- ["Malcolm Fell", "http://emarref.net/"]
|
||||
- ["Trismegiste", "https://github.com/Trismegiste"]
|
||||
filename: learnphp.php
|
||||
translators:
|
||||
- ["wikibook", "http://wikibook.co.kr"]
|
||||
lang: ko-kr
|
||||
---
|
||||
|
||||
이 문서에서는 PHP 5+를 설명합니다.
|
||||
|
||||
|
||||
```php
|
||||
<?php // PHP 코드는 반드시 <?php 태그로 감싸야 합니다.
|
||||
|
||||
// php 파일에 PHP 코드만 들어 있다면 닫는 태그를 생략하는 것이 관례입니다.
|
||||
|
||||
// 슬래시 두 개는 한 줄 주석을 의미합니다.
|
||||
|
||||
# 해시(파운드 기호로도 알려진)도 같은 역할을 하지만 //이 더 일반적으로 쓰입니다.
|
||||
|
||||
/*
|
||||
텍스트를 슬래시-별표와 별표-슬래시로 감싸면
|
||||
여러 줄 주석이 만들어집니다.
|
||||
*/
|
||||
|
||||
// 출력결과를 표시하려면 "echo"나 "print"를 사용합니다.
|
||||
print('Hello '); // 줄바꿈 없이 "Hello "를 출력합니다.
|
||||
|
||||
// ()는 print와 echo를 사용할 때 선택적으로 사용할 수 있습니다.
|
||||
echo "World\n"; // "World"를 출력한 후 줄바꿈합니다.
|
||||
// (모든 구문은 반드시 세미콜론으로 끝나야 합니다.)
|
||||
|
||||
// <?php 태그 밖의 내용은 모두 자동으로 출력됩니다.
|
||||
?>
|
||||
Hello World Again!
|
||||
<?php
|
||||
|
||||
|
||||
/************************************
|
||||
* 타입과 변수
|
||||
*/
|
||||
|
||||
// 변수명은 $ 기호로 시작합니다.
|
||||
// 유효한 변수명은 문자나 밑줄(_)로 시작하고,
|
||||
// 이어서 임의 개수의 숫자나 문자, 밑줄이 옵니다.
|
||||
|
||||
// 불린값은 대소문자를 구분합니다.
|
||||
$boolean = true; // 또는 TRUE나 True
|
||||
$boolean = false; // 또는 FALSE나 False
|
||||
|
||||
// Integer
|
||||
$int1 = 12; // => 12
|
||||
$int2 = -12; // => -12
|
||||
$int3 = 012; // => 10 (a leading 0 denotes an octal number)
|
||||
$int4 = 0x0F; // => 15 (a leading 0x denotes a hex literal)
|
||||
|
||||
// Float (doubles로도 알려짐)
|
||||
$float = 1.234;
|
||||
$float = 1.2e3;
|
||||
$float = 7E-10;
|
||||
|
||||
// 산술 연산
|
||||
$sum = 1 + 1; // 2
|
||||
$difference = 2 - 1; // 1
|
||||
$product = 2 * 2; // 4
|
||||
$quotient = 2 / 1; // 2
|
||||
|
||||
// 축약형 산술 연산
|
||||
$number = 0;
|
||||
$number += 1; // $number를 1만큼 증가
|
||||
echo $number++; // 1을 출력(평가 후 증가)
|
||||
echo ++$number; // 3 (평가 전 증가)
|
||||
$number /= $float; // 나눗셈 후 몫을 $number에 할당
|
||||
|
||||
// 문자열은 작은따옴표로 감싸야 합니다.
|
||||
$sgl_quotes = '$String'; // => '$String'
|
||||
|
||||
// 다른 변수를 포함할 때를 제외하면 큰따옴표 사용을 자제합니다.
|
||||
$dbl_quotes = "This is a $sgl_quotes."; // => 'This is a $String.'
|
||||
|
||||
// 특수 문자는 큰따옴표에서만 이스케이프됩니다.
|
||||
$escaped = "This contains a \t tab character.";
|
||||
$unescaped = 'This just contains a slash and a t: \t';
|
||||
|
||||
// 필요할 경우 변수를 중괄호로 감쌉니다.
|
||||
$money = "I have $${number} in the bank.";
|
||||
|
||||
// PHP 5.3부터는 여러 줄 문자열을 생성하는 데 나우닥(nowdoc)을 사용할 수 있습니다.
|
||||
$nowdoc = <<<'END'
|
||||
Multi line
|
||||
string
|
||||
END;
|
||||
|
||||
// 히어닥(heredoc)에서는 문자열 치환을 지원합니다.
|
||||
$heredoc = <<<END
|
||||
Multi line
|
||||
$sgl_quotes
|
||||
END;
|
||||
|
||||
// 문자열을 연결할 때는 .을 이용합니다.
|
||||
echo 'This string ' . 'is concatenated';
|
||||
|
||||
|
||||
/********************************
|
||||
* 상수
|
||||
*/
|
||||
|
||||
// 상수는 define()을 이용해 정의되며,
|
||||
// 런타임 동안 절대 변경될 수 없습니다!
|
||||
|
||||
// 유효한 상수명은 문자나 밑줄로 시작하고,
|
||||
// 이어서 임의 개수의 숫자나 문자, 밑줄이 옵니다.
|
||||
define("FOO", "something");
|
||||
|
||||
// 상수명을 이용해 직접 상수에 접근할 수 있습니다.
|
||||
echo 'This outputs '.FOO;
|
||||
|
||||
|
||||
/********************************
|
||||
* 배열
|
||||
*/
|
||||
|
||||
// PHP의 모든 배열은 연관 배열(associative array, 해시맵)입니다.
|
||||
|
||||
// 일부 언어에서 해시맵으로도 알려진 연관 배열은
|
||||
|
||||
// 모든 PHP 버전에서 동작합니다.
|
||||
$associative = array('One' => 1, 'Two' => 2, 'Three' => 3);
|
||||
|
||||
// PHP 5.4에서는 새로운 문법이 도입됐습니다.
|
||||
$associative = ['One' => 1, 'Two' => 2, 'Three' => 3];
|
||||
|
||||
echo $associative['One']; // 1을 출력
|
||||
|
||||
// 리스트 리터럴은 암시적으로 정수형 키를 할당합니다.
|
||||
$array = ['One', 'Two', 'Three'];
|
||||
echo $array[0]; // => "One"
|
||||
|
||||
|
||||
/********************************
|
||||
* 출력
|
||||
*/
|
||||
|
||||
echo('Hello World!');
|
||||
// 표준출력(stdout)에 Hello World!를 출력합니다.
|
||||
// 브라우저에서 실행할 경우 표준출력은 웹 페이지입니다.
|
||||
|
||||
print('Hello World!'); // echo과 동일
|
||||
|
||||
// echo는 실제로 언어 구성물에 해당하므로, 괄호를 생략할 수 있습니다.
|
||||
echo 'Hello World!';
|
||||
print 'Hello World!'; // 똑같이 출력됩니다.
|
||||
|
||||
$paragraph = 'paragraph';
|
||||
|
||||
echo 100; // 스칼라 변수는 곧바로 출력합니다.
|
||||
echo $paragraph; // 또는 변수의 값을 출력합니다.
|
||||
|
||||
// 축약형 여는 태그를 설정하거나 PHP 버전이 5.4.0 이상이면
|
||||
// 축약된 echo 문법을 사용할 수 있습니다.
|
||||
?>
|
||||
<p><?= $paragraph ?></p>
|
||||
<?php
|
||||
|
||||
$x = 1;
|
||||
$y = 2;
|
||||
$x = $y; // 이제 $x의 값은 $y의 값과 같습니다.
|
||||
$z = &$y;
|
||||
// $z는 이제 $y에 대한 참조를 담고 있습니다. $z의 값을 변경하면
|
||||
// $y의 값도 함께 변경되며, 그 반대도 마찬가지입니다.
|
||||
// $x는 $y의 원래 값을 그대로 유지합니다.
|
||||
|
||||
echo $x; // => 2
|
||||
echo $z; // => 2
|
||||
$y = 0;
|
||||
echo $x; // => 2
|
||||
echo $z; // => 0
|
||||
|
||||
|
||||
/********************************
|
||||
* 로직
|
||||
*/
|
||||
$a = 0;
|
||||
$b = '0';
|
||||
$c = '1';
|
||||
$d = '1';
|
||||
|
||||
// assert는 인자가 참이 아닌 경우 경고를 출력합니다.
|
||||
|
||||
// 다음과 같은 비교는 항상 참이며, 타입이 같지 않더라도 마찬가지입니다.
|
||||
assert($a == $b); // 동일성 검사
|
||||
assert($c != $a); // 불일치성 검사
|
||||
assert($c <> $a); // 또 다른 불일치성 검사
|
||||
assert($a < $c);
|
||||
assert($c > $b);
|
||||
assert($a <= $b);
|
||||
assert($c >= $d);
|
||||
|
||||
// 다음과 같은 코드는 값과 타입이 모두 일치하는 경우에만 참입니다.
|
||||
assert($c === $d);
|
||||
assert($a !== $d);
|
||||
assert(1 == '1');
|
||||
assert(1 !== '1');
|
||||
|
||||
// 변수는 어떻게 사용하느냐 따라 다른 타입으로 변환될 수 있습니다.
|
||||
|
||||
$integer = 1;
|
||||
echo $integer + $integer; // => 2
|
||||
|
||||
$string = '1';
|
||||
echo $string + $string; // => 2 (문자열이 강제로 정수로 변환됩니다)
|
||||
|
||||
$string = 'one';
|
||||
echo $string + $string; // => 0
|
||||
// + 연산자는 'one'이라는 문자열을 숫자로 형변환할 수 없기 때문에 0이 출력됩니다.
|
||||
|
||||
// 한 변수를 다른 타입으로 처리하는 데 형변환을 사용할 수 있습니다.
|
||||
|
||||
$boolean = (boolean) 1; // => true
|
||||
|
||||
$zero = 0;
|
||||
$boolean = (boolean) $zero; // => false
|
||||
|
||||
// 대다수의 타입을 형변환하는 데 사용하는 전용 함수도 있습니다.
|
||||
$integer = 5;
|
||||
$string = strval($integer);
|
||||
|
||||
$var = null; // 널 타입
|
||||
|
||||
|
||||
/********************************
|
||||
* 제어 구조
|
||||
*/
|
||||
|
||||
if (true) {
|
||||
print 'I get printed';
|
||||
}
|
||||
|
||||
if (false) {
|
||||
print 'I don\'t';
|
||||
} else {
|
||||
print 'I get printed';
|
||||
}
|
||||
|
||||
if (false) {
|
||||
print 'Does not get printed';
|
||||
} elseif(true) {
|
||||
print 'Does';
|
||||
}
|
||||
|
||||
// 사항 연산자
|
||||
print (false ? 'Does not get printed' : 'Does');
|
||||
|
||||
$x = 0;
|
||||
if ($x === '0') {
|
||||
print 'Does not print';
|
||||
} elseif($x == '1') {
|
||||
print 'Does not print';
|
||||
} else {
|
||||
print 'Does print';
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 다음과 같은 문법은 템플릿에 유용합니다.
|
||||
?>
|
||||
|
||||
<?php if ($x): ?>
|
||||
This is displayed if the test is truthy.
|
||||
<?php else: ?>
|
||||
This is displayed otherwise.
|
||||
<?php endif; ?>
|
||||
|
||||
<?php
|
||||
|
||||
// 특정 로직을 표현할 때는 switch를 사용합니다.
|
||||
switch ($x) {
|
||||
case '0':
|
||||
print 'Switch does type coercion';
|
||||
break; // break을 반드시 포함해야 하며, break를 생략하면
|
||||
// 'two'와 'three' 케이스로 넘어갑니다.
|
||||
case 'two':
|
||||
case 'three':
|
||||
// 변수가 'two'나 'three'인 경우에 실행될 코드를 작성합니다.
|
||||
break;
|
||||
default:
|
||||
// 기본값으로 실행될 코드를 작성
|
||||
}
|
||||
|
||||
// while과 do...while, for 문이 아마 더 친숙할 것입니다.
|
||||
$i = 0;
|
||||
while ($i < 5) {
|
||||
echo $i++;
|
||||
}; // "01234"를 출력
|
||||
|
||||
echo "\n";
|
||||
|
||||
$i = 0;
|
||||
do {
|
||||
echo $i++;
|
||||
} while ($i < 5); // "01234"를 출력
|
||||
|
||||
echo "\n";
|
||||
|
||||
for ($x = 0; $x < 10; $x++) {
|
||||
echo $x;
|
||||
} // "0123456789"를 출력
|
||||
|
||||
echo "\n";
|
||||
|
||||
$wheels = ['bicycle' => 2, 'car' => 4];
|
||||
|
||||
// foreach 문은 배영를 순회할 수 있습니다.
|
||||
foreach ($wheels as $wheel_count) {
|
||||
echo $wheel_count;
|
||||
} // "24"를 출력
|
||||
|
||||
echo "\n";
|
||||
|
||||
// 키와 값을 동시에 순회할 수 있습니다.
|
||||
foreach ($wheels as $vehicle => $wheel_count) {
|
||||
echo "A $vehicle has $wheel_count wheels";
|
||||
}
|
||||
|
||||
echo "\n";
|
||||
|
||||
$i = 0;
|
||||
while ($i < 5) {
|
||||
if ($i === 3) {
|
||||
break; // while 문을 빠져나옴
|
||||
}
|
||||
echo $i++;
|
||||
} // "012"를 출력
|
||||
|
||||
for ($i = 0; $i < 5; $i++) {
|
||||
if ($i === 3) {
|
||||
continue; // 이번 순회를 생략
|
||||
}
|
||||
echo $i;
|
||||
} // "0124"를 출력
|
||||
|
||||
|
||||
/********************************
|
||||
* 함수
|
||||
*/
|
||||
|
||||
// "function"으로 함수를 정의합니다.
|
||||
function my_function () {
|
||||
return 'Hello';
|
||||
}
|
||||
|
||||
echo my_function(); // => "Hello"
|
||||
|
||||
// 유효한 함수명은 문자나 밑줄로 시작하고, 이어서
|
||||
// 임의 개수의 문자나 숫자, 밑줄이 옵니다.
|
||||
|
||||
function add ($x, $y = 1) { // $y는 선택사항이고 기본값은 1입니다.
|
||||
$result = $x + $y;
|
||||
return $result;
|
||||
}
|
||||
|
||||
echo add(4); // => 5
|
||||
echo add(4, 2); // => 6
|
||||
|
||||
// 함수 밖에서는 $result에 접근할 수 없습니다.
|
||||
// print $result; // 이 코드를 실행하면 경고가 출력됩니다.
|
||||
|
||||
// PHP 5.3부터는 익명 함수를 선언할 수 있습니다.
|
||||
$inc = function ($x) {
|
||||
return $x + 1;
|
||||
};
|
||||
|
||||
echo $inc(2); // => 3
|
||||
|
||||
function foo ($x, $y, $z) {
|
||||
echo "$x - $y - $z";
|
||||
}
|
||||
|
||||
// 함수에서는 함수를 반환할 수 있습니다.
|
||||
function bar ($x, $y) {
|
||||
// 'use'를 이용해 바깥 함수의 변수를 전달합니다.
|
||||
return function ($z) use ($x, $y) {
|
||||
foo($x, $y, $z);
|
||||
};
|
||||
}
|
||||
|
||||
$bar = bar('A', 'B');
|
||||
$bar('C'); // "A - B - C"를 출력
|
||||
|
||||
// 문자열을 이용해 이름이 지정된 함수를 호출할 수 있습니다.
|
||||
$function_name = 'add';
|
||||
echo $function_name(1, 2); // => 3
|
||||
// 프로그램 방식으로 어느 함수를 실행할지 결정할 때 유용합니다.
|
||||
// 아니면 call_user_func(callable $callback [, $parameter [, ... ]]);를 사용해도 됩니다.
|
||||
|
||||
/********************************
|
||||
* 인클루드
|
||||
*/
|
||||
|
||||
<?php
|
||||
// 인클루드된 파일 내의 PHP 코드도 반드시 PHP 여는 태그로 시작해야 합니다.
|
||||
|
||||
include 'my-file.php';
|
||||
// my-file.php 안의 코드는 이제 현재 유효범위에서 이용할 수 있습니다.
|
||||
// 파일을 인클루드할 수 없으면(예: 파일을 찾을 수 없음) 경고가 출력됩니다.
|
||||
|
||||
include_once 'my-file.php';
|
||||
// my-file.php 안의 코드가 다른 곳에 인클루드됐다면 다시 인클루드되지는 않습니다.
|
||||
// 따라서 클래스 선언이 여러 번 되어 발생하는 문제가 일어나지 않습니다.
|
||||
|
||||
require 'my-file.php';
|
||||
require_once 'my-file.php';
|
||||
// require()는 include()와 같지만 파일을 인클루드할 수 없을 경우
|
||||
// 치명적인 오류가 발생한다는 점이 다릅니다.
|
||||
|
||||
// my-include.php의 내용
|
||||
<?php
|
||||
|
||||
return 'Anything you like.';
|
||||
// 파일의 끝
|
||||
|
||||
// include와 require는 값을 반환할 수도 있습니다.
|
||||
$value = include 'my-include.php';
|
||||
|
||||
// 파일은 지정된 파일 경로를 토대로 인클루드되거나, 혹은 아무것도 명시하지 않은 경우
|
||||
// include_path라는 설정 지시지를 따릅니다. include_path에서 파일을 발견할 수 없으면
|
||||
// include는 마지막으로 실패하기 전에 호출 스크립트 자체의 디렉터리와 현재 작업 디렉터리를 확인합니다.
|
||||
/* */
|
||||
|
||||
/********************************
|
||||
* 클래스
|
||||
*/
|
||||
|
||||
// 클래스는 class라는 키워드로 정의합니다.
|
||||
|
||||
class MyClass
|
||||
{
|
||||
const MY_CONST = 'value'; // 상수
|
||||
|
||||
static $staticVar = 'static';
|
||||
|
||||
// 프로퍼티에는 반드시 가시성을 선언해야 합니다.
|
||||
public $property = 'public';
|
||||
public $instanceProp;
|
||||
protected $prot = 'protected'; // 이 클래스와 하위 클래스에서 접근할 수 있음
|
||||
private $priv = 'private'; // 이 클래스 내에서만 접근 가능
|
||||
|
||||
// __construct로 생성자를 만듭니다.
|
||||
public function __construct($instanceProp) {
|
||||
// $this로 인스턴스 변수에 접근합니다.
|
||||
$this->instanceProp = $instanceProp;
|
||||
}
|
||||
|
||||
// 메서드는 클래스 안의 함수로서 선언됩니다.
|
||||
public function myMethod()
|
||||
{
|
||||
print 'MyClass';
|
||||
}
|
||||
|
||||
final function youCannotOverrideMe()
|
||||
{
|
||||
}
|
||||
|
||||
public static function myStaticMethod()
|
||||
{
|
||||
print 'I am static';
|
||||
}
|
||||
}
|
||||
|
||||
echo MyClass::MY_CONST; // 'value' 출력
|
||||
echo MyClass::$staticVar; // 'static' 출력
|
||||
MyClass::myStaticMethod(); // 'I am static' 출력
|
||||
|
||||
// new를 사용해 클래스를 인스턴스화합니다.
|
||||
$my_class = new MyClass('An instance property');
|
||||
// 인자를 전달하지 않을 경우 괄호를 생략할 수 있습니다.
|
||||
|
||||
// ->를 이용해 클래스 멤버에 접근합니다
|
||||
echo $my_class->property; // => "public"
|
||||
echo $my_class->instanceProp; // => "An instance property"
|
||||
$my_class->myMethod(); // => "MyClass"
|
||||
|
||||
|
||||
// "extends"를 이용해 클래스를 확장합니다.
|
||||
class MyOtherClass extends MyClass
|
||||
{
|
||||
function printProtectedProperty()
|
||||
{
|
||||
echo $this->prot;
|
||||
}
|
||||
|
||||
// 메서드 재정의
|
||||
function myMethod()
|
||||
{
|
||||
parent::myMethod();
|
||||
print ' > MyOtherClass';
|
||||
}
|
||||
}
|
||||
|
||||
$my_other_class = new MyOtherClass('Instance prop');
|
||||
$my_other_class->printProtectedProperty(); // => "protected" 출력
|
||||
$my_other_class->myMethod(); // "MyClass > MyOtherClass" 출력
|
||||
|
||||
final class YouCannotExtendMe
|
||||
{
|
||||
}
|
||||
|
||||
// "마법 메서드(magic method)"로 설정자 메서드와 접근자 메서드를 만들 수 있습니다.
|
||||
class MyMapClass
|
||||
{
|
||||
private $property;
|
||||
|
||||
public function __get($key)
|
||||
{
|
||||
return $this->$key;
|
||||
}
|
||||
|
||||
public function __set($key, $value)
|
||||
{
|
||||
$this->$key = $value;
|
||||
}
|
||||
}
|
||||
|
||||
$x = new MyMapClass();
|
||||
echo $x->property; // __get() 메서드를 사용
|
||||
$x->property = 'Something'; // __set() 메서드를 사용
|
||||
|
||||
// 클래스는 추상화하거나(abstract 키워드를 사용해)
|
||||
// 인터페이스를 구현할 수 있습니다(implments 키워드를 사용해).
|
||||
// 인터페이스는 interface 키워드로 선언합니다.
|
||||
|
||||
interface InterfaceOne
|
||||
{
|
||||
public function doSomething();
|
||||
}
|
||||
|
||||
interface InterfaceTwo
|
||||
{
|
||||
public function doSomethingElse();
|
||||
}
|
||||
|
||||
// 인터페이스는 확장할 수 있습니다.
|
||||
interface InterfaceThree extends InterfaceTwo
|
||||
{
|
||||
public function doAnotherContract();
|
||||
}
|
||||
|
||||
abstract class MyAbstractClass implements InterfaceOne
|
||||
{
|
||||
public $x = 'doSomething';
|
||||
}
|
||||
|
||||
class MyConcreteClass extends MyAbstractClass implements InterfaceTwo
|
||||
{
|
||||
public function doSomething()
|
||||
{
|
||||
echo $x;
|
||||
}
|
||||
|
||||
public function doSomethingElse()
|
||||
{
|
||||
echo 'doSomethingElse';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 클래스에서는 하나 이상의 인터페이스를 구현할 수 있습니다.
|
||||
class SomeOtherClass implements InterfaceOne, InterfaceTwo
|
||||
{
|
||||
public function doSomething()
|
||||
{
|
||||
echo 'doSomething';
|
||||
}
|
||||
|
||||
public function doSomethingElse()
|
||||
{
|
||||
echo 'doSomethingElse';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/********************************
|
||||
* 특성
|
||||
*/
|
||||
|
||||
// 특성(trait)은 PHP 5.4.0부터 사용 가능하며, "trait"으로 선언합니다.
|
||||
|
||||
trait MyTrait
|
||||
{
|
||||
public function myTraitMethod()
|
||||
{
|
||||
print 'I have MyTrait';
|
||||
}
|
||||
}
|
||||
|
||||
class MyTraitfulClass
|
||||
{
|
||||
use MyTrait;
|
||||
}
|
||||
|
||||
$cls = new MyTraitfulClass();
|
||||
$cls->myTraitMethod(); // "I have MyTrait"을 출력
|
||||
|
||||
|
||||
/********************************
|
||||
* 네임스페이스
|
||||
*/
|
||||
|
||||
// 이 부분은 별도의 영역인데, 파일에서 처음으로 나타나는 문장은
|
||||
// 네임스페이스 선언이어야 하기 때문입니다. 여기서는 그런 경우가 아니라고 가정합니다.
|
||||
|
||||
<?php
|
||||
|
||||
// 기본적으로 클래스는 전역 네임스페이스에 존재하며,
|
||||
// 백슬래시를 이용해 명시적으로 호출할 수 있습니다.
|
||||
|
||||
$cls = new \MyClass();
|
||||
|
||||
|
||||
|
||||
// 파일에 대한 네임스페이스를 설정합니다.
|
||||
namespace My\Namespace;
|
||||
|
||||
class MyClass
|
||||
{
|
||||
}
|
||||
|
||||
// (다른 파일에 들어 있는 코드)
|
||||
$cls = new My\Namespace\MyClass;
|
||||
|
||||
// 또는 다른 네임스페이스 내에서 접근하는 경우
|
||||
namespace My\Other\Namespace;
|
||||
|
||||
use My\Namespace\MyClass;
|
||||
|
||||
$cls = new MyClass();
|
||||
|
||||
// 혹은 네임스페이스에 별칭을 붙일 수도 있습니다.
|
||||
|
||||
namespace My\Other\Namespace;
|
||||
|
||||
use My\Namespace as SomeOtherNamespace;
|
||||
|
||||
$cls = new SomeOtherNamespace\MyClass();
|
||||
|
||||
*/
|
||||
|
||||
```
|
||||
|
||||
## 더 자세한 정보
|
||||
|
||||
레퍼런스와 커뮤니티 관련 내용은 [공식 PHP 문서](http://www.php.net/manual/)를 참고하세요.
|
||||
|
||||
최신 모범 사례에 관심이 있다면 [PHP The Right Way](http://www.phptherightway.com/)를 참고하세요.
|
||||
|
||||
PHP를 익히기 전에 다른 훌륭한 패키지 관리자를 지원하는 언어를 사용해본 적이 있다면 [컴포저(Composer)](http://getcomposer.org/)를 확인해 보세요.
|
||||
|
||||
공통 표준이 궁금하다면 PHP 프레임워크 상호운용성 그룹의 [PSR 표준](https://github.com/php-fig/fig-standards)을 참고하세요.
|
@ -3,7 +3,7 @@ language: python
|
||||
category: language
|
||||
contributors:
|
||||
- ["Louie Dinh", "http://ldinh.ca"]
|
||||
filename: learnpython.py
|
||||
filename: learnpython-ko.py
|
||||
translators:
|
||||
- ["wikibook", "http://wikibook.co.kr"]
|
||||
lang: ko-kr
|
||||
@ -481,4 +481,4 @@ dir(math)
|
||||
|
||||
* [Programming Python](http://www.amazon.com/gp/product/0596158106/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596158106&linkCode=as2&tag=homebits04-20)
|
||||
* [Dive Into Python](http://www.amazon.com/gp/product/1441413022/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1441413022&linkCode=as2&tag=homebits04-20)
|
||||
* [Python Essential Reference](http://www.amazon.com/gp/product/0672329786/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0672329786&linkCode=as2&tag=homebits04-20)
|
||||
* [Python Essential Reference](http://www.amazon.com/gp/product/0672329786/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0672329786&linkCode=as2&tag=homebits04-20)
|
||||
|
@ -135,11 +135,19 @@ funRE = //
|
||||
3 % 2 # => 1
|
||||
|
||||
|
||||
# Comparisons are mostly the same too, except that `==` and `===` are
|
||||
# inverted.
|
||||
# Comparisons are mostly the same too, except that `==` is the same as
|
||||
# JS's `===`, where JS's `==` in LiveScript is `~=`, and `===` enables
|
||||
# object and array comparisons, and also stricter comparisons:
|
||||
2 == 2 # => true
|
||||
2 == "2" # => false
|
||||
2 === "2" # => true
|
||||
2 ~= "2" # => true
|
||||
2 === "2" # => false
|
||||
|
||||
[1,2,3] == [1,2,3] # => false
|
||||
[1,2,3] === [1,2,3] # => true
|
||||
|
||||
+0 == -0 # => true
|
||||
+0 === -0 # => false
|
||||
|
||||
# Other relational operators include <, <=, > and >=
|
||||
|
||||
|
@ -125,6 +125,9 @@ f = function (x) return x * x end
|
||||
|
||||
-- And so are these:
|
||||
local function g(x) return math.sin(x) end
|
||||
local g = function(x) return math.sin(x) end
|
||||
-- Equivalent to local function g(x)..., except referring
|
||||
-- to g in the function body won't work as expected.
|
||||
local g; g = function (x) return math.sin(x) end
|
||||
-- the 'local g' decl makes g-self-references ok.
|
||||
|
||||
@ -133,6 +136,10 @@ local g; g = function (x) return math.sin(x) end
|
||||
-- Calls with one string param don't need parens:
|
||||
print 'hello' -- Works fine.
|
||||
|
||||
-- Calls with one table param don't need parens
|
||||
-- either (more on tables below):
|
||||
print {} -- Works fine too.
|
||||
|
||||
|
||||
----------------------------------------------------
|
||||
-- 3. Tables.
|
||||
@ -203,7 +210,7 @@ f2 = {a = 2, b = 3}
|
||||
|
||||
metafraction = {}
|
||||
function metafraction.__add(f1, f2)
|
||||
sum = {}
|
||||
local sum = {}
|
||||
sum.b = f1.b * f2.b
|
||||
sum.a = f1.a * f2.b + f2.a * f1.b
|
||||
return sum
|
||||
@ -266,7 +273,7 @@ eatenBy = myFavs.animal -- works! thanks, metatable
|
||||
Dog = {} -- 1.
|
||||
|
||||
function Dog:new() -- 2.
|
||||
newObj = {sound = 'woof'} -- 3.
|
||||
local newObj = {sound = 'woof'} -- 3.
|
||||
self.__index = self -- 4.
|
||||
return setmetatable(newObj, self) -- 5.
|
||||
end
|
||||
@ -301,7 +308,7 @@ mrDog:makeSound() -- 'I say woof' -- 8.
|
||||
LoudDog = Dog:new() -- 1.
|
||||
|
||||
function LoudDog:makeSound()
|
||||
s = self.sound .. ' ' -- 2.
|
||||
local s = self.sound .. ' ' -- 2.
|
||||
print(s .. s .. s)
|
||||
end
|
||||
|
||||
@ -322,7 +329,7 @@ seymour:makeSound() -- 'woof woof woof' -- 4.
|
||||
|
||||
-- If needed, a subclass's new() is like the base's:
|
||||
function LoudDog:new()
|
||||
newObj = {}
|
||||
local newObj = {}
|
||||
-- set up newObj
|
||||
self.__index = self
|
||||
return setmetatable(newObj, self)
|
||||
|
452
matlab.html.markdown
Normal file
452
matlab.html.markdown
Normal file
@ -0,0 +1,452 @@
|
||||
---
|
||||
language: Matlab
|
||||
contributors:
|
||||
- ["mendozao", "http://github.com/mendozao"]
|
||||
- ["jamesscottbrown", "http://jamesscottbrown.com"]
|
||||
|
||||
---
|
||||
|
||||
MATLAB stands for MATrix LABoratory. It is a powerful numerical computing language commonly used in engineering and mathematics.
|
||||
|
||||
If you have any feedback please feel free to reach me at
|
||||
[@the_ozzinator](https://twitter.com/the_ozzinator), or
|
||||
[osvaldo.t.mendoza@gmail.com](mailto:osvaldo.t.mendoza@gmail.com).
|
||||
|
||||
```matlab
|
||||
% Comments start with a percent sign.
|
||||
|
||||
%{ Multi line comments look
|
||||
something
|
||||
like
|
||||
this %}
|
||||
|
||||
% commands can span multiple lines, using '...':
|
||||
a = 1 + 2 + ...
|
||||
+ 4
|
||||
|
||||
% commands can be passed to the operating system
|
||||
!ping google.com
|
||||
|
||||
who % Displays all variables in memory
|
||||
whos % Displays all variables in memory, with their types
|
||||
clear % Erases all your variables from memory
|
||||
clear('A') % Erases a particular variable
|
||||
openvar('A') % Open variable in variable editor
|
||||
|
||||
clc % Erases the writing on your Command Window
|
||||
diary % Toggle writing Command Window text to file
|
||||
ctrl-c % Abort current computation
|
||||
|
||||
edit('myfunction.m') % Open function/script in editor
|
||||
type('myfunction.m') % Print the source of function/script to Command Window
|
||||
|
||||
profile viewer % Open profiler
|
||||
|
||||
help command % Displays documentation for command in Command Window
|
||||
doc command % Displays documentation for command in Help Window
|
||||
lookfor command % Searches for a given command
|
||||
|
||||
|
||||
% Output formatting
|
||||
format short % 4 decimals in a floating number
|
||||
format long % 15 decimals
|
||||
format bank % only two digits after decimal point - for financial calculations
|
||||
fprintf
|
||||
|
||||
% Variables & Expressions
|
||||
myVariable = 4 % Notice Workspace pane shows newly created variable
|
||||
myVariable = 4; % Semi colon suppresses output to the Command Window
|
||||
4 + 6 % ans = 10
|
||||
8 * myVariable % ans = 32
|
||||
2 ^ 3 % ans = 8
|
||||
a = 2; b = 3;
|
||||
c = exp(a)*sin(pi/2) % c = 7.3891
|
||||
|
||||
% Calling functions can be done in either of two ways:
|
||||
% Standard function syntax:
|
||||
load('myFile.mat', 'y')
|
||||
% Command syntax:
|
||||
load myFile.mat y % no parentheses, and spaces instead of commas
|
||||
% Note the lack of quote marks in command form: inputs are always passed as
|
||||
% literal text - cannot pass variable values. Also, can't receive output:
|
||||
[V,D] = eig(A) % this has no equivalent in command form
|
||||
|
||||
|
||||
|
||||
% Logicals
|
||||
1 > 5 % ans = 0
|
||||
10 >= 10 % ans = 1
|
||||
3 ~= 4 % Not equal to -> ans = 1
|
||||
3 == 3 % equal to -> ans = 1
|
||||
3 > 1 && 4 > 1 % AND -> ans = 1
|
||||
3 > 1 || 4 > 1 % OR -> ans = 1
|
||||
~1 % NOT -> ans = 0
|
||||
|
||||
% Logicals can be applied to matrices:
|
||||
A > 5
|
||||
% for each element, if condition is true, that element is 1 in returned matrix
|
||||
A[ A > 5 ]
|
||||
% returns a vector containing the elements in A for which condition is true
|
||||
|
||||
% Strings
|
||||
a = 'MyString'
|
||||
length(a) % ans = 8
|
||||
a(2) % ans = y
|
||||
[a,a] % ans = MyStringMyString
|
||||
|
||||
|
||||
% Cells
|
||||
a = {'one', 'two', 'three'}
|
||||
a(1) % ans = 'one' - returns a cell
|
||||
char(a(1)) % ans = one - returns a string
|
||||
|
||||
|
||||
% Vectors
|
||||
x = [4 32 53 7 1]
|
||||
x(2) % ans = 32, indices in Matlab start 1, not 0
|
||||
x(2:3) % ans = 32 53
|
||||
x(2:end) % ans = 32 53 7 1
|
||||
|
||||
x = [4; 32; 53; 7; 1] % Column vector
|
||||
|
||||
x = [1:10] % x = 1 2 3 4 5 6 7 8 9 10
|
||||
|
||||
% Matrices
|
||||
A = [1 2 3; 4 5 6; 7 8 9]
|
||||
% Rows are separated by a semicolon; elements are separated with space or comma
|
||||
% A =
|
||||
|
||||
% 1 2 3
|
||||
% 4 5 6
|
||||
% 7 8 9
|
||||
|
||||
A(2,3) % ans = 6, A(row, column)
|
||||
A(6) % ans = 8
|
||||
% (implicitly concatenates columns into vector, then indexes into that)
|
||||
|
||||
|
||||
A(2,3) = 42 % Update row 2 col 3 with 42
|
||||
% A =
|
||||
|
||||
% 1 2 3
|
||||
% 4 5 42
|
||||
% 7 8 9
|
||||
|
||||
A(2:3,2:3) % Creates a new matrix from the old one
|
||||
%ans =
|
||||
|
||||
% 5 42
|
||||
% 8 9
|
||||
|
||||
A(:,1) % All rows in column 1
|
||||
%ans =
|
||||
|
||||
% 1
|
||||
% 4
|
||||
% 7
|
||||
|
||||
A(1,:) % All columns in row 1
|
||||
%ans =
|
||||
|
||||
% 1 2 3
|
||||
|
||||
[A ; A] % Concatenation of matrices (vertically)
|
||||
%ans =
|
||||
|
||||
% 1 2 3
|
||||
% 4 5 42
|
||||
% 7 8 9
|
||||
% 1 2 3
|
||||
% 4 5 42
|
||||
% 7 8 9
|
||||
|
||||
[A , A] % Concatenation of matrices (horizontally)
|
||||
|
||||
%ans =
|
||||
|
||||
% 1 2 3 1 2 3
|
||||
% 4 5 42 4 5 42
|
||||
% 7 8 9 7 8 9
|
||||
|
||||
|
||||
|
||||
A(:, [3 1 2]) % Rearrange the columns of original matrix
|
||||
%ans =
|
||||
|
||||
% 3 1 2
|
||||
% 42 4 5
|
||||
% 9 7 8
|
||||
|
||||
size(A) % ans = 3 3
|
||||
|
||||
A(1, :) =[] % Delete the first row of the matrix
|
||||
|
||||
A' % Hermitian transpose the matrix
|
||||
% (the transpose, followed by taking complex conjugate of each element)
|
||||
transpose(A) % Transpose the matrix, without taking complex conjugate
|
||||
|
||||
|
||||
|
||||
% Element by Element Arithmetic vs. Matrix Arithmetic
|
||||
% On their own, the arithmetic operators act on whole matrices. When preceded
|
||||
% by a period, they act on each element instead. For example:
|
||||
A * B % Matrix multiplication
|
||||
A .* B % Multiple each element in A by its corresponding element in B
|
||||
|
||||
% There are several pairs of functions, where one acts on each element, and
|
||||
% the other (whose name ends in m) acts on the whole matrix.
|
||||
exp(A) % exponentiate each element
|
||||
expm(A) % calculate the matrix exponential
|
||||
sqrt(A) % take the square root of each element
|
||||
sqrtm(A) % find the matrix whose square is A
|
||||
|
||||
|
||||
% Plotting
|
||||
x = 0:.10:2*pi; % Creates a vector that starts at 0 and ends at 2*pi with increments of .1
|
||||
y = sin(x);
|
||||
plot(x,y)
|
||||
xlabel('x axis')
|
||||
ylabel('y axis')
|
||||
title('Plot of y = sin(x)')
|
||||
axis([0 2*pi -1 1]) % x range from 0 to 2*pi, y range from -1 to 1
|
||||
|
||||
plot(x,y1,'-',x,y2,'--',x,y3,':') % For multiple functions on one plot
|
||||
legend('Line 1 label', 'Line 2 label') % Label curves with a legend
|
||||
|
||||
% Alternative method to plot multiple functions in one plot.
|
||||
% while 'hold' is on, commands add to existing graph rather than replacing it
|
||||
plot(x, y)
|
||||
hold on
|
||||
plot(x, z)
|
||||
hold off
|
||||
|
||||
loglog(x, y) % A log-log plot
|
||||
semilogx(x, y) % A plot with logarithmic x-axis
|
||||
semilogy(x, y) % A plot with logarithmic y-axis
|
||||
|
||||
fplot (@(x) x^2, [2,5]) % plot the function x^2 from x=2 to x=5
|
||||
|
||||
grid on % Show grid; turn off with 'grid off'
|
||||
axis square % Makes the current axes region square
|
||||
axis equal % Set aspect ratio so data units are the same in every direction
|
||||
|
||||
scatter(x, y); % Scatter-plot
|
||||
hist(x); % Histogram
|
||||
|
||||
z = sin(x);
|
||||
plot3(x,y,z); % 3D line plot
|
||||
|
||||
pcolor(A) % Heat-map of matrix: plot as grid of rectangles, coloured by value
|
||||
contour(A) % Contour plot of matrix
|
||||
mesh(A) % Plot as a mesh surface
|
||||
|
||||
h = figure % Create new figure object, with handle f
|
||||
figure(h) % Makes the figure corresponding to handle h the current figure
|
||||
close(h) % close figure with handle h
|
||||
close all % close all open figure windows
|
||||
close % close current figure window
|
||||
|
||||
shg % bring an existing graphics window forward, or create new one if needed
|
||||
clf clear % clear current figure window, and reset most figure properties
|
||||
|
||||
% Properties can be set and changed through a figure handle.
|
||||
% You can save a handle to a figure when you create it.
|
||||
% The function gcf returns a handle to the current figure
|
||||
h = plot(x, y); % you can save a handle to a figure when you create it
|
||||
set(h, 'Color', 'r')
|
||||
% 'y' yellow; 'm' magenta, 'c' cyan, 'r' red, 'g' green, 'b' blue, 'w' white, 'k' black
|
||||
set(h, 'LineStyle', '--')
|
||||
% '--' is solid line, '---' dashed, ':' dotted, '-.' dash-dot, 'none' is no line
|
||||
get(h, 'LineStyle')
|
||||
|
||||
|
||||
% The function gca returns a handle to the axes for the current figure
|
||||
set(gca, 'XDir', 'reverse'); % reverse the direction of the x-axis
|
||||
|
||||
% To create a figure that contains several axes in tiled positions, use subplot
|
||||
subplot(2,3,1); % select the first position in a 2-by-3 grid of subplots
|
||||
plot(x1); title('First Plot') % plot something in this position
|
||||
subplot(2,3,2); % select second position in the grid
|
||||
plot(x2); title('Second Plot') % plot something there
|
||||
|
||||
|
||||
% To use functions or scripts, they must be on your path or current directory
|
||||
path % display current path
|
||||
addpath /path/to/dir % add to path
|
||||
rmpath /path/to/dir % remove from path
|
||||
cd /path/to/move/into % change directory
|
||||
|
||||
|
||||
% Variables can be saved to .mat files
|
||||
save('myFileName.mat') % Save the variables in your Workspace
|
||||
load('myFileName.mat') % Load saved variables into Workspace
|
||||
|
||||
% M-file Scripts
|
||||
% A script file is an external file that contains a sequence of statements.
|
||||
% They let you avoid repeatedly typing the same code in the Command Window
|
||||
% Have .m extensions
|
||||
|
||||
% M-file Functions
|
||||
% Like scripts, and have the same .m extension
|
||||
% But can accept input arguments and return an output
|
||||
% Also, they have their own workspace (ie. different variable scope).
|
||||
% Function name should match file name (so save this example as double_input.m).
|
||||
% 'help double_input.m' returns the comments under line beginning function
|
||||
function output = double_input(x)
|
||||
%double_input(x) returns twice the value of x
|
||||
output = 2*x;
|
||||
end
|
||||
double_input(6) % ans = 12
|
||||
|
||||
|
||||
% You can also have subfunctions and nested functions.
|
||||
% Subfunctions are in the same file as the primary function, and can only be
|
||||
% called by functions in the file. Nested functions are defined within another
|
||||
% functions, and have access to both its workspace and their own workspace.
|
||||
|
||||
% If you want to create a function without creating a new file you can use an
|
||||
% anonymous function. Useful when quickly defining a function to pass to
|
||||
% another function (eg. plot with fplot, evaluate an indefinite integral
|
||||
% with quad, find roots with fzero, or find minimum with fminsearch).
|
||||
% Example that returns the square of it's input, assigned to to the handle sqr:
|
||||
sqr = @(x) x.^2;
|
||||
sqr(10) % ans = 100
|
||||
doc function_handle % find out more
|
||||
|
||||
% User input
|
||||
a = input('Enter the value: ')
|
||||
|
||||
% Stops execution of file and gives control to the keyboard: user can examine
|
||||
% or change variables. Type 'return' to continue execution, or 'dbquit' to exit
|
||||
keyboard
|
||||
|
||||
% Reading in data (also xlsread/importdata/imread for excel/CSV/image files)
|
||||
fopen(filename)
|
||||
|
||||
% Output
|
||||
disp(a) % Print out the value of variable a
|
||||
disp('Hello World') % Print out a string
|
||||
fprintf % Print to Command Window with more control
|
||||
|
||||
% Conditional statements (the parentheses are optional, but good style)
|
||||
if (a > 15)
|
||||
disp('Greater than 15')
|
||||
elseif (a == 23)
|
||||
disp('a is 23')
|
||||
else
|
||||
disp('neither condition met')
|
||||
end
|
||||
|
||||
% Looping
|
||||
% NB. looping over elements of a vector/matrix is slow!
|
||||
% Where possible, use functions that act on whole vector/matrix at once
|
||||
for k = 1:5
|
||||
disp(k)
|
||||
end
|
||||
|
||||
k = 0;
|
||||
while (k < 5)
|
||||
k = k + 1;
|
||||
end
|
||||
|
||||
% Timing code execution: 'toc' prints the time since 'tic' was called
|
||||
tic
|
||||
A = rand(1000);
|
||||
A*A*A*A*A*A*A;
|
||||
toc
|
||||
|
||||
% Connecting to a MySQL Database
|
||||
dbname = 'database_name';
|
||||
username = 'root';
|
||||
password = 'root';
|
||||
driver = 'com.mysql.jdbc.Driver';
|
||||
dburl = ['jdbc:mysql://localhost:8889/' dbname];
|
||||
javaclasspath('mysql-connector-java-5.1.xx-bin.jar'); %xx depends on version, download available at http://dev.mysql.com/downloads/connector/j/
|
||||
conn = database(dbname, username, password, driver, dburl);
|
||||
sql = ['SELECT * from table_name where id = 22'] % Example sql statement
|
||||
a = fetch(conn, sql) %a will contain your data
|
||||
|
||||
|
||||
% Common math functions
|
||||
sin(x)
|
||||
cos(x)
|
||||
tan(x)
|
||||
asin(x)
|
||||
acos(x)
|
||||
atan(x)
|
||||
exp(x)
|
||||
sqrt(x)
|
||||
log(x)
|
||||
log10(x)
|
||||
abs(x)
|
||||
min(x)
|
||||
max(x)
|
||||
ceil(x)
|
||||
floor(x)
|
||||
round(x)
|
||||
rem(x)
|
||||
rand % Uniformly distributed pseudorandom numbers
|
||||
randi % Uniformly distributed pseudorandom integers
|
||||
randn % Normally distributed pseudorandom numbers
|
||||
|
||||
% Common constants
|
||||
pi
|
||||
NaN
|
||||
inf
|
||||
|
||||
% Solving matrix equations (if no solution, returns a least squares solution)
|
||||
% The \ and / operators are equivalent to the functions mldivide and mrdivide
|
||||
x=A\b % Solves Ax=b. Faster and more numerically accurate than using inv(A)*b.
|
||||
x=b/A % Solves xA=b
|
||||
|
||||
inv(A) % calculate the inverse matrix
|
||||
pinv(A) % calculate the pseudo-inverse
|
||||
|
||||
% Common matrix functions
|
||||
zeros(m,n) % m x n matrix of 0's
|
||||
ones(m,n) % m x n matrix of 1's
|
||||
diag(A) % Extracts the diagonal elements of a matrix A
|
||||
diag(x) % Construct a matrix with diagonal elements listed in x, and zeroes elsewhere
|
||||
eye(m,n) % Identity matrix
|
||||
linspace(x1, x2, n) % Return n equally spaced points, with min x1 and max x2
|
||||
inv(A) % Inverse of matrix A
|
||||
det(A) % Determinant of A
|
||||
eig(A) % Eigenvalues and eigenvectors of A
|
||||
trace(A) % Trace of matrix - equivalent to sum(diag(A))
|
||||
isempty(A) % Tests if array is empty
|
||||
all(A) % Tests if all elements are nonzero or true
|
||||
any(A) % Tests if any elements are nonzero or true
|
||||
isequal(A, B) % Tests equality of two arrays
|
||||
numel(A) % Number of elements in matrix
|
||||
triu(x) % Returns the upper triangular part of x
|
||||
tril(x) % Returns the lower triangular part of x
|
||||
cross(A,B) % Returns the cross product of the vectors A and B
|
||||
dot(A,B) % Returns scalar product of two vectors (must have the same length)
|
||||
transpose(A) % Returns the transpose of A
|
||||
flipl(A) % Flip matrix left to right
|
||||
|
||||
% Matrix Factorisations
|
||||
[L, U, P] = lu(A) % LU decomposition: PA = LU,L is lower triangular, U is upper triangular, P is permutation matrix
|
||||
[P, D] = eig(A) % eigen-decomposition: AP = PD, P's columns are eigenvectors and D's diagonals are eigenvalues
|
||||
[U,S,V] = svd(X) % SVD: XV = US, U and V are unitary matrices, S has non-negative diagonal elements in decreasing order
|
||||
|
||||
% Common vector functions
|
||||
max % largest component
|
||||
min % smallest component
|
||||
length % length of a vector
|
||||
sort % sort in ascending order
|
||||
sum % sum of elements
|
||||
prod % product of elements
|
||||
mode % modal value
|
||||
median % median value
|
||||
mean % mean value
|
||||
std % standard deviation
|
||||
perms(x) % list all permutations of elements of x
|
||||
|
||||
```
|
||||
|
||||
## More on Matlab
|
||||
|
||||
* The official website [http://http://www.mathworks.com/products/matlab/](http://www.mathworks.com/products/matlab/)
|
||||
* The official MATLAB Answers forum: [http://www.mathworks.com/matlabcentral/answers/](http://www.mathworks.com/matlabcentral/answers/)
|
||||
|
297
neat.html.markdown
Normal file
297
neat.html.markdown
Normal file
@ -0,0 +1,297 @@
|
||||
---
|
||||
language: neat
|
||||
contributors:
|
||||
- ["Feep", "https://github.com/FeepingCreature"]
|
||||
filename: LearnNeat.nt
|
||||
---
|
||||
|
||||
Neat is basically a smaller version of D1 with some experimental syntax and a focus on terseness without losing the basic C-like syntax.
|
||||
|
||||
[Read more here.](https://github.com/FeepingCreature/fcc/wiki)
|
||||
|
||||
```c
|
||||
// single line comments start with //
|
||||
/*
|
||||
multiline comments look like this
|
||||
*/
|
||||
/+
|
||||
or this
|
||||
/+ these can be nested too, same as D +/
|
||||
+/
|
||||
|
||||
// Module name. This has to match the filename/directory.
|
||||
module LearnNeat;
|
||||
|
||||
// Make names from another module visible in this one.
|
||||
import std.file;
|
||||
// You can import multiple things at once.
|
||||
import std.math, std.util;
|
||||
// You can even group up imports!
|
||||
import std.(process, socket);
|
||||
|
||||
// Global functions!
|
||||
void foo() { }
|
||||
|
||||
// Main function, same as in C.
|
||||
// string[] == "array of strings".
|
||||
// "string" is just an alias for char[],
|
||||
void main(string[] args) {
|
||||
// Call functions with "function expression".
|
||||
writeln "Hello World";
|
||||
// You can do it like in C too... if you really want.
|
||||
writeln ("Hello World");
|
||||
// Declare a variable with "type identifier"
|
||||
string arg = ("Hello World");
|
||||
writeln arg;
|
||||
// (expression, expression) forms a tuple.
|
||||
// There are no one-value tuples though.
|
||||
// So you can always use () in the mathematical sense.
|
||||
// (string) arg; <- is an error
|
||||
|
||||
/*
|
||||
byte: 8 bit signed integer
|
||||
char: 8 bit UTF-8 byte component.
|
||||
short: 16 bit signed integer
|
||||
int: 32 bit signed integer
|
||||
long: 64 bit signed integer
|
||||
|
||||
float: 32 bit floating point
|
||||
double: 64 bit floating point
|
||||
real: biggest native size floating point (80 bit on x86).
|
||||
|
||||
bool: true or false
|
||||
*/
|
||||
int a = 5;
|
||||
bool b = true;
|
||||
// as in C, && and || are short-circuit evaluating.
|
||||
b = b && false;
|
||||
assert(b == false);
|
||||
// "" are "format strings". So $variable will be substituted at runtime
|
||||
// with a formatted version of the variable.
|
||||
writeln "$a";
|
||||
// This will just print $a.
|
||||
writeln `$a`;
|
||||
// you can format expressions with $()
|
||||
writeln "$(2+2)";
|
||||
// Note: there is no special syntax for characters.
|
||||
char c = "a";
|
||||
// Cast values by using type: expression.
|
||||
// There are three kinds of casts:
|
||||
// casts that just specify conversions that would be happening automatically
|
||||
// (implicit casts)
|
||||
float f = float:5;
|
||||
float f2 = 5; // would also work
|
||||
// casts that require throwing away information or complicated computation -
|
||||
// those must always be done explicitly
|
||||
// (conversion casts)
|
||||
int i = int:f;
|
||||
// int i = f; // would not work!
|
||||
// and, as a last attempt, casts that just reinterpret the raw data.
|
||||
// Those only work if the types have the same size.
|
||||
string s = "Hello World";
|
||||
// Arrays are (length, pointer) pairs.
|
||||
// This is a tuple type. Tuple types are (type, type, type).
|
||||
// The type of a tuple expression is a tuple type. (duh)
|
||||
(int, char*) array = (int, char*): s;
|
||||
// You can index arrays and tuples using the expression[index] syntax.
|
||||
writeln "pointer is $(array[1]) and length is $(array[0])";
|
||||
// You can slice them using the expression[from .. to] syntax.
|
||||
// Slicing an array makes another array.
|
||||
writeln "$(s[0..5]) World";
|
||||
// Alias name = expression gives the expression a name.
|
||||
// As opposed to a variable, aliases do not have an address
|
||||
// and can not be assigned to. (Unless the expression is assignable)
|
||||
alias range = 0 .. 5;
|
||||
writeln "$(s[range]) World";
|
||||
// You can iterate over ranges.
|
||||
for int i <- range {
|
||||
write "$(s[i])";
|
||||
}
|
||||
writeln " World";
|
||||
// Note that if "range" had been a variable, it would be 'empty' now!
|
||||
// Range variables can only be iterated once.
|
||||
// The syntax for iteration is "expression <- iterable".
|
||||
// Lots of things are iterable.
|
||||
for char c <- "Hello" { write "$c"; }
|
||||
writeln " World";
|
||||
// For loops are "for test statement";
|
||||
alias test = char d <- "Hello";
|
||||
for test write "$d";
|
||||
writeln " World\t\x05"; // note: escapes work
|
||||
// Pointers: function the same as in C, btw. The usual.
|
||||
// Do note: the pointer star sticks with the TYPE, not the VARIABLE!
|
||||
string* p;
|
||||
assert(p == null); // default initializer
|
||||
p = &s;
|
||||
writeln "$(*p)";
|
||||
// Math operators are (almost) standard.
|
||||
int x = 2 + 3 * 4 << 5;
|
||||
// Note: XOR is "xor". ^ is reserved for exponentiation (once I implement that).
|
||||
int y = 3 xor 5;
|
||||
int z = 5;
|
||||
assert(z++ == 5);
|
||||
assert(++z == 7);
|
||||
writeln "x $x y $y z $z";
|
||||
// As in D, ~ concatenates.
|
||||
string hewo = "Hello " ~ "World";
|
||||
// == tests for equality, "is" tests for identity.
|
||||
assert (hewo == s);
|
||||
assert !(hewo is s);
|
||||
// same as
|
||||
assert (hewo !is s);
|
||||
|
||||
// Allocate arrays using "new array length"
|
||||
int[] integers = new int[] 10;
|
||||
assert(integers.length == 10);
|
||||
assert(integers[0] == 0); // zero is default initializer
|
||||
integers = integers ~ 5; // This allocates a new array!
|
||||
assert(integers.length == 11);
|
||||
|
||||
// This is an appender array.
|
||||
// Instead of (length, pointer), it tracks (capacity, length, pointer).
|
||||
// When you append to it, it will use the free capacity if it can.
|
||||
// If it runs out of space, it reallocates - but it will free the old array automatically.
|
||||
// This makes it convenient for building arrays.
|
||||
int[auto~] appender;
|
||||
appender ~= 2;
|
||||
appender ~= 3;
|
||||
appender.free(); // same as {mem.free(appender.ptr); appender = null;}
|
||||
|
||||
// Scope variables are automatically freed at the end of the current scope.
|
||||
scope int[auto~] someOtherAppender;
|
||||
// This is the same as:
|
||||
int[auto~] someOtherAppender2;
|
||||
onExit { someOtherAppender2.free; }
|
||||
|
||||
// You can do a C for loop too
|
||||
// - but why would you want to?
|
||||
for (int i = 0; i < 5; ++i) { }
|
||||
// Otherwise, for and while are the same.
|
||||
while int i <- 0..4 {
|
||||
assert(i == 0);
|
||||
break; // continue works too
|
||||
} then assert(false); // if we hadn't break'd, this would run at the end
|
||||
// This is the height of loopdom - the produce-test-consume loop.
|
||||
do {
|
||||
int i = 5;
|
||||
} while (i == 5) {
|
||||
assert(i == 5);
|
||||
break; // otherwise we'd go back up to do {
|
||||
}
|
||||
|
||||
// This is a nested function.
|
||||
// Nested functions can access the surrounding function.
|
||||
string returnS() { return s; }
|
||||
writeln returnS();
|
||||
|
||||
// Take the address of a function using &
|
||||
// The type of a global function is ReturnType function(ParameterTypeTuple).
|
||||
void function() foop = &foo;
|
||||
|
||||
// Similarly, the type of a nested function is ReturnType delegate(ParameterTypeTuple).
|
||||
string delegate() returnSp = &returnS;
|
||||
writeln returnSp();
|
||||
// Class member functions and struct member functions also fit into delegate variables.
|
||||
// In general, delegates are functions that carry an additional context pointer.
|
||||
// ("fat pointers" in C)
|
||||
|
||||
// Allocate a "snapshot" with "new delegate".
|
||||
// Snapshots are not closures! I used to call them closures too,
|
||||
// but then my Haskell-using friends yelled at me so I had to stop.
|
||||
// The difference is that snapshots "capture" their surrounding context
|
||||
// when "new" is used.
|
||||
// This allows things like this
|
||||
int delegate(int) add(int a) {
|
||||
int add_a(int b) { return a + b; }
|
||||
// This does not work - the context of add_a becomes invalid
|
||||
// when add returns.
|
||||
// return &add_a;
|
||||
// Instead:
|
||||
return new &add_a;
|
||||
}
|
||||
int delegate(int) dg = add 2;
|
||||
assert (dg(3) == 5);
|
||||
// or
|
||||
assert (((add 2) 3) == 5);
|
||||
// or
|
||||
assert (add 2 3 == 5);
|
||||
// add can also be written as
|
||||
int delegate(int) add2(int a) {
|
||||
// this is an implicit, nameless nested function.
|
||||
return new λ(int b) { return a + b; }
|
||||
}
|
||||
// or even
|
||||
auto add3(int a) { return new λ(int b) -> a + b; }
|
||||
// hahahaaa
|
||||
auto add4 = λ(int a) -> new λ(int b) -> a + b;
|
||||
assert(add4 2 3 == 5);
|
||||
// If your keyboard doesn't have a λ (you poor sod)
|
||||
// you can use \ too.
|
||||
auto add5 = \(int a) -> new \(int b) -> a + b;
|
||||
// Note!
|
||||
auto nestfun = λ() { } // There is NO semicolon needed here!
|
||||
// "}" can always substitute for "};".
|
||||
// This provides syntactic consistency with built-in statements.
|
||||
|
||||
|
||||
// This is a class.
|
||||
// Note: almost all elements of Neat can be used on the module level
|
||||
// or just as well inside a function.
|
||||
class C {
|
||||
int a;
|
||||
void writeA() { writeln "$a"; }
|
||||
// It's a nested class - it exists in the context of main().
|
||||
// so if you leave main(), any instances of C become invalid.
|
||||
void writeS() { writeln "$s"; }
|
||||
}
|
||||
C cc = new C;
|
||||
// cc is a *reference* to C. Classes are always references.
|
||||
cc.a = 5; // Always used for property access.
|
||||
auto ccp = &cc;
|
||||
(*ccp).a = 6;
|
||||
// or just
|
||||
ccp.a = 7;
|
||||
cc.writeA();
|
||||
cc.writeS(); // to prove I'm not making things up
|
||||
// Interfaces work same as in D, basically. Or Java.
|
||||
interface E { void doE(); }
|
||||
// Inheritance works same as in D, basically. Or Java.
|
||||
class D : C, E {
|
||||
override void writeA() { writeln "hahahahaha no"; }
|
||||
override void doE() { writeln "eeeee"; }
|
||||
// all classes inherit from Object. (toString is defined in Object)
|
||||
override string toString() { return "I am a D"; }
|
||||
}
|
||||
C cd = new D;
|
||||
// all methods are always virtual.
|
||||
cd.writeA();
|
||||
E e = E:cd; // dynamic class cast!
|
||||
e.doE();
|
||||
writeln "$e"; // all interfaces convert to Object implicitly.
|
||||
|
||||
// Templates!
|
||||
// Templates are parameterized namespaces, taking a type as a parameter.
|
||||
template Templ(T) {
|
||||
alias hi = 5, hii = 8;
|
||||
// Templates always have to include something with the same name as the template
|
||||
// - this will become the template's _value_.
|
||||
// Static ifs are evaluated statically, at compile-time.
|
||||
// Because of this, the test has to be a constant expression,
|
||||
// or something that can be optimized to a constant.
|
||||
static if (types-equal (T, int)) {
|
||||
alias Templ = hi;
|
||||
} else {
|
||||
alias Templ = hii;
|
||||
}
|
||||
}
|
||||
assert(Templ!int == 5);
|
||||
assert(Templ!float == 8);
|
||||
}
|
||||
```
|
||||
|
||||
## Topics Not Covered
|
||||
|
||||
* Extended iterator types and expressions
|
||||
* Standard library
|
||||
* Conditions (error handling)
|
||||
* Macros
|
@ -80,7 +80,7 @@ int main (int argc, const char * argv[])
|
||||
NSLog(@"%f", piFloat);
|
||||
|
||||
NSNumber *piDoubleNumber = @3.1415926535;
|
||||
piDouble = [piDoubleNumber doubleValue];
|
||||
double piDouble = [piDoubleNumber doubleValue];
|
||||
NSLog(@"%f", piDouble);
|
||||
|
||||
// BOOL literals
|
||||
@ -160,7 +160,7 @@ int main (int argc, const char * argv[])
|
||||
int jj;
|
||||
for (jj=0; jj < 4; jj++)
|
||||
{
|
||||
NSLog(@"%d,", jj++);
|
||||
NSLog(@"%d,", jj);
|
||||
} // => prints "0,"
|
||||
// "1,"
|
||||
// "2,"
|
||||
@ -223,7 +223,7 @@ int main (int argc, const char * argv[])
|
||||
// }
|
||||
// -/+ (type) Method declarations;
|
||||
// @end
|
||||
@interface MyClass : NSObject <MyCustomProtocol>
|
||||
@interface MyClass : NSObject <MyProtocol>
|
||||
{
|
||||
int count;
|
||||
id data;
|
||||
@ -241,14 +241,14 @@ int main (int argc, const char * argv[])
|
||||
+ (NSString *)classMethod;
|
||||
|
||||
// - for instance method
|
||||
- (NSString *)instanceMethodWithParmeter:(NSString *)string;
|
||||
- (NSString *)instanceMethodWithParameter:(NSString *)string;
|
||||
- (NSNumber *)methodAParameterAsString:(NSString*)string andAParameterAsNumber:(NSNumber *)number;
|
||||
|
||||
@end
|
||||
|
||||
// Implement the methods in an implementation (MyClass.m) file:
|
||||
|
||||
@implementation UserObject
|
||||
@implementation MyClass
|
||||
|
||||
// Call when the object is releasing
|
||||
- (void)dealloc
|
||||
@ -271,7 +271,7 @@ int main (int argc, const char * argv[])
|
||||
return [[self alloc] init];
|
||||
}
|
||||
|
||||
- (NSString *)instanceMethodWithParmeter:(NSString *)string
|
||||
- (NSString *)instanceMethodWithParameter:(NSString *)string
|
||||
{
|
||||
return @"New string";
|
||||
}
|
||||
|
@ -104,15 +104,44 @@ $a =~ s/foo/bar/; # replaces foo with bar in $a
|
||||
$a =~ s/foo/bar/g; # replaces ALL INSTANCES of foo with bar in $a
|
||||
|
||||
|
||||
#### Files and I/O
|
||||
|
||||
# You can open a file for input or output using the "open()" function.
|
||||
|
||||
open(my $in, "<", "input.txt") or die "Can't open input.txt: $!";
|
||||
open(my $out, ">", "output.txt") or die "Can't open output.txt: $!";
|
||||
open(my $log, ">>", "my.log") or die "Can't open my.log: $!";
|
||||
|
||||
# You can read from an open filehandle using the "<>" operator. In scalar context it reads a single line from
|
||||
# the filehandle, and in list context it reads the whole file in, assigning each line to an element of the list:
|
||||
|
||||
my $line = <$in>;
|
||||
my @lines = <$in>;
|
||||
|
||||
#### Writing subroutines
|
||||
|
||||
# Writing subroutines is easy:
|
||||
|
||||
sub logger {
|
||||
my $logmessage = shift;
|
||||
open my $logfile, ">>", "my.log" or die "Could not open my.log: $!";
|
||||
print $logfile $logmessage;
|
||||
}
|
||||
|
||||
# Now we can use the subroutine just as any other built-in function:
|
||||
|
||||
logger("We have a logger subroutine!");
|
||||
```
|
||||
|
||||
#### Using Perl modules
|
||||
|
||||
Perl modules provide a range of features to help you avoid reinventing the wheel, and can be downloaded from CPAN ( http://www.cpan.org/ ). A number of popular modules are included with the Perl distribution itself.
|
||||
Perl modules provide a range of features to help you avoid reinventing the wheel, and can be downloaded from CPAN (http://www.cpan.org/). A number of popular modules are included with the Perl distribution itself.
|
||||
|
||||
perlfaq contains questions and answers related to many common tasks, and often provides suggestions for good CPAN modules to use.
|
||||
|
||||
#### Further Reading
|
||||
|
||||
[Learn at www.perl.com](http://www.perl.org/learn.html)
|
||||
and perldoc perlintro
|
||||
- [perl-tutorial](http://perl-tutorial.org/)
|
||||
- [Learn at www.perl.com](http://www.perl.org/learn.html)
|
||||
- [perldoc](http://perldoc.perl.org/)
|
||||
- and perl built-in : `perldoc perlintro`
|
||||
|
@ -11,7 +11,7 @@ This document describes PHP 5+.
|
||||
```php
|
||||
<?php // PHP code must be enclosed with <?php tags
|
||||
|
||||
// If your php file only contains PHP code, it is best practise
|
||||
// If your php file only contains PHP code, it is best practice
|
||||
// to omit the php closing tag.
|
||||
|
||||
// Two forward slashes start a one-line comment.
|
||||
@ -59,6 +59,9 @@ $float = 1.234;
|
||||
$float = 1.2e3;
|
||||
$float = 7E-10;
|
||||
|
||||
// Delete variable
|
||||
unset($int1)
|
||||
|
||||
// Arithmetic
|
||||
$sum = 1 + 1; // 2
|
||||
$difference = 2 - 1; // 1
|
||||
@ -69,7 +72,7 @@ $quotient = 2 / 1; // 2
|
||||
$number = 0;
|
||||
$number += 1; // Increment $number by 1
|
||||
echo $number++; // Prints 1 (increments after evaluation)
|
||||
echo ++$number; // Prints 3 (increments before evalutation)
|
||||
echo ++$number; // Prints 3 (increments before evaluation)
|
||||
$number /= $float; // Divide and assign the quotient to $number
|
||||
|
||||
// Strings should be enclosed in single quotes;
|
||||
@ -104,7 +107,7 @@ echo 'This string ' . 'is concatenated';
|
||||
/********************************
|
||||
* Constants
|
||||
*/
|
||||
|
||||
|
||||
// A constant is defined by using define()
|
||||
// and can never be changed during runtime!
|
||||
|
||||
@ -136,6 +139,11 @@ echo $associative['One']; // prints 1
|
||||
$array = ['One', 'Two', 'Three'];
|
||||
echo $array[0]; // => "One"
|
||||
|
||||
// Add an element to the end of an array
|
||||
$array[] = 'Four';
|
||||
|
||||
// Remove element from array
|
||||
unset($array[3]);
|
||||
|
||||
/********************************
|
||||
* Output
|
||||
@ -176,6 +184,11 @@ $y = 0;
|
||||
echo $x; // => 2
|
||||
echo $z; // => 0
|
||||
|
||||
// Dumps type and value of variable to stdout
|
||||
var_dump($z); // prints int(0)
|
||||
|
||||
// Prints variable to stdout in human-readable format
|
||||
print_r($array); // prints: Array ( [0] => One [1] => Two [2] => Three )
|
||||
|
||||
/********************************
|
||||
* Logic
|
||||
@ -442,8 +455,10 @@ class MyClass
|
||||
|
||||
// Static variables and their visibility
|
||||
public static $publicStaticVar = 'publicStatic';
|
||||
private static $privateStaticVar = 'privateStatic'; // Accessible within the class only
|
||||
protected static $protectedStaticVar = 'protectedStatic'; // Accessible from the class and subclasses
|
||||
// Accessible within the class only
|
||||
private static $privateStaticVar = 'privateStatic';
|
||||
// Accessible from the class and subclasses
|
||||
protected static $protectedStaticVar = 'protectedStatic';
|
||||
|
||||
// Properties must declare their visibility
|
||||
public $property = 'public';
|
||||
@ -463,10 +478,17 @@ class MyClass
|
||||
print 'MyClass';
|
||||
}
|
||||
|
||||
//final keyword would make a function unoverridable
|
||||
final function youCannotOverrideMe()
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Declaring class properties or methods as static makes them accessible without
|
||||
* needing an instantiation of the class. A property declared as static can not
|
||||
* be accessed with an instantiated class object (though a static method can).
|
||||
*/
|
||||
|
||||
public static function myStaticMethod()
|
||||
{
|
||||
print 'I am static';
|
||||
@ -655,10 +677,14 @@ $cls = new SomeOtherNamespace\MyClass();
|
||||
|
||||
## More Information
|
||||
|
||||
Visit the [official PHP documentation](http://www.php.net/manual/) for reference and community input.
|
||||
Visit the [official PHP documentation](http://www.php.net/manual/) for reference
|
||||
and community input.
|
||||
|
||||
If you're interested in up-to-date best practices, visit [PHP The Right Way](http://www.phptherightway.com/).
|
||||
If you're interested in up-to-date best practices, visit
|
||||
[PHP The Right Way](http://www.phptherightway.com/).
|
||||
|
||||
If you're coming from a language with good package management, check out [Composer](http://getcomposer.org/).
|
||||
If you're coming from a language with good package management, check out
|
||||
[Composer](http://getcomposer.org/).
|
||||
|
||||
For common standards, visit the PHP Framework Interoperability Group's [PSR standards](https://github.com/php-fig/fig-standards).
|
||||
For common standards, visit the PHP Framework Interoperability Group's
|
||||
[PSR standards](https://github.com/php-fig/fig-standards).
|
||||
|
202
pogo.html.markdown
Normal file
202
pogo.html.markdown
Normal file
@ -0,0 +1,202 @@
|
||||
---
|
||||
language: pogoscript
|
||||
contributors:
|
||||
- ["Tim Macfarlane", "http://github.com/refractalize"]
|
||||
filename: learnPogo.pogo
|
||||
---
|
||||
|
||||
Pogoscript is a little language that emphasises readability, DSLs and provides excellent asynchronous primitives for writing connected JavaScript applications for the browser or server.
|
||||
|
||||
``` javascript
|
||||
// defining a variable
|
||||
water temperature = 24
|
||||
|
||||
// re-assigning a variable after its definition
|
||||
water temperature := 26
|
||||
|
||||
// functions allow their parameters to be placed anywhere
|
||||
temperature at (a) altitude = 32 - a / 100
|
||||
|
||||
// longer functions are just indented
|
||||
temperature at (a) altitude :=
|
||||
if (a < 0)
|
||||
water temperature
|
||||
else
|
||||
32 - a / 100
|
||||
|
||||
// calling a function
|
||||
current temperature = temperature at 3200 altitude
|
||||
|
||||
// this function constructs a new object with methods
|
||||
position (x, y) = {
|
||||
x = x
|
||||
y = y
|
||||
|
||||
distance from position (p) =
|
||||
dx = self.x - p.x
|
||||
dy = self.y - p.y
|
||||
Math.sqrt (dx * dx + dy * dy)
|
||||
}
|
||||
|
||||
// `self` is similar to `this` in JavaScript with the
|
||||
// exception that `self` isn't redefined in each new
|
||||
// function definition
|
||||
// `self` just does what you expect
|
||||
|
||||
// calling methods
|
||||
position (7, 2).distance from position (position (5, 1))
|
||||
|
||||
// as in JavaScript, objects are hashes too
|
||||
position.'x' == position.x == position.('x')
|
||||
|
||||
// arrays
|
||||
positions = [
|
||||
position (1, 1)
|
||||
position (1, 2)
|
||||
position (1, 3)
|
||||
]
|
||||
|
||||
// indexing an array
|
||||
positions.0.y
|
||||
|
||||
n = 2
|
||||
positions.(n).y
|
||||
|
||||
// strings
|
||||
poem = 'Tail turned to red sunset on a juniper crown a lone magpie cawks.
|
||||
Mad at Oryoki in the shrine-room -- Thistles blossomed late afternoon.
|
||||
Put on my shirt and took it off in the sun walking the path to lunch.
|
||||
A dandelion seed floats above the marsh grass with the mosquitos.
|
||||
At 4 A.M. the two middleaged men sleeping together holding hands.
|
||||
In the half-light of dawn a few birds warble under the Pleiades.
|
||||
Sky reddens behind fir trees, larks twitter, sparrows cheep cheep cheep
|
||||
cheep cheep.'
|
||||
|
||||
// that's Allen Ginsburg
|
||||
|
||||
// interpolation
|
||||
outlook = 'amazing!'
|
||||
console.log "the weather tomorrow is going to be #(outlook)"
|
||||
|
||||
// regular expressions
|
||||
r/(\d+)m/i
|
||||
r/(\d+) degrees/mg
|
||||
|
||||
// operators
|
||||
true @and true
|
||||
false @or true
|
||||
@not false
|
||||
2 < 4
|
||||
2 >= 2
|
||||
2 > 1
|
||||
|
||||
// plus all the javascript ones
|
||||
|
||||
// to define your own
|
||||
(p1) plus (p2) =
|
||||
position (p1.x + p2.x, p1.y + p2.y)
|
||||
|
||||
// `plus` can be called as an operator
|
||||
position (1, 1) @plus position (0, 2)
|
||||
// or as a function
|
||||
(position (1, 1)) plus (position (0, 2))
|
||||
|
||||
// explicit return
|
||||
(x) times (y) = return (x * y)
|
||||
|
||||
// new
|
||||
now = @new Date ()
|
||||
|
||||
// functions can take named optional arguments
|
||||
spark (position, color: 'black', velocity: {x = 0, y = 0}) = {
|
||||
color = color
|
||||
position = position
|
||||
velocity = velocity
|
||||
}
|
||||
|
||||
red = spark (position 1 1, color: 'red')
|
||||
fast black = spark (position 1 1, velocity: {x = 10, y = 0})
|
||||
|
||||
// functions can unsplat arguments too
|
||||
log (messages, ...) =
|
||||
console.log (messages, ...)
|
||||
|
||||
// blocks are functions passed to other functions.
|
||||
// This block takes two parameters, `spark` and `c`,
|
||||
// the body of the block is the indented code after the
|
||||
// function call
|
||||
|
||||
render each @(spark) into canvas context @(c)
|
||||
ctx.begin path ()
|
||||
ctx.stroke style = spark.color
|
||||
ctx.arc (
|
||||
spark.position.x + canvas.width / 2
|
||||
spark.position.y
|
||||
3
|
||||
0
|
||||
Math.PI * 2
|
||||
)
|
||||
ctx.stroke ()
|
||||
|
||||
// asynchronous calls
|
||||
|
||||
// JavaScript both in the browser and on the server (with Node.js)
|
||||
// makes heavy use of asynchronous IO with callbacks. Async IO is
|
||||
// amazing for performance and making concurrency simple but it
|
||||
// quickly gets complicated.
|
||||
// Pogoscript has a few things to make async IO much much easier
|
||||
|
||||
// Node.js includes the `fs` module for accessing the file system.
|
||||
// Let's list the contents of a directory
|
||||
|
||||
fs = require 'fs'
|
||||
directory listing = fs.readdir! '.'
|
||||
|
||||
// `fs.readdir()` is an asynchronous function, so we can call it
|
||||
// using the `!` operator. The `!` operator allows you to call
|
||||
// async functions with the same syntax and largely the same
|
||||
// semantics as normal synchronous functions. Pogoscript rewrites
|
||||
// it so that all subsequent code is placed in the callback function
|
||||
// to `fs.readdir()`.
|
||||
|
||||
// to catch asynchronous errors while calling asynchronous functions
|
||||
|
||||
try
|
||||
another directory listing = fs.readdir! 'a-missing-dir'
|
||||
catch (ex)
|
||||
console.log (ex)
|
||||
|
||||
// in fact, if you don't use `try catch`, it will raise the error up the
|
||||
// stack to the outer-most `try catch` or to the event loop, as you'd expect
|
||||
// with non-async exceptions
|
||||
|
||||
// all the other control structures work with asynchronous calls too
|
||||
// here's `if else`
|
||||
config =
|
||||
if (fs.stat! 'config.json'.is file ())
|
||||
JSON.parse (fs.read file! 'config.json' 'utf-8')
|
||||
else
|
||||
{
|
||||
color: 'red'
|
||||
}
|
||||
|
||||
// to run two asynchronous calls concurrently, use the `?` operator.
|
||||
// The `?` operator returns a *future* which can be executed to
|
||||
// wait for and obtain the result, again using the `!` operator
|
||||
|
||||
// we don't wait for either of these calls to finish
|
||||
a = fs.stat? 'a.txt'
|
||||
b = fs.stat? 'b.txt'
|
||||
|
||||
// now we wait for the calls to finish and print the results
|
||||
console.log "size of a.txt is #(a!.size)"
|
||||
console.log "size of b.txt is #(b!.size)"
|
||||
|
||||
// futures in Pogoscript are analogous to Promises
|
||||
```
|
||||
|
||||
That's it.
|
||||
|
||||
Download [Node.js](http://nodejs.org/) and `npm install pogo`.
|
||||
|
||||
There is plenty of documentation on [http://pogoscript.org/](http://pogoscript.org/), inlcuding a [cheat sheet](http://pogoscript.org/cheatsheet.html), a [guide](http://pogoscript.org/guide/), and how [Pogoscript translates to Javascript](http://featurist.github.io/pogo-examples/). Get in touch on the [google group](http://groups.google.com/group/pogoscript) if you have questions!
|
254
pt-br/erlang-pt.html.markdown
Normal file
254
pt-br/erlang-pt.html.markdown
Normal file
@ -0,0 +1,254 @@
|
||||
---
|
||||
language: erlang
|
||||
filename: learnerlang-pt.erl
|
||||
contributors:
|
||||
- ["Giovanni Cappellotto", "http://www.focustheweb.com/"]
|
||||
translators:
|
||||
- ["Guilherme Heuser Prestes", "http://twitter.com/gprestes"]
|
||||
lang: pt-br
|
||||
---
|
||||
|
||||
```erlang
|
||||
% Símbolo de porcento começa comentários de uma linha.
|
||||
|
||||
%% Dois caracteres de porcento devem ser usados para comentar funções.
|
||||
|
||||
%%% Três caracteres de porcento devem ser usados para comentar módulos.
|
||||
|
||||
% Nós usamos três tipos de pontuação em Erlang.
|
||||
% Vírgulas (`,`) separam argumentos em chamadas de função, construtores de
|
||||
% dados, e padrões.
|
||||
% Pontos finais (`.`) separam totalmente funções e expressões no prompt.
|
||||
% Ponto e vírgulas (`;`) separam cláusulas. Nós encontramos cláusulas em
|
||||
% vários contextos: definições de função e em expressões com `case`, `if`,
|
||||
% `try..catch` e `receive`.
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%% 1. Variáveis e casamento de padrões.
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
Num = 42. % Todos nomes de variáveis devem começar com uma letra maiúscula.
|
||||
|
||||
% Erlang tem atribuição única de variáveis, se você tentar atribuir um valor
|
||||
% diferente à variável `Num`, você receberá um erro.
|
||||
Num = 43. % ** exception error: no match of right hand side value 43
|
||||
|
||||
% Na maioria das linguagens, `=` denota um comando de atribuição. Em Erlang, no
|
||||
% entanto, `=` denota uma operação de casamento de padrão. `Lhs = Rhs` realmente
|
||||
% significa isso: avalia o lado direito (Rhs), e então casa o resultado com o
|
||||
% padrão no lado esquerdo (Lhs).
|
||||
Num = 7 * 6.
|
||||
|
||||
% Número de ponto flutuante.
|
||||
Pi = 3.14159.
|
||||
|
||||
% Átomos são usados para representar diferentes valores constantes não
|
||||
% numéricos. Átomos começam com letras minúsculas seguidas por uma sequência de
|
||||
% caracteres alfanuméricos ou sinais de subtraço (`_`) ou arroba (`@`).
|
||||
Hello = hello.
|
||||
OtherNode = example@node.
|
||||
|
||||
% Átomos com valores alfanuméricos podem ser escritos colocando aspas por fora
|
||||
% dos átomos.
|
||||
AtomWithSpace = 'some atom with space'.
|
||||
|
||||
% Tuplas são similares a structs em C.
|
||||
Point = {point, 10, 45}.
|
||||
|
||||
% Se nós queremos extrair alguns valores de uma tupla, nós usamos o operador `=`.
|
||||
{point, X, Y} = Point. % X = 10, Y = 45
|
||||
|
||||
% Nós podemos usar `_` para ocupar o lugar de uma variável que não estamos interessados.
|
||||
% O símbolo `_` é chamado de variável anônima. Ao contrário de variáveis regulares,
|
||||
% diversas ocorrências de _ no mesmo padrão não precisam se amarrar ao mesmo valor.
|
||||
Person = {person, {name, {first, joe}, {last, armstrong}}, {footsize, 42}}.
|
||||
{_, {_, {_, Who}, _}, _} = Person. % Who = joe
|
||||
|
||||
% Nós criamos uma lista colocando valores separados por vírgula entre colchetes.
|
||||
% Cada elemento de uma lista pode ser de qualquer tipo.
|
||||
% O primeiro elemento de uma lista é a cabeça da lista. Se removermos a cabeça
|
||||
% da lista, o que sobra é chamado de cauda da lista.
|
||||
ThingsToBuy = [{apples, 10}, {pears, 6}, {milk, 3}].
|
||||
|
||||
% Se `T` é uma lista, então `[H|T]` também é uma lista, com cabeça `H` e cauda `T`.
|
||||
% A barra vertical (`|`) separa a cabeça de uma lista de sua cauda.
|
||||
% `[]` é uma lista vazia.
|
||||
% Podemos extrair elementos de uma lista com uma operação de casamento de
|
||||
% padrão. Se temos uma lista não-vazia `L`, então a expressão `[X|Y] = L`, onde
|
||||
% `X` e `Y` são variáveis desamarradas, irá extrair a cabeça de uma lista para
|
||||
% `X` e a cauda da lista para `Y`.
|
||||
[FirstThing|OtherThingsToBuy] = ThingsToBuy.
|
||||
% FirstThing = {apples, 10}
|
||||
% OtherThingsToBuy = {pears, 6}, {milk, 3}
|
||||
|
||||
% Não existe o tipo string em Erlang. Strings são somente listas de inteiros.
|
||||
% Strings são representadas dentro de aspas duplas (`"`).
|
||||
Name = "Hello".
|
||||
[72, 101, 108, 108, 111] = "Hello".
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%% 2. Programação sequencial.
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
% Módulos são a unidade básica de código em Erlang. Todas funções que
|
||||
% escrevemos são armazenadas em módulos. Módulos são armazenados em arquivos
|
||||
% com extensão `.erl`.
|
||||
% Módulos devem ser compilados antes que o código possa ser rodado. Um módulo
|
||||
% compilado tem a extensão `.beam`.
|
||||
-module(geometry).
|
||||
-export([area/1]). % lista de funções exportadas de um módulo.
|
||||
|
||||
% A função `area` consiste de duas cláusulas. As cláusulas são separadas por um
|
||||
% ponto e vírgula, e a cláusula final é terminada por um ponto final.
|
||||
% Cada cláusula tem uma cabeça em um corpo; a cabeça consiste de um nome de
|
||||
% função seguido por um padrão (entre parêntesis), e o corpo consiste de uma
|
||||
% sequência de expressões, que são avaliadas se o padrão na cabeça é um par bem
|
||||
% sucedido dos argumentos da chamada. Os padrões são casados na ordem que
|
||||
% aparecem na definição da função.
|
||||
area({rectangle, Width, Ht}) -> Width * Ht;
|
||||
area({circle, R}) -> 3.14159 * R * R.
|
||||
|
||||
% Compila o código no arquivo geometry.erl.
|
||||
c(geometry). % {ok,geometry}
|
||||
|
||||
% Nós precisamos incluir o nome do módulo junto com o nome da função de maneira
|
||||
% a identificar exatamente qual função queremos chamar.
|
||||
geometry:area({rectangle, 10, 5}). % 50
|
||||
geometry:area({circle, 1.4}). % 6.15752
|
||||
|
||||
% Em Erlang, duas funções com o mesmo nome e diferentes aridades (números de
|
||||
% argumentos) no mesmo módulo representam funções totalmente diferentes.
|
||||
-module(lib_misc).
|
||||
-export([sum/1]). % exporta a função `sum` de aridade 1 aceitando um argumento: lista de inteiros.
|
||||
sum(L) -> sum(L, 0).
|
||||
sum([], N) -> N;
|
||||
sum([H|T], N) -> sum(T, H+N).
|
||||
|
||||
% Funs são funções "anônimas". Elas são chamadas desta maneira por que elas não
|
||||
% têm nome. No entanto podem ser atribuídas a variáveis.
|
||||
Double = fun(X) -> 2*X end. % `Double` aponta para uma função anônima com referência: #Fun<erl_eval.6.17052888>
|
||||
Double(2). % 4
|
||||
|
||||
% Funções aceitam funs como seus argumentos e podem retornar funs.
|
||||
Mult = fun(Times) -> ( fun(X) -> X * Times end ) end.
|
||||
Triple = Mult(3).
|
||||
Triple(5). % 15
|
||||
|
||||
% Compreensão de lista são expressões que criam listas sem precisar usar funs,
|
||||
% maps, ou filtros.
|
||||
% A notação `[F(X) || X <- L]` significa "a lista de `F(X)` onde `X` é tomada
|
||||
% da lista `L`."
|
||||
L = [1,2,3,4,5].
|
||||
[2*X || X <- L]. % [2,4,6,8,10]
|
||||
% Uma compreensão de lista pode ter geradores e filtros que selecionam
|
||||
% subconjuntos dos valores gerados.
|
||||
EvenNumbers = [N || N <- [1, 2, 3, 4], N rem 2 == 0]. % [2, 4]
|
||||
|
||||
% Sentinelas são contruções que podemos usar para incrementar o poder de
|
||||
% casamento de padrão. Usando sentinelas, podemos executar testes simples e
|
||||
% comparações nas variáveis em um padrão.
|
||||
% Você pode usar sentinelas nas cabeças das definições de função onde eles são
|
||||
% introduzidos pela palavra-chave `when`, ou você pode usá-los em qualquer
|
||||
% lugar na linguagem onde uma expressão é permitida.
|
||||
max(X, Y) when X > Y -> X;
|
||||
max(X, Y) -> Y.
|
||||
|
||||
% Um sentinela é uma série de expressões sentinelas, separadas por
|
||||
% vírgulas (`,`).
|
||||
% O sentinela `GuardExpr1, GuardExpr2, ..., GuardExprN` é verdadeiro se todas
|
||||
% expressões sentinelas `GuardExpr1, GuardExpr2, ...` forem verdadeiras.
|
||||
is_cat(A) when is_atom(A), A =:= cat -> true;
|
||||
is_cat(A) -> false.
|
||||
is_dog(A) when is_atom(A), A =:= dog -> true;
|
||||
is_dog(A) -> false.
|
||||
|
||||
% Uma `sequência sentinela` é um sentinela ou uma série de sentinelas separados
|
||||
% por ponto e vírgula (`;`). A sequência sentinela `G1; G2; ...; Gn` é
|
||||
% verdadeira se pelo menos um dos sentinelas `G1, G2, ...` for verdadeiro.
|
||||
is_pet(A) when is_dog(A); is_cat(A) -> true;
|
||||
is_pet(A) -> false.
|
||||
|
||||
% Registros provêem um método para associar um nome com um elemento particular
|
||||
% em uma tupla.
|
||||
% Definições de registro podem ser incluídas em arquivos fonte Erlang ou em
|
||||
% arquivos com extensão `.hrl`, que então são incluídos em arquivos fonte Erlang.
|
||||
-record(todo, {
|
||||
status = reminder, % Default value
|
||||
who = joe,
|
||||
text
|
||||
}).
|
||||
|
||||
% Nós temos que ler definições de registro no prompt antes que possamos definir
|
||||
% um registro. Nós usamos a função de prompt `rr` (abreviação de read records)
|
||||
% para fazer isso.
|
||||
rr("records.hrl"). % [todo]
|
||||
|
||||
% Criando e atualizando registros:
|
||||
X = #todo{}.
|
||||
% #todo{status = reminder, who = joe, text = undefined}
|
||||
X1 = #todo{status = urgent, text = "Fix errata in book"}.
|
||||
% #todo{status = urgent, who = joe, text = "Fix errata in book"}
|
||||
X2 = X1#todo{status = done}.
|
||||
% #todo{status = done,who = joe,text = "Fix errata in book"}
|
||||
|
||||
% Expressões `case`.
|
||||
% A função `filter` retorna uma lista de todos elementos `X` em uma lista `L`
|
||||
% para qual `P(X)` é verdadeiro.
|
||||
filter(P, [H|T]) ->
|
||||
case P(H) of
|
||||
true -> [H|filter(P, T)];
|
||||
false -> filter(P, T)
|
||||
end;
|
||||
filter(P, []) -> [].
|
||||
filter(fun(X) -> X rem 2 == 0 end, [1, 2, 3, 4]). % [2, 4]
|
||||
|
||||
% Expressões `if`.
|
||||
max(X, Y) ->
|
||||
if
|
||||
X > Y -> X;
|
||||
X < Y -> Y;
|
||||
true -> nil;
|
||||
end.
|
||||
|
||||
% Aviso: pelo menos um dos sentinelas na expressão `if` deve retornar
|
||||
% verdadeiro; Caso contrário, uma exceção será levantada.
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%% 3. Exceções.
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
% Exceções são levantadas pelo sistema quando erros internos são encontrados ou
|
||||
% explicitamente em código pela chamada `throw(Exception)`, `exit(Exception)`
|
||||
% ou `erlang:error(Exception)`.
|
||||
generate_exception(1) -> a;
|
||||
generate_exception(2) -> throw(a);
|
||||
generate_exception(3) -> exit(a);
|
||||
generate_exception(4) -> {'EXIT', a};
|
||||
generate_exception(5) -> erlang:error(a).
|
||||
|
||||
% Erlang tem dois métodos para capturar uma exceção. Uma é encapsular a chamada
|
||||
% para a função que levanta uma exceção dentro de uma expressão `try...catch`.
|
||||
catcher(N) ->
|
||||
try generate_exception(N) of
|
||||
Val -> {N, normal, Val}
|
||||
catch
|
||||
throw:X -> {N, caught, thrown, X};
|
||||
exit:X -> {N, caught, exited, X};
|
||||
error:X -> {N, caught, error, X}
|
||||
end.
|
||||
|
||||
% O outro é encapsular a chamada em uma expressão `catch`. Quando você captura
|
||||
% uma exceção, é convertida em uma tupla que descreve o erro.
|
||||
catcher(N) -> catch generate_exception(N).
|
||||
|
||||
```
|
||||
|
||||
## Referências
|
||||
|
||||
* ["Learn You Some Erlang for great good!"](http://learnyousomeerlang.com/)
|
||||
* ["Programming Erlang: Software for a Concurrent World" by Joe Armstrong](http://pragprog.com/book/jaerlang2/programming-erlang)
|
||||
* [Erlang/OTP Reference Documentation](http://www.erlang.org/doc/)
|
||||
* [Erlang - Programming Rules and Conventions](http://www.erlang.se/doc/programming_rules.shtml)
|
||||
|
308
pt-br/go-pt.html.markdown
Normal file
308
pt-br/go-pt.html.markdown
Normal file
@ -0,0 +1,308 @@
|
||||
---
|
||||
name: Go
|
||||
category: language
|
||||
language: Go
|
||||
filename: learngo-pt.go
|
||||
lang: pt-br
|
||||
contributors:
|
||||
- ["Sonia Keys", "https://github.com/soniakeys"]
|
||||
translators:
|
||||
- ["Nuno Antunes", "https://github.com/ntns"]
|
||||
---
|
||||
|
||||
A linguagem Go foi criada a partir da necessidade de ver trabalho feito. Não
|
||||
é a última moda em ciências da computação, mas é a mais recente e mais rápida
|
||||
forma de resolver os problemas do mundo real.
|
||||
|
||||
Tem conceitos familiares de linguagens imperativas com tipagem estática. É
|
||||
rápida a compilar e rápida a executar, acrescentando mecanismos de concorrência
|
||||
fáceis de entender para tirar partido dos CPUs multi-core de hoje em dia, e tem
|
||||
recursos para ajudar com a programação em larga escala.
|
||||
|
||||
Go vem com uma biblioteca padrão exaustiva e uma comunidade entusiasta.
|
||||
|
||||
```go
|
||||
// Comentário de uma linha
|
||||
/* Comentário de
|
||||
várias linhas */
|
||||
|
||||
// A cláusula package aparece no início de cada arquivo.
|
||||
// Main é um nome especial declarando um executável ao invés de uma biblioteca.
|
||||
package main
|
||||
|
||||
// A cláusula Import declara os pacotes referenciados neste arquivo.
|
||||
import (
|
||||
"fmt" // Um pacote da biblioteca padrão da linguagem Go
|
||||
"net/http" // Sim, um servidor web!
|
||||
"strconv" // Conversão de Strings
|
||||
)
|
||||
|
||||
// Definição de uma função. Main é especial. É o ponto de entrada para o
|
||||
// programa executável. Goste-se ou não, a linguagem Go usa chavetas.
|
||||
func main() {
|
||||
// A função Println envia uma linha para stdout.
|
||||
// É necessário qualifica-la com o nome do pacote, fmt.
|
||||
fmt.Println("Olá Mundo!")
|
||||
|
||||
// Chama outra função dentro deste pacote.
|
||||
beyondHello()
|
||||
}
|
||||
|
||||
// As funções declaram os seus parâmetros dentro de parênteses. Se a função
|
||||
// não receber quaisquer parâmetros, é obrigatório usar parênteses vazios.
|
||||
func beyondHello() {
|
||||
var x int // Declaração de variável. Tem de ser declarada antes de usar.
|
||||
x = 3 // Atribuição de variável.
|
||||
// Declarações "curtas" usam := para inferir o tipo, declarar e atribuir.
|
||||
y := 4
|
||||
sum, prod := learnMultiple(x, y) // a função retorna dois valores
|
||||
fmt.Println("soma:", sum, "produto:", prod)
|
||||
learnTypes() // continuar a aprender!
|
||||
}
|
||||
|
||||
// As funções podem receber parâmetros e retornar (vários!) valores.
|
||||
func learnMultiple(x, y int) (sum, prod int) {
|
||||
return x + y, x * y // retorna dois valores
|
||||
}
|
||||
|
||||
// Alguns tipos e literais básicos.
|
||||
func learnTypes() {
|
||||
// Declarações "curtas" geralmente servem para o que pretendemos.
|
||||
s := "Aprender Go!" // tipo string
|
||||
|
||||
s2 := `Uma string em "bruto"
|
||||
pode incluir quebras de linha.` // mesmo tipo string
|
||||
|
||||
// literal não-ASCII. A linguagem Go utiliza de raiz a codificação UTF-8.
|
||||
g := 'Σ' // tipo rune, um alias para uint32, que contém um código unicode
|
||||
|
||||
f := 3.14195 // float64, número de vírgula flutuante de 64bit (IEEE-754)
|
||||
c := 3 + 4i // complex128, representado internamente com dois float64s
|
||||
|
||||
// Declaração de variáveis, com inicialização.
|
||||
var u uint = 7 // inteiro sem sinal, tamanho depende da implementação do Go
|
||||
var pi float32 = 22. / 7
|
||||
|
||||
// Sintaxe de conversão de tipo, com declaração "curta".
|
||||
n := byte('\n') // byte é um alias para uint8
|
||||
|
||||
// Os arrays têm tamanho fixo e definido antes da compilação.
|
||||
var a4 [4]int // um array de 4 ints, inicializado com ZEROS
|
||||
a3 := [...]int{3, 1, 5} // um array de 3 ints, inicializado como mostrado
|
||||
|
||||
// As slices têm tamanho dinâmico. Os arrays e as slices têm cada um as
|
||||
// suas vantagens mas o uso de slices é muito mais comum.
|
||||
s3 := []int{4, 5, 9} // compare com a3. sem reticências aqui
|
||||
s4 := make([]int, 4) // aloca uma slice de 4 ints, inicializada com ZEROS
|
||||
var d2 [][]float64 // declaração apenas, nada é alocado
|
||||
bs := []byte("uma slice") // sintaxe de conversão de tipos
|
||||
|
||||
p, q := learnMemory() // learnMemory retorna dois apontadores para int.
|
||||
fmt.Println(*p, *q) // * segue um apontador. isto imprime dois ints.
|
||||
|
||||
// Os maps são um tipo de matriz associativa, semelhante aos tipos hash
|
||||
// ou dictionary que encontramos noutras linguagens.
|
||||
m := map[string]int{"três": 3, "quatro": 4}
|
||||
m["um"] = 1
|
||||
|
||||
// As variáveis não usadas são um erro em Go.
|
||||
// O traço inferior permite "usar" uma variável, mas descarta o seu valor.
|
||||
_, _, _, _, _, _, _, _, _ = s2, g, f, u, pi, n, a3, s4, bs
|
||||
// Enviar para o stdout conta como utilização de uma variável.
|
||||
fmt.Println(s, c, a4, s3, d2, m)
|
||||
|
||||
learnFlowControl()
|
||||
}
|
||||
|
||||
// A linguagem Go é totalmente garbage collected. Tem apontadores mas não
|
||||
// permite que os apontadores sejam manipulados com aritmética. Pode-se cometer
|
||||
// um erro com um apontador nulo, mas não por incrementar um apontador.
|
||||
func learnMemory() (p, q *int) {
|
||||
// A função retorna os valores p e q, que são do tipo apontador para int.
|
||||
p = new(int) // a função new aloca memória, neste caso para um int.
|
||||
// O int alocado é inicializado com o valor 0, p deixa de ser nil.
|
||||
s := make([]int, 20) // alocar 20 ints como um único bloco de memória
|
||||
s[3] = 7 // atribui o valor 7 a um deles
|
||||
r := -2 // declarar outra variável local
|
||||
return &s[3], &r // & obtém o endereço de uma variável.
|
||||
}
|
||||
|
||||
func expensiveComputation() int {
|
||||
return 1e6
|
||||
}
|
||||
|
||||
func learnFlowControl() {
|
||||
// As instruções if exigem o uso de chavetas, e não requerem parênteses.
|
||||
if true {
|
||||
fmt.Println("eu avisei-te")
|
||||
}
|
||||
// A formatação do código-fonte é "estandardizada" através do comando
|
||||
// da linha de comandos "go fmt."
|
||||
if false {
|
||||
// reclamar
|
||||
} else {
|
||||
// exultar
|
||||
}
|
||||
// Preferir o uso de switch em vez de ifs em cadeia.
|
||||
x := 1
|
||||
switch x {
|
||||
case 0:
|
||||
case 1:
|
||||
// os cases não fazem "fall through"
|
||||
case 2:
|
||||
// esta linha só é executada se e só se x=2
|
||||
}
|
||||
// Tal como a instrução if, a instrução for não usa parênteses.
|
||||
for x := 0; x < 3; x++ { // x++ é uma instrução, nunca uma expressão
|
||||
fmt.Println("iteração", x)
|
||||
}
|
||||
// note que, x == 1 aqui.
|
||||
|
||||
// A instrução for é a única para ciclos, mas assume várias formas.
|
||||
for { // ciclo infinito
|
||||
break // brincadeirinha
|
||||
continue // nunca executado
|
||||
}
|
||||
// O uso de := numa instrução if permite criar uma variável local,
|
||||
// que existirá apenas dentro do bloco if.
|
||||
if y := expensiveComputation(); y > x {
|
||||
x = y
|
||||
}
|
||||
// As funções podem ser closures.
|
||||
xBig := func() bool {
|
||||
return x > 100 // referencia x, declarado acima da instrução switch.
|
||||
}
|
||||
fmt.Println("xBig:", xBig()) // true (1e6 é o último valor de x)
|
||||
x /= 1e5 // agora temos x == 10
|
||||
fmt.Println("xBig:", xBig()) // false
|
||||
|
||||
// Quando for mesmo necessário, pode usar o velho goto.
|
||||
goto love
|
||||
love:
|
||||
|
||||
learnInterfaces() // Mais coisas interessantes chegando!
|
||||
}
|
||||
|
||||
// Define Stringer como uma interface consistindo de um método, String.
|
||||
type Stringer interface {
|
||||
String() string
|
||||
}
|
||||
|
||||
// Define pair como uma struct com dois campos ints chamados x e y.
|
||||
type pair struct {
|
||||
x, y int
|
||||
}
|
||||
|
||||
// Define um método para o tipo pair. O tipo pair implementa agora a
|
||||
// interface Stringer.
|
||||
func (p pair) String() string { // p é chamado de "receptor"
|
||||
// Sprintf é outra função pública no pacote fmt.
|
||||
// Uso de pontos para referenciar os campos de p.
|
||||
return fmt.Sprintf("(%d, %d)", p.x, p.y)
|
||||
}
|
||||
|
||||
func learnInterfaces() {
|
||||
// Uma struct pode ser inicializada com os valores dos seus campos dentro
|
||||
// de chavetas, seguindo a mesma ordem com que os campos foram definidos.
|
||||
p := pair{3, 4}
|
||||
fmt.Println(p.String()) // chama o método String de p, que tem tipo pair.
|
||||
var i Stringer // declara i do tipo interface Stringer.
|
||||
i = p // válido, porque pair implementa Stringer
|
||||
// Chama o método String de i, que tem tipo Stringer. Mesmo que acima.
|
||||
fmt.Println(i.String())
|
||||
|
||||
// As funções no pacote fmt chamam o método String para pedir a um objecto
|
||||
// uma representação textual de si mesmo.
|
||||
fmt.Println(p) // mesmo que acima. Println chama o método String.
|
||||
fmt.Println(i) // mesmo que acima.
|
||||
|
||||
learnErrorHandling()
|
||||
}
|
||||
|
||||
func learnErrorHandling() {
|
||||
// ", ok" forma idiomática usada para saber se algo funcionou ou não.
|
||||
m := map[int]string{3: "três", 4: "quatro"}
|
||||
if x, ok := m[1]; !ok { // ok vai ser false porque 1 não está no map m.
|
||||
fmt.Println("ninguem lá")
|
||||
} else {
|
||||
fmt.Print(x) // x seria o valor, se 1 estivesse no map.
|
||||
}
|
||||
// Um valor de erro comunica mais informação sobre o problema.
|
||||
if _, err := strconv.Atoi("non-int"); err != nil { // _ descarta o valor
|
||||
// imprime "strconv.ParseInt: parsing "non-int": invalid syntax"
|
||||
fmt.Println(err)
|
||||
}
|
||||
// Vamos revisitar as interfaces um pouco mais tarde. Entretanto,
|
||||
learnConcurrency()
|
||||
}
|
||||
|
||||
// c é um channel, um objecto para comunicação concurrency-safe.
|
||||
func inc(i int, c chan int) {
|
||||
c <- i + 1 // <- é operador "enviar" quando um channel aparece à esquerda.
|
||||
}
|
||||
|
||||
// Vamos usar a função inc para incrementar números de forma concorrente.
|
||||
func learnConcurrency() {
|
||||
// A mesma função make usada anteriormente para alocar uma slice.
|
||||
// Make aloca e inicializa slices, maps, e channels.
|
||||
c := make(chan int)
|
||||
// Inicia três goroutines concorrentes. Os números serão incrementados de
|
||||
// forma concorrente, talvez em paralelo se a máquina for capaz e estiver
|
||||
// configurada correctamente. As três goroutines enviam para o mesmo canal.
|
||||
go inc(0, c) // go é a instrução para iniciar uma goroutine.
|
||||
go inc(10, c)
|
||||
go inc(-805, c)
|
||||
// Lê três resultados do channel c e imprime os seus valores.
|
||||
// Não se pode dizer em que ordem os resultados vão chegar!
|
||||
fmt.Println(<-c, <-c, <-c) // channel na direita, <- é operador "receptor".
|
||||
|
||||
cs := make(chan string) // outro channel, este lida com strings.
|
||||
cc := make(chan chan string) // channel que lida com channels de strings.
|
||||
go func() { c <- 84 }() // inicia uma goroutine para enviar um valor
|
||||
go func() { cs <- "palavroso" }() // outra vez, para o channel cs desta vez
|
||||
// A instrução select tem uma sintaxe semelhante à instrução switch mas
|
||||
// cada caso envolve uma operação com channels. Esta instrução seleciona,
|
||||
// de forma aleatória, um caso que esteja pronto para comunicar.
|
||||
select {
|
||||
case i := <-c: // o valor recebido pode ser atribuído a uma variável
|
||||
fmt.Printf("é um %T", i)
|
||||
case <-cs: // ou o valor recebido pode ser descartado
|
||||
fmt.Println("é uma string")
|
||||
case <-cc: // channel vazio, não se encontra pronto para comunicar.
|
||||
fmt.Println("não aconteceu")
|
||||
}
|
||||
// Neste ponto um valor foi recebido de um dos channels c ou cs. Uma das
|
||||
// duas goroutines iniciadas acima completou, a outra continua bloqueada.
|
||||
|
||||
learnWebProgramming() // Go faz. Você quer faze-lo também.
|
||||
}
|
||||
|
||||
// Basta apenas uma função do pacote http para iniciar um servidor web.
|
||||
func learnWebProgramming() {
|
||||
// O primeiro parâmetro de ListenAndServe é o endereço TCP onde escutar.
|
||||
// O segundo parâmetro é uma interface, especificamente http.Handler.
|
||||
err := http.ListenAndServe(":8080", pair{})
|
||||
fmt.Println(err) // não ignorar erros
|
||||
}
|
||||
|
||||
// Tornar pair um http.Handler ao implementar o seu único método, ServeHTTP.
|
||||
func (p pair) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
// Servir dados com um método de http.ResponseWriter
|
||||
w.Write([]byte("Aprendeu Go em Y minutos!"))
|
||||
}
|
||||
```
|
||||
|
||||
## Leitura Recomendada
|
||||
|
||||
A principal fonte de informação é o [web site oficial Go](http://golang.org/).
|
||||
Lá é possível seguir o tutorial, experimentar de forma iterativa, e ler muito.
|
||||
|
||||
A própria especificação da linguagem é altamente recomendada. É fácil de ler e
|
||||
incrivelmente curta (em relação ao que é habitual hoje em dia).
|
||||
|
||||
Na lista de leitura para os aprendizes de Go deve constar o [código fonte da
|
||||
biblioteca padrão](http://golang.org/src/pkg/). Exaustivamente documentado, é
|
||||
a melhor demonstração de código fácil de ler e de perceber, do estilo Go, e da
|
||||
sua escrita idiomática. Ou então clique no nome de uma função na [documentação]
|
||||
(http://golang.org/pkg/) e veja o código fonte aparecer!
|
||||
|
435
pt-br/java-pt.html.markdown
Normal file
435
pt-br/java-pt.html.markdown
Normal file
@ -0,0 +1,435 @@
|
||||
---
|
||||
|
||||
language: java
|
||||
contributors:
|
||||
- ["Jake Prather", "http://github.com/JakeHP"]
|
||||
- ["Madison Dickson", "http://github.com/mix3d"]
|
||||
translators:
|
||||
- ["Victor Kléber Santos L. Melo", "http://victormelo.com.br/blog"]
|
||||
- ["Renê Douglas N. de Morais", "mailto:rene.douglas.bsi@gmail.com"]
|
||||
lang: pt-br
|
||||
filename: LearnJava.java
|
||||
|
||||
---
|
||||
|
||||
Java é uma linguagem de programação de propósito geral, concorrente, baseada em classes e orientada a objetos.
|
||||
[Leia mais aqui](http://docs.oracle.com/javase/tutorial/java/index.html)
|
||||
|
||||
```java
|
||||
// Comentários de uma linha começam com //
|
||||
/*
|
||||
Comentários de várias linhas são feitos dessa forma.
|
||||
*/
|
||||
/**
|
||||
Comentários JavaDoc são feitos assim. São usados para descrever a Classe ou os atributos da Classe.
|
||||
*/
|
||||
|
||||
// Importa a classe ArrayList que está dentro do pacote java.util
|
||||
import java.util.ArrayList;
|
||||
// Importa todas as classes que estão dentro do pacote java.security
|
||||
import java.security.*;
|
||||
|
||||
// Cada arquivo .java contém uma classe pública, com o mesmo nome do arquivo.
|
||||
public class LearnJava {
|
||||
|
||||
// Um programa precisa ter um método main como um ponto de entrada.
|
||||
public static void main (String[] args) {
|
||||
|
||||
// O System.out.println é usado para imprimir no console
|
||||
System.out.println("Olá Mundo!");
|
||||
System.out.println(
|
||||
"Integer: " + 10 +
|
||||
" Double: " + 3.14 +
|
||||
" Boolean: " + true);
|
||||
|
||||
// Para imprimir sem inserir uma nova lina, use o System.out.print
|
||||
System.out.print("Olá ");
|
||||
System.out.print("Mundo");
|
||||
|
||||
|
||||
///////////////////////////////////////
|
||||
// Tipos & Variáveis
|
||||
///////////////////////////////////////
|
||||
|
||||
// Declara-se variáveis usando <tipo> <nome> [
|
||||
// Byte - inteiro de 8 bits com sinal complementado a dois
|
||||
// (-128 <= byte <= 127)
|
||||
byte fooByte = 100;
|
||||
|
||||
// Short - inteiro de 16 bits com sinal complementado a dois
|
||||
// (-32,768 <= short <= 32,767)
|
||||
short fooShort = 10000;
|
||||
|
||||
// Integer - inteiro de 32 bits com sinal complementado a dois
|
||||
// (-2,147,483,648 <= int <= 2,147,483,647)
|
||||
int fooInt = 1;
|
||||
|
||||
// Long - inteiro de 64 bits com sinal complementado a dois
|
||||
// (-9,223,372,036,854,775,808 <= long <= 9,223,372,036,854,775,807)
|
||||
long fooLong = 100000L;
|
||||
// L é usado para indicar que o valor da variável é do tipo Long;
|
||||
// sem o L, tudo é tratado como inteiro por padrão.
|
||||
|
||||
// Nota: Java não tem tipos sem sinal
|
||||
|
||||
// Float - Ponto Flutuante 32-bits, de precisão simples no padrão IEEE 754
|
||||
float fooFloat = 234.5f;
|
||||
// f é usado para indicar que o valor da variável é do tipo float;
|
||||
// caso contrário, ela é tratada como double.
|
||||
|
||||
// Double - Ponto Flutuante 64-bits, de precisão dupla no padrão IEEE 754
|
||||
double fooDouble = 123.4;
|
||||
|
||||
// Boolean - true & false
|
||||
boolean fooBoolean = true;
|
||||
boolean barBoolean = false;
|
||||
|
||||
// Char - Um caractere Unicode de 16 bits
|
||||
char fooChar = 'A';
|
||||
|
||||
// Usa-se o final para fazer com que a variável seja imutável.
|
||||
final int HORAS_QUE_TRABALHEI_POR_SEMANA = 9001;
|
||||
|
||||
// Strings
|
||||
String fooString = "Aqui está minha String!";
|
||||
|
||||
// \n é um caractere de escape que inicia uma nova linha
|
||||
String barString = "Imprimir em uma nova linha?\nSem problemas!";
|
||||
// \t é um caractere de escape que adiciona um caractere de tabulação
|
||||
String bazString = "Você quer adicionar tabulação?\tSem problemas!";
|
||||
System.out.println(fooString);
|
||||
System.out.println(barString);
|
||||
System.out.println(bazString);
|
||||
|
||||
// Arrays
|
||||
//O tamanho do array precisa ser determinado na sua declaração
|
||||
//O formato para declarar um array é:
|
||||
//<tipo de dado> [] <nome da variável> = new <tipo de dado>[<tamanho do array>];
|
||||
int [] intArray = new int[10];
|
||||
String [] stringArray = new String[1];
|
||||
boolean [] booleanArray = new boolean[100];
|
||||
|
||||
// Outra maneira de declarar e inicializar um array
|
||||
int [] y = {9000, 1000, 1337};
|
||||
|
||||
// Indexando um array - Acessando um elemento
|
||||
System.out.println("intArray no índice 0: " + intArray[0]);
|
||||
|
||||
// O primeiro termo de um array é o 0 e eles são mutáveis.
|
||||
intArray[1] = 1;
|
||||
System.out.println("intArray no índice 1: " + intArray[1]); // => 1
|
||||
|
||||
// Outras estruturas que devem ser vistas
|
||||
// ArrayLists - São parecidos com os arrays, porém oferecem mais funcionalidades
|
||||
// e o tamanho é mutável.
|
||||
// LinkedLists
|
||||
// Maps
|
||||
// HashMaps
|
||||
|
||||
///////////////////////////////////////
|
||||
// Operadores
|
||||
///////////////////////////////////////
|
||||
System.out.println("\n->Operadores");
|
||||
|
||||
int i1 = 1, i2 = 2; // Forma abreviada de escrever múltiplas declarações.
|
||||
|
||||
// Aritmética é feita da forma convencional
|
||||
System.out.println("1+2 = " + (i1 + i2)); // => 3
|
||||
System.out.println("2-1 = " + (i2 - i1)); // => 1
|
||||
System.out.println("2*1 = " + (i2 * i1)); // => 2
|
||||
System.out.println("1/2 = " + (i1 / i2)); // => 0 (0.5 arredondado para baixo)
|
||||
|
||||
// Módulo
|
||||
System.out.println("11%3 = "+(11 % 3)); // => 2
|
||||
|
||||
// Operadores de comparação
|
||||
System.out.println("3 == 2? " + (3 == 2)); // => false
|
||||
System.out.println("3 != 2? " + (3 != 2)); // => true
|
||||
System.out.println("3 > 2? " + (3 > 2)); // => true
|
||||
System.out.println("3 < 2? " + (3 < 2)); // => false
|
||||
System.out.println("2 <= 2? " + (2 <= 2)); // => true
|
||||
System.out.println("2 >= 2? " + (2 >= 2)); // => true
|
||||
|
||||
// Operadores bit-a-bit!
|
||||
/*
|
||||
~ Complemento de um
|
||||
<< Deslocamento a esquerda com sinal
|
||||
>> Deslocamento a direita com sinal
|
||||
>>> Deslocamento a direita sem sinal
|
||||
& E bit-a-bit
|
||||
| OU bit-a-bit
|
||||
^ OU exclusivo bit-a-bit
|
||||
*/
|
||||
|
||||
// Incrementações
|
||||
int i = 0;
|
||||
System.out.println("\n->Inc/Dec-rementação");
|
||||
System.out.println(i++); //i = 1. Pós-Incrementação
|
||||
System.out.println(++i); //i = 2. Pre-Incrementação
|
||||
System.out.println(i--); //i = 1. Pós-Decrementação
|
||||
System.out.println(--i); //i = 0. Pre-Decrementação
|
||||
|
||||
///////////////////////////////////////
|
||||
// Estruturas de Controle
|
||||
///////////////////////////////////////
|
||||
System.out.println("\n->Estruturas de Controle");
|
||||
|
||||
// Os comandos If são parecidos com o da linguagem C
|
||||
int j = 10;
|
||||
if (j == 10){
|
||||
System.out.println("Eu serei impresso");
|
||||
} else if (j > 10) {
|
||||
System.out.println("Eu não");
|
||||
} else {
|
||||
System.out.println("Eu também não");
|
||||
}
|
||||
|
||||
// O Loop While
|
||||
int fooWhile = 0;
|
||||
while(fooWhile < 100)
|
||||
{
|
||||
//System.out.println(fooWhile);
|
||||
//Incrementando o contador
|
||||
//Iteração feita 99 vezes, fooWhile 0->99
|
||||
fooWhile++;
|
||||
}
|
||||
System.out.println("Valor do fooWhile: " + fooWhile);
|
||||
|
||||
// O Loop Do While
|
||||
int fooDoWhile = 0;
|
||||
do
|
||||
{
|
||||
//System.out.println(fooDoWhile);
|
||||
//Incrementando o contador
|
||||
//Iteração feita 99 vezes, fooDoWhile 0->99
|
||||
fooDoWhile++;
|
||||
}while(fooDoWhile < 100);
|
||||
System.out.println("Valor do fooDoWhile: " + fooDoWhile);
|
||||
|
||||
// O Loop For
|
||||
int fooFor;
|
||||
//estrutura do loop for => for(<operação_de_início>; <condição>; <passo>)
|
||||
for(fooFor=0; fooFor<10; fooFor++){
|
||||
//System.out.println(fooFor);
|
||||
//Iteração feita 10 vezes, fooFor 0->9
|
||||
}
|
||||
System.out.println("Valor do fooFor: " + fooFor);
|
||||
|
||||
// O Loop For Each
|
||||
// Itera automaticamente por um array ou lista de objetos.
|
||||
int[] fooList = {1,2,3,4,5,6,7,8,9};
|
||||
//estrutura do loop for each => for(<objeto> : <array_de_objeto>)
|
||||
//lê-se: para cada objeto no array
|
||||
//nota: o tipo do objeto deve ser o mesmo do array.
|
||||
|
||||
for( int bar : fooList ){
|
||||
//System.out.println(bar);
|
||||
//Itera 9 vezes e imprime 1-9 em novas linhas
|
||||
}
|
||||
|
||||
// Switch
|
||||
// Um switch funciona com os tipos de dados: byte, short, char e int
|
||||
// Ele também funciona com tipos enumerados (vistos em tipos Enum)
|
||||
// como também a classe String e algumas outras classes especiais
|
||||
// tipos primitivos: Character, Byte, Short e Integer
|
||||
int mes = 3;
|
||||
String mesString;
|
||||
switch (mes){
|
||||
case 1:
|
||||
mesString = "Janeiro";
|
||||
break;
|
||||
case 2:
|
||||
mesString = "Fevereiro";
|
||||
break;
|
||||
case 3:
|
||||
mesString = "Março";
|
||||
break;
|
||||
default:
|
||||
mesString = "Algum outro mês";
|
||||
break;
|
||||
}
|
||||
System.out.println("Resultado do Switch: " + mesString);
|
||||
|
||||
// Condição de forma abreviada.
|
||||
// Você pode usar o operador '?' para atribuições rápidas ou decisões lógicas.
|
||||
// Lê-se "Se (declaração) é verdadeira, use <primeiro valor>
|
||||
// caso contrário, use <segundo valor>".
|
||||
int foo = 5;
|
||||
String bar = (foo < 10) ? "A" : "B";
|
||||
System.out.println(bar); //Imprime A, pois a condição é verdadeira.
|
||||
|
||||
|
||||
///////////////////////////////////////
|
||||
// Convertendo tipos de dados e Casting
|
||||
///////////////////////////////////////
|
||||
|
||||
//Conversão de Dados
|
||||
|
||||
//Convertendo String para Inteiro.
|
||||
Integer.parseInt("123");//retorna uma versão inteira de "123".
|
||||
|
||||
//Convertendo Inteiro para String
|
||||
Integer.toString(123);//retorna uma versão String de 123.
|
||||
|
||||
// Para outras conversões confira as seguintes classes
|
||||
// Double
|
||||
// Long
|
||||
// String
|
||||
|
||||
// Casting
|
||||
// Você pode também converter objetos java, há vários detalhes e
|
||||
// lida com alguns conceitos intermediários
|
||||
// Dê uma olhada no link:
|
||||
// http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html
|
||||
|
||||
|
||||
///////////////////////////////////////
|
||||
// Classes e Métodos
|
||||
///////////////////////////////////////
|
||||
|
||||
System.out.println("\n->Classes e Métodos");
|
||||
|
||||
// (segue a definição da classe Bicicleta)
|
||||
|
||||
// Use o new para instanciar uma classe
|
||||
Bicicleta caloi = new Bicicleta(); // Objeto caloi criado.
|
||||
|
||||
// Chame os métodos do objeto
|
||||
caloi.aumentarVelocidade(3); // Você deve sempre usar métodos para modificar variáveis
|
||||
caloi.setRitmo(100);
|
||||
|
||||
// toString é uma convenção para mostrar o valor deste objeto.
|
||||
System.out.println("informações de caloi: " + caloi.toString());
|
||||
|
||||
} // Fim do método main
|
||||
} // Fim da classe LearnJava
|
||||
|
||||
|
||||
// Você pode incluir outras classes que não são públicas num arquivo .java
|
||||
|
||||
|
||||
// Sintaxe de declaração de Classe.
|
||||
// <public/private/protected> class <nome da classe>{
|
||||
// // atributos, construtores e todos os métodos.
|
||||
// // funções são chamadas de métodos em Java.
|
||||
// }
|
||||
|
||||
class Bicicleta {
|
||||
|
||||
// Atributos/Variáveis da classe Bicicleta.
|
||||
public int ritmo; // Public: Pode ser acessada em qualquer lugar.
|
||||
private int velocidade; // Private: Apenas acessível a classe.
|
||||
protected int catraca; // Protected: Acessível a classe e suas subclasses.
|
||||
String nome; // default: Apenas acessível ao pacote.
|
||||
|
||||
// Construtores são uma forma de criação de classes
|
||||
// Este é o construtor padrão.
|
||||
public Bicicleta() {
|
||||
catraca = 1;
|
||||
ritmo = 50;
|
||||
velocidade = 5;
|
||||
nome = "Bontrager";
|
||||
}
|
||||
|
||||
// Este é um construtor específico (ele contém argumentos).
|
||||
public Bicicleta (int ritmoInicial, int velocidadeInicial, int catracaInicial, String nome) {
|
||||
this.catraca = catracaInicial;
|
||||
this.ritmo = ritmoInicial;
|
||||
this.velocidade = velocidadeInicial;
|
||||
this.nome = nome;
|
||||
}
|
||||
|
||||
// Sintaxe de um método:
|
||||
// <public/private/protected> <tipo de retorno> <nome do método>(<args>) //
|
||||
|
||||
// Classes em Java costumam implementar métodos getters e setters para seus campos.
|
||||
|
||||
// Sintaxe de declaração de métodos
|
||||
// <escopo> <tipo de retorno> <nome do método>(<args>) //
|
||||
public int getRitmo() {
|
||||
return ritmo;
|
||||
}
|
||||
|
||||
// Métodos do tipo void não requerem declaração de retorno.
|
||||
public void setRitmo(int novoValor) {
|
||||
ritmo = novoValor;
|
||||
}
|
||||
|
||||
public void setEquipamento(int novoValor) {
|
||||
catraca = novoValor;
|
||||
}
|
||||
|
||||
public void aumentarVelocidade(int incremento) {
|
||||
velocidade += incremento;
|
||||
}
|
||||
|
||||
public void diminuirVelocidade(int decremento) {
|
||||
velocidade -= decremento;
|
||||
}
|
||||
|
||||
public void setNome(String novoNome) {
|
||||
nome = novoNome;
|
||||
}
|
||||
|
||||
public String getNome() {
|
||||
return nome; // retorna um dado do tipo String.
|
||||
}
|
||||
|
||||
//Método para mostrar os valores dos atributos deste objeto.
|
||||
@Override
|
||||
public String toString() {
|
||||
return "catraca: " + catraca +
|
||||
" ritmo: " + ritmo +
|
||||
" velocidade: " + velocidade +
|
||||
" nome: " + nome;
|
||||
}
|
||||
} // fim classe Bicicleta
|
||||
|
||||
// Velocipede é uma subclasse de bicicleta.
|
||||
class Velocipede extends Bicicleta {
|
||||
// (Velocípedes são bicicletas com rodas dianteiras grandes
|
||||
// Elas não possuem catraca.)
|
||||
|
||||
public Velocipede(int ritmoInicial, int velocidadeInicial){
|
||||
// Chame o construtor do pai (construtor de Bicicleta) com o comando super.
|
||||
super(ritmoInicial, velocidadeInicial, 0, "PennyFarthing");
|
||||
}
|
||||
|
||||
// Você pode marcar um método que você está substituindo com uma @annotation
|
||||
// Para aprender mais sobre o que são as annotations e sua finalidade
|
||||
// dê uma olhada em: http://docs.oracle.com/javase/tutorial/java/annotations/
|
||||
@Override
|
||||
public void setEquipamento(int catraca) {
|
||||
catraca = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Leitura Recomendada
|
||||
|
||||
Os links fornecidos aqui abaixo são apenas para ter uma compreensão do tema, use o Google e encontre exemplos específicos.
|
||||
|
||||
Outros tópicos para pesquisar:
|
||||
|
||||
* [Tutorial Java para Sun Trail / Oracle](http://docs.oracle.com/javase/tutorial/index.html)
|
||||
|
||||
* [Modificadores de acesso do Java](http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html)
|
||||
|
||||
* [Coceitos de Programação Orientada à Objetos](http://docs.oracle.com/javase/tutorial/java/concepts/index.html):
|
||||
* [Herança](http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html)
|
||||
* [Polimorfismo](http://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html)
|
||||
* [Abstração](http://docs.oracle.com/javase/tutorial/java/IandI/abstract.html)
|
||||
|
||||
* [Exceções](http://docs.oracle.com/javase/tutorial/essential/exceptions/index.html)
|
||||
|
||||
* [Interfaces](http://docs.oracle.com/javase/tutorial/java/IandI/createinterface.html)
|
||||
|
||||
* [Tipos Genéricos](http://docs.oracle.com/javase/tutorial/java/generics/index.html)
|
||||
|
||||
* [Conversões de código Java](http://www.oracle.com/technetwork/java/codeconv-138413.html)
|
||||
|
||||
Livros:
|
||||
|
||||
* [Use a cabeça, Java] (http://www.headfirstlabs.com/books/hfjava/)
|
700
pt-br/php-pt.html.markdown
Normal file
700
pt-br/php-pt.html.markdown
Normal file
@ -0,0 +1,700 @@
|
||||
---
|
||||
language: php
|
||||
contributors:
|
||||
- ["Malcolm Fell", "http://emarref.net/"]
|
||||
- ["Trismegiste", "https://github.com/Trismegiste"]
|
||||
translators:
|
||||
- ["Abdala Cerqueira", "http://abda.la"]
|
||||
- ["Raquel Diniz", "http://twitter.com/raquelrdiniz"]
|
||||
lang: pt-br
|
||||
filename: learnphp-pt.php
|
||||
---
|
||||
|
||||
Este documento descreve PHP 5+.
|
||||
|
||||
```php
|
||||
<?php // O código PHP deve estar incluso na tag <?php
|
||||
|
||||
// Se o arquivo PHP só contém código PHP, a melhor prática
|
||||
// é omitir a tag de fechamento PHP.
|
||||
|
||||
// Duas barras iniciam o comentário de uma linha.
|
||||
|
||||
# O hash (aka pound symbol) também inicia, mas // é mais comum
|
||||
|
||||
/*
|
||||
O texto envolto por barra-asterisco e asterisco-barra
|
||||
faz um comentário de múltiplas linhas
|
||||
*/
|
||||
|
||||
// Utilize "echo" ou "print" para imprimir a saída
|
||||
print('Olá '); // Imprime "Olá " sem quebra de linha
|
||||
|
||||
// () são opcionais para print e echo
|
||||
echo "Mundo\n"; // Imprime "Mundo" com quebra de linha
|
||||
// (Todas as declarações devem terminar com um ponto e vírgula)
|
||||
|
||||
// Qualquer coisa fora da tag <?php é impresso automaticamente
|
||||
?>
|
||||
Olá mundo novamente!
|
||||
<?php
|
||||
|
||||
|
||||
/************************************
|
||||
* Tipos e variáveis
|
||||
*/
|
||||
|
||||
// Variáveis começam com o símbolo $.
|
||||
// Um nome de variável válido se inicia com uma letra ou sublinhado,
|
||||
// seguido por qualquer quantidade de letras, números ou sublinhados.
|
||||
|
||||
// Valores booleanos não diferenciam maiúsculo de minúsculo (case-insensitive)
|
||||
$boolean = true; // ou TRUE ou True
|
||||
$boolean = false; // ou FALSE ou False
|
||||
|
||||
// Inteiros
|
||||
$int1 = 12; // => 12
|
||||
$int2 = -12; // => -12
|
||||
$int3 = 012; // => 10 (um 0 denota um número octal)
|
||||
$int4 = 0x0F; // => 15 (um 0x denota um literal hex)
|
||||
|
||||
// Flutuantes - Floats (aka doubles)
|
||||
$float = 1.234;
|
||||
$float = 1.2e3;
|
||||
$float = 7E-10;
|
||||
|
||||
// Excluir variável
|
||||
unset($int1)
|
||||
|
||||
// Aritmética
|
||||
$soma = 1 + 1; // 2
|
||||
$diferenca = 2 - 1; // 1
|
||||
$produto = 2 * 2; // 4
|
||||
$quociente = 2 / 1; // 2
|
||||
|
||||
// Taquigrafia aritmética
|
||||
$numero = 0;
|
||||
$numero += 1; // Incrementa $number em 1
|
||||
echo $numero++; // Imprime 1 (incrementa após a avaliação)
|
||||
echo ++$numero; // Imprime 3 (incrementa antes da avaliação)
|
||||
$numero /= $float; // Divide e atribui o quociente de $numero
|
||||
|
||||
// Strings podem ser colocadas entre aspas simples
|
||||
$sgl_quotes = '$String'; // => '$String'
|
||||
|
||||
// Evite o uso de aspas duplas, exceto para incorporar outras variáveis
|
||||
$dbl_quotes = "Esta é uma $sgl_quotes."; // => 'Esta é uma $String.'
|
||||
|
||||
// Os caracteres especiais só são escapados entre aspas duplas
|
||||
$escapado = "Este contém um \t caractere tab.";
|
||||
$naoescapado = 'Este contém somente a barra e o t: \t';
|
||||
|
||||
// Coloque uma variável entre chaves se necessário
|
||||
$dinheiro = "Eu tenho $${numero} no banco.";
|
||||
|
||||
// Desde o PHP 5.3, nowdocs podem ser usados para múltiplas linhas sem análise
|
||||
$nowdoc = <<<'FIM'
|
||||
múltiplas linhas
|
||||
string
|
||||
FIM;
|
||||
|
||||
// Heredocs farão a análise
|
||||
$heredoc = <<<FIM
|
||||
múltiplas linhas
|
||||
$sgl_quotes
|
||||
FIM;
|
||||
|
||||
// Concatenação de string é feita com .
|
||||
echo 'Esta string ' . 'é concatenada';
|
||||
|
||||
|
||||
/********************************
|
||||
* Constantes
|
||||
*/
|
||||
|
||||
// Uma constante é definida usando define()
|
||||
// e nunca pode ser mudada durante a execução!
|
||||
|
||||
// Um nome de constante válida começa com uma letra ou sublinhado,
|
||||
// seguido por qualquer quantidade de letras, números ou sublinhados.
|
||||
define("FOO", "alguma coisa");
|
||||
|
||||
// Acesso a uma constante é possível usando diretamente o nome escolhido
|
||||
echo 'Isto sairá '.FOO;
|
||||
|
||||
|
||||
/********************************
|
||||
* Arrays
|
||||
*/
|
||||
|
||||
// Todos os arrays em PHP são arrays associativos (hashmaps),
|
||||
|
||||
// Funciona com todas as versões do PHP
|
||||
$associativo = array('Um' => 1, 'Dois' => 2, 'Tres' => 3);
|
||||
|
||||
// PHP 5.4 introduziu uma nova sintaxe
|
||||
$associativo = ['Um' => 1, 'Dois' => 2, 'Tres' => 3];
|
||||
|
||||
echo $associativo['Um']; // imprime 1
|
||||
|
||||
// Uma lista de literais atribui chaves inteiras implicitamente
|
||||
$array = ['Um', 'Dois', 'Tres'];
|
||||
echo $array[0]; // => "Um"
|
||||
|
||||
// Adiciona um elemento no final do array
|
||||
$array[] = 'Quatro';
|
||||
|
||||
// Remove um elemento do array
|
||||
unset($array[3]);
|
||||
|
||||
/********************************
|
||||
* Saída
|
||||
*/
|
||||
|
||||
echo('Olá Mundo!');
|
||||
// Imprime Olá Mundo! para stdout.
|
||||
// Stdout é uma página web se executado em um navegador.
|
||||
|
||||
print('Olá Mundo!'); // O mesmo que o echo
|
||||
|
||||
// echo é atualmente um construtor de linguagem, então você pode
|
||||
// remover os parênteses.
|
||||
echo 'Olá Mundo!';
|
||||
print 'Olá Mundo!'; // O print também é
|
||||
|
||||
$paragrafo = 'parágrafo';
|
||||
|
||||
echo 100; // Imprime valores escalares diretamente
|
||||
echo $paragrafo; // ou variáveis
|
||||
|
||||
// Se a abertura de tags curtas está configurada, ou sua versão do PHP é
|
||||
// 5.4.0 ou maior, você pode usar a sintaxe de echo curto
|
||||
?>
|
||||
<p><?= $paragrafo ?></p>
|
||||
<?php
|
||||
|
||||
$x = 1;
|
||||
$y = 2;
|
||||
$x = $y; // $x agora contém o mesmo valor de $y
|
||||
$z = &$y;
|
||||
// $z agora contém uma referência para $y. Mudando o valor de
|
||||
// $z irá mudar o valor de $y também, e vice-versa.
|
||||
// $x irá permanecer inalterado com o valor original de $y
|
||||
|
||||
echo $x; // => 2
|
||||
echo $z; // => 2
|
||||
$y = 0;
|
||||
echo $x; // => 2
|
||||
echo $z; // => 0
|
||||
|
||||
// Despeja tipos e valores de variável para o stdout
|
||||
var_dump($z); // imprime int(0)
|
||||
|
||||
// Imprime variáveis para stdout em formato legível para humanos
|
||||
print_r($array); // imprime: Array ( [0] => Um [1] => Dois [2] => Tres )
|
||||
|
||||
/********************************
|
||||
* Lógica
|
||||
*/
|
||||
$a = 0;
|
||||
$b = '0';
|
||||
$c = '1';
|
||||
$d = '1';
|
||||
|
||||
// assert lança um aviso se o seu argumento não é verdadeiro
|
||||
|
||||
// Estas comparações serão sempre verdadeiras, mesmo que os tipos
|
||||
// não sejam os mesmos.
|
||||
assert($a == $b); // igualdade
|
||||
assert($c != $a); // desigualdade
|
||||
assert($c <> $a); // alternativa para desigualdade
|
||||
assert($a < $c);
|
||||
assert($c > $b);
|
||||
assert($a <= $b);
|
||||
assert($c >= $d);
|
||||
|
||||
// A seguir, só serão verdadeiras se os valores correspondem e são do mesmo tipo.
|
||||
assert($c === $d);
|
||||
assert($a !== $d);
|
||||
assert(1 == '1');
|
||||
assert(1 !== '1');
|
||||
|
||||
// As variáveis podem ser convertidas entre tipos, dependendo da sua utilização.
|
||||
|
||||
$inteiro = 1;
|
||||
echo $inteiro + $inteiro; // => 2
|
||||
|
||||
$string = '1';
|
||||
echo $string + $string; // => 2 (strings são coagidas para inteiros)
|
||||
|
||||
$string = 'one';
|
||||
echo $string + $string; // => 0
|
||||
// Imprime 0 porque o operador + não pode fundir a string 'um' para um número
|
||||
|
||||
// Tipo de fundição pode ser utilizado para tratar uma variável
|
||||
// como um outro tipo
|
||||
|
||||
$booleano = (boolean) 1; // => true
|
||||
|
||||
$zero = 0;
|
||||
$booleano = (boolean) $zero; // => false
|
||||
|
||||
// Há também funções dedicadas para fundir a maioria dos tipos
|
||||
$inteiro = 5;
|
||||
$string = strval($inteiro);
|
||||
|
||||
$var = null; // valor Null
|
||||
|
||||
|
||||
/********************************
|
||||
* Estruturas de controle
|
||||
*/
|
||||
|
||||
if (true) {
|
||||
print 'Eu fico impresso';
|
||||
}
|
||||
|
||||
if (false) {
|
||||
print 'Eu não\'t';
|
||||
} else {
|
||||
print 'Eu fico impresso';
|
||||
}
|
||||
|
||||
if (false) {
|
||||
print 'Não fica impresso';
|
||||
} elseif(true) {
|
||||
print 'Fica';
|
||||
}
|
||||
|
||||
// operadores ternários
|
||||
print (false ? 'Não fica impresso' : 'Fica');
|
||||
|
||||
$x = 0;
|
||||
if ($x === '0') {
|
||||
print 'Não imprime';
|
||||
} elseif($x == '1') {
|
||||
print 'Não imprime';
|
||||
} else {
|
||||
print 'Imprime';
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Esta sintaxe alternativa é útil para modelos (templates)
|
||||
?>
|
||||
|
||||
<?php if ($x): ?>
|
||||
Isto é exibido se o teste for verdadeiro.
|
||||
<?php else: ?>
|
||||
Isto é apresentado caso contrário.
|
||||
<?php endif; ?>
|
||||
|
||||
<?php
|
||||
|
||||
// Use switch para salvar alguma lógica.
|
||||
switch ($x) {
|
||||
case '0':
|
||||
print 'Switch faz coerção de tipo';
|
||||
break; // Você deve incluir uma pausa, ou você vai cair
|
||||
// no caso 'dois' e 'tres'
|
||||
case 'dois':
|
||||
case 'tres':
|
||||
// Faz alguma coisa, se a variável é 'dois' ou 'tres'
|
||||
break;
|
||||
default:
|
||||
// Faz algo por padrão
|
||||
}
|
||||
|
||||
// While, do...while e for são repetições provavelmente familiares
|
||||
$i = 0;
|
||||
while ($i < 5) {
|
||||
echo $i++;
|
||||
}; // Imprime "01234"
|
||||
|
||||
echo "\n";
|
||||
|
||||
$i = 0;
|
||||
do {
|
||||
echo $i++;
|
||||
} while ($i < 5); // Imprime "01234"
|
||||
|
||||
echo "\n";
|
||||
|
||||
for ($x = 0; $x < 10; $x++) {
|
||||
echo $x;
|
||||
} // Imprime "0123456789"
|
||||
|
||||
echo "\n";
|
||||
|
||||
$rodas = ['bicicleta' => 2, 'carro' => 4];
|
||||
|
||||
// Repetições foreach podem iterar sobre arrays
|
||||
foreach ($rodas as $contador_rodas) {
|
||||
echo $contador_rodas;
|
||||
} // Imprime "24"
|
||||
|
||||
echo "\n";
|
||||
|
||||
// Você pode iterar sobre as chaves, bem como os valores
|
||||
foreach ($rodas as $veiculo => $contador_rodas) {
|
||||
echo "O $veiculo tem $contador_rodas rodas";
|
||||
}
|
||||
|
||||
echo "\n";
|
||||
|
||||
$i = 0;
|
||||
while ($i < 5) {
|
||||
if ($i === 3) {
|
||||
break; // Sai da repetição
|
||||
}
|
||||
echo $i++;
|
||||
} // Imprime "012"
|
||||
|
||||
for ($i = 0; $i < 5; $i++) {
|
||||
if ($i === 3) {
|
||||
continue; // Ignora esta iteração da repetição
|
||||
}
|
||||
echo $i;
|
||||
} // Imprime "0124"
|
||||
|
||||
|
||||
/********************************
|
||||
* Functions
|
||||
*/
|
||||
|
||||
// Define a função com "function":
|
||||
function minha_funcao () {
|
||||
return 'Olá';
|
||||
}
|
||||
|
||||
echo minha_funcao(); // => "Olá"
|
||||
|
||||
// Um nome de função válido começa com uma letra ou sublinhado,
|
||||
// seguido por qualquer quantidade de letras, números ou sublinhados.
|
||||
|
||||
function adicionar($x, $y = 1) { // $y é opcional e o valor padrão é 1
|
||||
$resultado = $x + $y;
|
||||
return $resultado;
|
||||
}
|
||||
|
||||
echo adicionar(4); // => 5
|
||||
echo adicionar(4, 2); // => 6
|
||||
|
||||
// $resultado não é acessível fora da função
|
||||
// print $resultado; // Dá uma aviso.
|
||||
|
||||
// Desde o PHP 5.3 você pode declarar funções anônimas
|
||||
$inc = function ($x) {
|
||||
return $x + 1;
|
||||
};
|
||||
|
||||
echo $inc(2); // => 3
|
||||
|
||||
function foo ($x, $y, $z) {
|
||||
echo "$x - $y - $z";
|
||||
}
|
||||
|
||||
// Funções podem retornar funções
|
||||
function bar ($x, $y) {
|
||||
// Utilize 'use' para trazer variáveis de fora
|
||||
return function ($z) use ($x, $y) {
|
||||
foo($x, $y, $z);
|
||||
};
|
||||
}
|
||||
|
||||
$bar = bar('A', 'B');
|
||||
$bar('C'); // Imprime "A - B - C"
|
||||
|
||||
// Você pode chamar funções nomeadas usando strings
|
||||
$nome_funcao = 'add';
|
||||
echo $nome_funcao(1, 2); // => 3
|
||||
// Útil para dinamicamente determinar qual função será executada.
|
||||
// Ou utilize call_user_func(callable $callback [, $parameter [, ... ]]);
|
||||
|
||||
/********************************
|
||||
* Includes (Incluir)
|
||||
*/
|
||||
|
||||
<?php
|
||||
// PHP dentro de arquivos incluídos também deve começar com uma tag
|
||||
// de abertura do PHP.
|
||||
|
||||
include 'meu-arquivo.php';
|
||||
// O código meu-arquivo.php já está disponível no escopo atual.
|
||||
// Se o arquivo não pode ser incluído (por exemplo, arquivo não encontrado),
|
||||
//um aviso é emitido.
|
||||
|
||||
include_once 'meu-arquivo.php';
|
||||
// Se o código no meu-arquivo.php foi incluído em outro lugar, ele não vai
|
||||
// ser incluído novamente. Isso evita vários erros de declaração de classe
|
||||
|
||||
require 'meu-arquivo.php';
|
||||
require_once 'meu-arquivo.php';
|
||||
// Faz o mesmo que o include(), exceto que o require() irá causar um erro fatal
|
||||
// se o arquivo não puder ser incluído
|
||||
|
||||
// Conteúdo de meu-include.php:
|
||||
<?php
|
||||
|
||||
return 'Qualquer coisa que você quiser.';
|
||||
// Fim do arquivo
|
||||
|
||||
// Includes e requires também podem retornar um valor.
|
||||
$valor = include 'meu-include.php';
|
||||
|
||||
// Arquivos são incluídos com base no caminho determinado ou,
|
||||
// se este não for passado, com base na diretiva de configuração include_path.
|
||||
// Se o arquivo não é encontrado no include_path, o include vai finalmente
|
||||
// verificar no próprio diretório do script chamado e no diretório
|
||||
// de trabalho atual antes de falhar.
|
||||
/* */
|
||||
|
||||
/********************************
|
||||
* Classes
|
||||
*/
|
||||
|
||||
// As classes são definidas com a palavra-chave class
|
||||
|
||||
class MinhaClasse
|
||||
{
|
||||
const MINHA_CONST = 'valor'; // Uma constante
|
||||
|
||||
static $valorEstatico = 'estatico';
|
||||
|
||||
// Variáveis estáticas e sua visibilidade
|
||||
public static $valorEstaticoPublico = 'estaticoPublico';
|
||||
// Acessível somente dentro da classe
|
||||
private static $valorEstaticoPrivado = 'estaticoPrivado';
|
||||
// Acessível a partir da classe e subclasses
|
||||
protected static $valorEstaticoProtegido = 'estaticoProtegido';
|
||||
|
||||
// Propriedades devem declarar a sua visibilidade
|
||||
public $propriedade = 'publica';
|
||||
public $propInstancia;
|
||||
protected $prot = 'protegida'; // Acessível a partir da classe e subclasses
|
||||
private $priv = 'privada'; // Acessível somente dentro da classe
|
||||
|
||||
// Criar um construtor com o __construct
|
||||
public function __construct($propInstancia) {
|
||||
// Acesse variável de instância utilizando $this
|
||||
$this->propInstancia = $propInstancia;
|
||||
}
|
||||
|
||||
// Métodos são declarados como funções dentro de uma classe
|
||||
public function meuMetodo()
|
||||
{
|
||||
print 'MinhaClasse';
|
||||
}
|
||||
|
||||
//palavra-chave final faz uma função não poder ser sobrescrita
|
||||
final function voceNaoPodeMeSobrescrever()
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Declarando propriedades ou métodos de classe como estáticos faz deles
|
||||
* acessíveis sem precisar instanciar a classe. A propriedade declarada
|
||||
* como estática não pode ser acessada com um objeto
|
||||
* instanciado da classe (embora métodos estáticos possam).
|
||||
*/
|
||||
|
||||
public static function meuMetodoEstatico()
|
||||
{
|
||||
print 'Eu sou estatico';
|
||||
}
|
||||
}
|
||||
|
||||
echo MinhaClasse::MINHA_CONST; // Imprime 'valor';
|
||||
echo MinhaClasse::$valorEstatico; // Imprime 'estatico';
|
||||
MinhaClasse::meuMetodoEstatico(); // Imprime 'Eu sou estatico';
|
||||
|
||||
// Instantiate classes using new
|
||||
$minha_classe = new MinhaClasse('Uma propriedade de instância');
|
||||
// Os parênteses são opcionais, se não passar algum argumento.
|
||||
|
||||
// Acesse membros da classe utilizando ->
|
||||
echo $minha_classe->propriedade; // => "publica"
|
||||
echo $minha_classe->instanceProp; // => "Uma propriedade de instância"
|
||||
$minha_classe->meuMetodo(); // => "MinhaClasse"
|
||||
|
||||
|
||||
// Estender classes usando "extends"
|
||||
class MinhaOutraClasse extends MinhaClasse
|
||||
{
|
||||
function imprimePropriedadeProtegida()
|
||||
{
|
||||
echo $this->prot;
|
||||
}
|
||||
|
||||
// Sobrescrever um método
|
||||
function meuMetodo()
|
||||
{
|
||||
parent::meuMetodo();
|
||||
print ' > MinhaOutraClasse';
|
||||
}
|
||||
}
|
||||
|
||||
$minha_outra_classe = new MinhaOutraClasse('Propriedade de instância');
|
||||
$minha_outra_classe->imprimePropriedadeProtegida(); // => Prints "protegida"
|
||||
$minha_outra_classe->myMethod(); // Prints "MinhaClasse > MinhaOutraClasse"
|
||||
|
||||
final class VoceNaoPodeMeEstender
|
||||
{
|
||||
}
|
||||
|
||||
// Você pode usar "métodos mágicos" para criar getters e setters
|
||||
class MinhaClasseMapa
|
||||
{
|
||||
private $propriedade;
|
||||
|
||||
public function __get($chave)
|
||||
{
|
||||
return $this->$chave;
|
||||
}
|
||||
|
||||
public function __set($chave, $valor)
|
||||
{
|
||||
$this->$chave = $valor;
|
||||
}
|
||||
}
|
||||
|
||||
$x = new MinhaClasseMapa();
|
||||
echo $x->propriedade; // Irá usar o método __get()
|
||||
$x->propriedade = 'Algo'; // Irá usar o método __set()
|
||||
|
||||
// Classes podem ser abstratas (usando a palavra-chave abstract) ou
|
||||
// implementar interfaces (usando a palavra-chave implements).
|
||||
// Uma interface é declarada com a palavra-chave interface.
|
||||
|
||||
interface InterfaceUm
|
||||
{
|
||||
public function fazAlgo();
|
||||
}
|
||||
|
||||
interface InterfaceDois
|
||||
{
|
||||
public function fazOutraCoisa();
|
||||
}
|
||||
|
||||
// interfaces podem ser estendidas
|
||||
interface InterfaceTres extends InterfaceDois
|
||||
{
|
||||
public function fazOutroContrato();
|
||||
}
|
||||
|
||||
abstract class MinhaClasseAbstrata implements InterfaceUm
|
||||
{
|
||||
public $x = 'fazAlgo';
|
||||
}
|
||||
|
||||
class MinhaClasseConcreta extends MinhaClasseAbstrata implements InterfaceDois
|
||||
{
|
||||
public function fazAlgo()
|
||||
{
|
||||
echo $x;
|
||||
}
|
||||
|
||||
public function fazOutraCoisa()
|
||||
{
|
||||
echo 'fazOutraCoisa';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Classes podem implementar mais de uma interface
|
||||
class UmaOutraClasse implements InterfaceUm, InterfaceDois
|
||||
{
|
||||
public function fazAlgo()
|
||||
{
|
||||
echo 'fazAlgo';
|
||||
}
|
||||
|
||||
public function fazOutraCoisa()
|
||||
{
|
||||
echo 'fazOutraCoisa';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/********************************
|
||||
* Traits (Traços)
|
||||
*/
|
||||
|
||||
// Traits estão disponíveis a partir de PHP 5.4.0 e
|
||||
// são declarados usando "trait"
|
||||
|
||||
trait MeuTraco
|
||||
{
|
||||
public function meuMetodoDeTraco()
|
||||
{
|
||||
print 'Eu tenho MeuTraco';
|
||||
}
|
||||
}
|
||||
|
||||
class MinhaClasseTracada
|
||||
{
|
||||
use MeuTraco;
|
||||
}
|
||||
|
||||
$cls = new MinhaClasseTracada();
|
||||
$cls->meuMetodoDeTraco(); // Imprime "Eu tenho MeuTraco"
|
||||
|
||||
|
||||
/********************************
|
||||
* Namespaces (Espaço nominal)
|
||||
*/
|
||||
|
||||
// Esta seção é separada porque a declaração de espaços nominais
|
||||
// deve ser a primeira instrução em um arquivo. Vamos fingir, aqui não é o caso
|
||||
|
||||
<?php
|
||||
|
||||
// Por padrão, as classes existem no espaço nominal global e podem
|
||||
// ser explicitamente chamadas com uma barra invertida.
|
||||
|
||||
$cls = new \MinhaClasse();
|
||||
|
||||
|
||||
|
||||
// Definir o espaço nominal para o arquivo
|
||||
namespace Meu\Espaconominal;
|
||||
|
||||
class MinhaClasse
|
||||
{
|
||||
}
|
||||
|
||||
// (de outro arquivo)
|
||||
$cls = new Meu\Espaconominal\MinhaClasse;
|
||||
|
||||
//Ou de dentro de outro espaço nominal.
|
||||
namespace Meu\Outro\Espaconominal;
|
||||
|
||||
use My\Espaconominal\MinhaClasse;
|
||||
|
||||
$cls = new MinhaClasse();
|
||||
|
||||
//Ou você pode usar como apelido de espaço nominal;
|
||||
|
||||
namespace Meu\Outro\Espaconominal;
|
||||
|
||||
use Meu\Espaconominal as OutroEspaconominal;
|
||||
|
||||
$cls = new OutroEspaconominal\MinhaClasse();
|
||||
|
||||
*/
|
||||
|
||||
```
|
||||
|
||||
## Mais informações
|
||||
|
||||
Visite a [documentação oficial do PHP](http://www.php.net/manual/)
|
||||
para referência e participação da comunidade.
|
||||
|
||||
Se você estiver interessado em melhores práticas atualizadas, visite
|
||||
[PHP The Right Way](http://www.phptherightway.com/).
|
||||
|
||||
Se você está vindo de uma linguagem com bom gerenciamento de pacotes, confira
|
||||
[Composer](http://getcomposer.org/).
|
||||
|
||||
Para os padrões comuns, visite o Grupo de Interoperabilidade de Framework PHP
|
||||
[PSR standards](https://github.com/php-fig/fig-standards).
|
@ -4,6 +4,7 @@ lang: br-pt
|
||||
filename: learnruby.rb
|
||||
contributors:
|
||||
- ["Bruno Henrique - Garu", "http://garulab.com"]
|
||||
translators:
|
||||
- ["Katyanna Moura", "https://twitter.com/amelie_kn"]
|
||||
---
|
||||
|
||||
|
84
pt-pt/brainfuck-pt.html.markdown
Normal file
84
pt-pt/brainfuck-pt.html.markdown
Normal file
@ -0,0 +1,84 @@
|
||||
---
|
||||
language: brainfuck
|
||||
contributors:
|
||||
- ["Prajit Ramachandran", "http://prajitr.github.io/"]
|
||||
- ["Mathias Bynens", "http://mathiasbynens.be/"]
|
||||
translators:
|
||||
- ["Joao Marques", "http://github.com/mrshankly"]
|
||||
lang: pt-pt
|
||||
---
|
||||
|
||||
Brainfuck (não capitalizado excepto no início de uma frase) é uma linguagem de
|
||||
programação Turing-completa extremamente simples com apenas 8 comandos.
|
||||
|
||||
```
|
||||
Qualquer caractere excepto "><+-.,[]" (não contar com as aspas) é ignorado.
|
||||
|
||||
Brainfuck é representado por um vector com 30 000 células inicializadas a zero
|
||||
e um ponteiro de dados que aponta para a célula actual.
|
||||
|
||||
Existem 8 comandos:
|
||||
+ : Incrementa o valor da célula actual em 1.
|
||||
- : Decrementa o valor da célula actual em 1.
|
||||
> : Move o ponteiro de dados para a célula seguinte (célula à direita).
|
||||
< : Move o ponteiro de dados para a célula anterior (célula à esquerda).
|
||||
. : Imprime o valor ASCII da célula actual. (ex. 65 = 'A').
|
||||
, : Lê um único caractere para a célula actual.
|
||||
[ : Se o valor da célula actual for zero, salta para o ] correspondente.
|
||||
Caso contrário, passa para a instrução seguinte.
|
||||
] : Se o valor da célula actual for zero, passa para a instrução seguinte.
|
||||
Caso contrário, volta para a instrução relativa ao [ correspondente.
|
||||
|
||||
[ e ] formam um ciclo while. Obviamente, devem ser equilibrados.
|
||||
|
||||
Vejamos alguns programas básicos de brainfuck.
|
||||
|
||||
++++++ [ > ++++++++++ < - ] > +++++ .
|
||||
|
||||
Este programa imprime a letra 'A'. Primeiro incrementa a célula #1 para 6.
|
||||
A célula #1 será usada num ciclo. Depois é iniciado o ciclo ([) e move-se
|
||||
o ponteiro de dados para a célula #2. Incrementa-se o valor da célula #1 10
|
||||
vezes, move-se o ponteiro de dados de volta para a célula #1, e decrementa-se
|
||||
a célula #1. Este ciclo acontece 6 vezes (são necessários 6 decrementos para
|
||||
a célula #1 chegar a 0, momento em que se salta para o ] correspondente,
|
||||
continuando com a instrução seguinte).
|
||||
|
||||
Nesta altura encontramo-nos na célula #1, cujo valor é 0, enquanto a célula #2
|
||||
tem o valor 60. Movemos o ponteiro de dados para a célula #2, incrementa-se 5
|
||||
vezes para um valor final de 65, é então impresso o valor da célula #2. Ao valor
|
||||
65 corresponde o caractere 'A' em ASCII, 'A' é então impresso para o terminal.
|
||||
|
||||
, [ > + < - ] > .
|
||||
|
||||
Este programa lê um caractere e copia o seu valor para a célula #1. Um ciclo é
|
||||
iniciado. Movemos o ponteiro de dados para a célula #2, incrementamos o valor na
|
||||
célula #2, movemos o ponteiro de dados de volta para a célula #1, finalmente
|
||||
decrementamos o valor na célula #1. Isto continua até o valor na célula #1 ser
|
||||
igual a 0 e a célula #2 ter o antigo valor da célula #1. Como o ponteiro de
|
||||
dados está a apontar para a célula #1 no fim do ciclo, movemos o ponteiro para a
|
||||
célula #2 e imprimimos o valor em ASCII.
|
||||
|
||||
Os espaços servem apenas para tornar o programa mais legível. Podemos escrever
|
||||
o mesmo programa da seguinte maneira:
|
||||
|
||||
,[>+<-]>.
|
||||
|
||||
Tenta descobrir o que este programa faz:
|
||||
|
||||
,>,< [ > [ >+ >+ << -] >> [- << + >>] <<< -] >>
|
||||
|
||||
Este programa lê dois números e multiplica-os.
|
||||
|
||||
Basicamente o programa pede dois caracteres ao utilizador. Depois é iniciado um
|
||||
ciclo exterior controlado pelo valor da célula #1. Movemos o ponteiro de dados
|
||||
para a célula #2 e inicia-se o ciclo interior controlado pelo valor da célula
|
||||
#2, incrementando o valor da célula #3. Contudo, existe um problema, no final do
|
||||
ciclo interior a célula #2 tem o valor 0. Para resolver este problema o valor da
|
||||
célula #4 é também incrementado e copiado para a célula #2.
|
||||
```
|
||||
|
||||
Fica então explicado brainfuck. Simples, não? Por divertimento podes escrever os
|
||||
teus próprios programas em brainfuck, ou então escrever um interpretador de
|
||||
brainfuck noutra linguagem. O interpretador é relativamente fácil de se
|
||||
implementar, mas se fores masoquista, tenta escrever um interpretador de
|
||||
brainfuck… em brainfuck.
|
416
pt-pt/git-pt.html.markdown
Normal file
416
pt-pt/git-pt.html.markdown
Normal file
@ -0,0 +1,416 @@
|
||||
---
|
||||
category: tool
|
||||
tool: git
|
||||
lang: pt-pt
|
||||
filename: LearnGit.txt
|
||||
contributors:
|
||||
- ["Jake Prather", "http://github.com/JakeHP"]
|
||||
translators:
|
||||
- ["Rafael Jegundo", "http://rafaeljegundo.github.io/"]
|
||||
---
|
||||
|
||||
Git é um sistema distribuido de gestão para código fonte e controlo de versões.
|
||||
|
||||
Funciona através de uma série de registos de estado do projecto e usa esse
|
||||
registo para permitir funcionalidades de versionamento e gestão de código
|
||||
fonte.
|
||||
|
||||
## Conceitos de versionamento
|
||||
|
||||
### O que é controlo de versões
|
||||
|
||||
Controlo de versões (*source control*) é um processo de registo de alterações
|
||||
a um ficheiro ou conjunto de ficheiros ao longo do tempo.
|
||||
|
||||
### Controlo de versões: Centralizado VS Distribuido
|
||||
|
||||
* Controlo de versões centralizado foca-se na sincronização, registo e *backup*
|
||||
de ficheiros.
|
||||
* Controlo de versões distribuido foca-se em partilhar alterações. Cada
|
||||
alteração é associada a um *id* único.
|
||||
* Sistemas distribuidos não têm estrutura definida. É possivel ter um sistema
|
||||
centralizado ao estilo SVN usando git.
|
||||
|
||||
[Informação adicional (EN)](http://git-scm.com/book/en/Getting-Started-About-Version-Control)
|
||||
|
||||
### Porquê usar git?
|
||||
|
||||
* Permite trabalhar offline.
|
||||
* Colaborar com outros é fácil!
|
||||
* Criar *branches* é fácil!
|
||||
* Fazer *merge* é fácil!
|
||||
* Git é rápido.
|
||||
* Git é flexivel.
|
||||
|
||||
## Git - Arquitectura
|
||||
|
||||
|
||||
### Repositório
|
||||
|
||||
Um conjunto de ficheiros, directórios, registos históricos, *commits* e
|
||||
referências. Pode ser imaginado como uma estrutura de dados de código fonte
|
||||
com a particularidade de cada elemento do código fonte permitir acesso ao
|
||||
histórico das suas alterações, entre outras coisas.
|
||||
|
||||
Um repositório git é constituido pelo directório .git e a *working tree*
|
||||
|
||||
### Directório .git (componente do repositório)
|
||||
|
||||
O repositório .git contém todas as configurações, *logs*, *branches*,
|
||||
referências e outros.
|
||||
|
||||
[Lista detalhada (EN)](http://gitready.com/advanced/2009/03/23/whats-inside-your-git-directory.html)
|
||||
|
||||
### *Working Tree* (componente do repositório)
|
||||
|
||||
Isto é basicamente os directórios e ficheiros do repositório. É frequentemente
|
||||
referido como o directório do projecto.
|
||||
|
||||
### *Index* (componente do directório .git)
|
||||
|
||||
O *Index* é a camada de interface no git. Consistente num elemento que separa
|
||||
o directório do projecto do repositório git. Isto permite aos programadores um
|
||||
maior controlo sobre o que é registado no repositório git.
|
||||
|
||||
### *Commit*
|
||||
|
||||
Um *commit** de git é um registo de um cojunto de alterações ou manipulações
|
||||
no nos ficheiros do projecto.
|
||||
Por exemplo, ao adicionar cinco ficheiros e remover outros 2, estas alterações
|
||||
serão gravadas num *commit* (ou registo). Este *commit* pode então ser enviado
|
||||
para outros repositórios ou não!
|
||||
|
||||
### *Branch*
|
||||
|
||||
Um *branch* é essencialmente uma referência que aponta para o último *commit*
|
||||
efetuado. à medida que são feitos novos commits, esta referência é atualizada
|
||||
automaticamente e passa a apontar para o commit mais recente.
|
||||
|
||||
### *HEAD* e *head* (componentes do directório .git)
|
||||
|
||||
*HEAD* é a referência que aponta para o *branch* em uso. Um repositório só tem
|
||||
uma *HEAD* activa.
|
||||
*head* é uma referência que aponta para qualquer *commit*. Um repositório pode
|
||||
ter um número indefinido de *heads*
|
||||
|
||||
### Recursos conceptuais (EN)
|
||||
|
||||
* [Git para Cientistas de Computação](http://eagain.net/articles/git-for-computer-scientists/)
|
||||
* [Git para Designers](http://hoth.entp.com/output/git_for_designers.html)
|
||||
|
||||
## Comandos
|
||||
|
||||
### *init*
|
||||
|
||||
Cria um repositório Git vazio. As definições, informação guardada e outros do
|
||||
repositório git são guardados num directório (pasta) denominado ".git".
|
||||
|
||||
```bash
|
||||
$ git init
|
||||
```
|
||||
|
||||
### *config*
|
||||
|
||||
Permite configurar as definições, sejam as definições do repositório, sistema
|
||||
ou configurações globais.
|
||||
|
||||
```bash
|
||||
# Imprime & Define Algumas Variáveis de Configuração Básicas (Global)
|
||||
$ git config --global user.email
|
||||
$ git config --global user.name
|
||||
|
||||
$ git config --global user.email "MyEmail@Zoho.com"
|
||||
$ git config --global user.name "My Name"
|
||||
```
|
||||
|
||||
[Aprenda Mais Sobre git config. (EN)](http://git-scm.com/docs/git-config)
|
||||
|
||||
### help
|
||||
|
||||
Para aceder rapidamente a um guia extremamente detalhada sobre cada comando.
|
||||
Ou para dar apenas uma lembraça rápida de alguma semântica.
|
||||
|
||||
```bash
|
||||
# Ver rapidamente os comandos disponiveis
|
||||
$ git help
|
||||
|
||||
# Ver todos os comandos disponiveis
|
||||
$ git help -a
|
||||
|
||||
# Requerer *help* sobre um comando especifico - manual de utilizador
|
||||
# git help <command_here>
|
||||
$ git help add
|
||||
$ git help commit
|
||||
$ git help init
|
||||
```
|
||||
|
||||
### status
|
||||
|
||||
Apresenta as diferenças entre o ficheiro *index* (no fundo a versão corrente
|
||||
do repositório) e o *commit* da *HEAD* atual.
|
||||
|
||||
|
||||
```bash
|
||||
# Apresenta o *branch*, ficheiros não monitorizados, alterações e outras
|
||||
# difereças
|
||||
$ git status
|
||||
|
||||
# Para aprender mais detalhes sobre git *status*
|
||||
$ git help status
|
||||
```
|
||||
|
||||
### add
|
||||
|
||||
Adiciona ficheiros ao repositório corrente. Se os ficheiros novos não forem
|
||||
adicionados através de `git add` ao repositório, então eles não serão
|
||||
incluidos nos commits!
|
||||
|
||||
```bash
|
||||
# adiciona um ficheiro no directório do project atual
|
||||
$ git add HelloWorld.java
|
||||
|
||||
# adiciona um ficheiro num sub-directório
|
||||
$ git add /path/to/file/HelloWorld.c
|
||||
|
||||
# permite usar expressões regulares!
|
||||
$ git add ./*.java
|
||||
```
|
||||
|
||||
### branch
|
||||
|
||||
Gere os *branches*. É possível ver, editar, criar e apagar branches com este
|
||||
comando.
|
||||
|
||||
```bash
|
||||
# listar *branches* existentes e remotos
|
||||
$ git branch -a
|
||||
|
||||
# criar um novo *branch*
|
||||
$ git branch myNewBranch
|
||||
|
||||
# apagar um *branch*
|
||||
$ git branch -d myBranch
|
||||
|
||||
# alterar o nome de um *branch*
|
||||
# git branch -m <oldname> <newname>
|
||||
$ git branch -m myBranchName myNewBranchName
|
||||
|
||||
# editar a descrição de um *branch*
|
||||
$ git branch myBranchName --edit-description
|
||||
```
|
||||
|
||||
### checkout
|
||||
|
||||
Atualiza todos os ficheiros no directório do projecto de forma a ficarem iguais
|
||||
à versão do index ou do *branch* especificado.
|
||||
|
||||
```bash
|
||||
# Checkout de um repositório - por predefinição para o branch master
|
||||
$ git checkout
|
||||
# Checkout de um branch especifico
|
||||
$ git checkout branchName
|
||||
# Cria um novo branch e faz checkout para ele.
|
||||
# Equivalente a: "git branch <name>; git checkout <name>"
|
||||
$ git checkout -b newBranch
|
||||
```
|
||||
|
||||
### clone
|
||||
|
||||
Clona ou copia um repositório existente para um novo directório. Também
|
||||
adiciona *branches* de monitorização remota para cada *branch* no repositório
|
||||
clonado o que permite enviar alterações para um *branch* remoto.
|
||||
|
||||
```bash
|
||||
# Clona learnxinyminutes-docs
|
||||
$ git clone https://github.com/adambard/learnxinyminutes-docs.git
|
||||
```
|
||||
|
||||
### commit
|
||||
|
||||
Guarda o conteudo atual do index num novo *commit*. Este *commit* contém
|
||||
as alterações feitas e a mensagem criada pelo utilizador.
|
||||
|
||||
```bash
|
||||
# commit com uma mensagem
|
||||
$ git commit -m "Added multiplyNumbers() function to HelloWorld.c"
|
||||
```
|
||||
|
||||
### diff
|
||||
|
||||
Apresenta as diferenças entre um ficheiro no repositório do projecto, *index*
|
||||
e *commits*
|
||||
|
||||
```bash
|
||||
# Apresenta a diferença entre o directório atual e o index
|
||||
$ git diff
|
||||
|
||||
# Apresenta a diferença entre o index e os commits mais recentes
|
||||
$ git diff --cached
|
||||
|
||||
# Apresenta a diferença entre o directório atual e o commit mais recente
|
||||
$ git diff HEAD
|
||||
```
|
||||
|
||||
### grep
|
||||
|
||||
Permite procurar facilmente num repositório
|
||||
|
||||
Configurações opcionais:
|
||||
|
||||
```bash
|
||||
# Obrigado a Travis Jeffery por estas
|
||||
# Define a apresentação de números de linha nos resultados do grep
|
||||
$ git config --global grep.lineNumber true
|
||||
|
||||
# Torna os resultados da pesquisa mais fáceis de ler, agrupando-os
|
||||
$ git config --global alias.g "grep --break --heading --line-number"
|
||||
```
|
||||
|
||||
```bash
|
||||
# Pesquisa por "variableName" em todos os ficheiros de java
|
||||
$ git grep 'variableName' -- '*.java'
|
||||
|
||||
# Pesquisa por uma linha que contém "arrayListName" e "add" ou "remove"
|
||||
$ git grep -e 'arrayListName' --and \( -e add -e remove \)
|
||||
```
|
||||
|
||||
Google é teu amigo; para mais exemplos:
|
||||
[Git Grep Ninja (EN)](http://travisjeffery.com/b/2012/02/search-a-git-repo-like-a-ninja)
|
||||
|
||||
### log
|
||||
|
||||
Apresenta commits do repositório.
|
||||
|
||||
```bash
|
||||
# Apresenta todos os commits
|
||||
$ git log
|
||||
|
||||
# Apresenta X commits
|
||||
$ git log -n 10
|
||||
|
||||
# Apresenta apenas commits de merge
|
||||
$ git log --merges
|
||||
```
|
||||
|
||||
### merge
|
||||
|
||||
"Merge" (junta) as alterações de commits externos com o *branch* atual.
|
||||
|
||||
```bash
|
||||
# Junta o branch especificado com o atual
|
||||
$ git merge branchName
|
||||
|
||||
# Para gerar sempre um commit ao juntar os branches
|
||||
$ git merge --no-ff branchName
|
||||
```
|
||||
|
||||
### mv
|
||||
|
||||
Alterar o nome ou mover um ficheiro.
|
||||
|
||||
```bash
|
||||
# Alterar o nome de um ficheiro
|
||||
$ git mv HelloWorld.c HelloNewWorld.c
|
||||
|
||||
# Mover um ficheiro
|
||||
$ git mv HelloWorld.c ./new/path/HelloWorld.c
|
||||
|
||||
# Forçar a alteração de nome ou mudança local
|
||||
# "existingFile" já existe no directório, será sobre-escrito.
|
||||
$ git mv -f myFile existingFile
|
||||
```
|
||||
|
||||
### pull
|
||||
|
||||
Puxa alterações de um repositório e junta-as com outro branch
|
||||
|
||||
```bash
|
||||
# Atualiza o repositório local, juntando as novas alterações
|
||||
# do repositório remoto 'origin' e branch 'master'
|
||||
# git pull <remote> <branch>
|
||||
# git pull => aplica a predefinição => git pull origin master
|
||||
$ git pull origin master
|
||||
|
||||
# Juntar alterações do branch remote e fazer rebase commits do branch
|
||||
# no repositório local, como: "git pull <remote> <branch>, git rebase <branch>"
|
||||
$ git pull origin master --rebase
|
||||
```
|
||||
|
||||
### push
|
||||
|
||||
Enviar e juntar alterações de um branch para o seu branch correspondente
|
||||
num repositório remoto.
|
||||
|
||||
```bash
|
||||
# Envia e junta as alterações de um repositório local
|
||||
# para um remoto denominado "origin" no branch "master".
|
||||
# git push <remote> <branch>
|
||||
# git push => aplica a predefinição => git push origin master
|
||||
$ git push origin master
|
||||
```
|
||||
|
||||
### rebase (cautela!)
|
||||
|
||||
Pega em todas as alterações que foram registadas num branch e volta a
|
||||
aplicá-las em outro branch.
|
||||
*Não deve ser feito rebase de commits que foram enviados para um repositório
|
||||
público*
|
||||
|
||||
```bash
|
||||
# Faz Rebase de experimentBranch para master
|
||||
# git rebase <basebranch> <topicbranch>
|
||||
$ git rebase master experimentBranch
|
||||
```
|
||||
|
||||
[Additional Reading (EN).](http://git-scm.com/book/en/Git-Branching-Rebasing)
|
||||
|
||||
### reset (cautela!)
|
||||
|
||||
Restabelece a HEAD atual ao estado definido. Isto permite reverter *merges*,
|
||||
*pulls*, *commits*, *adds* e outros. É um comando muito poderoso mas também
|
||||
perigoso se não há certeza quanto ao que se está a fazer.
|
||||
|
||||
```bash
|
||||
# Restabelece a camada intermediária dr registo para o último
|
||||
# commit (o directório fica sem alterações)
|
||||
$ git reset
|
||||
|
||||
# Restabelece a camada intermediária de registo para o último commit, e
|
||||
# sobre-escreve o projecto atual
|
||||
$ git reset --hard
|
||||
|
||||
# Move a head do branch atual para o commit especificado, sem alterar o projecto.
|
||||
# todas as alterações ainda existem no projecto
|
||||
$ git reset 31f2bb1
|
||||
|
||||
# Inverte a head do branch atual para o commit especificado
|
||||
# fazendo com que este esteja em sintonia com o directório do projecto
|
||||
# Remove alterações não registadas e todos os commits após o commit especificado
|
||||
$ git reset --hard 31f2bb1
|
||||
```
|
||||
|
||||
### rm
|
||||
|
||||
O oposto de git add, git rm remove ficheiros do branch atual.
|
||||
|
||||
```bash
|
||||
# remove HelloWorld.c
|
||||
$ git rm HelloWorld.c
|
||||
|
||||
# Remove um ficheiro de um sub-directório
|
||||
$ git rm /pather/to/the/file/HelloWorld.c
|
||||
```
|
||||
|
||||
## Informação complementar (EN)
|
||||
|
||||
* [tryGit - A fun interactive way to learn Git.](http://try.github.io/levels/1/challenges/1)
|
||||
|
||||
* [git-scm - Video Tutorials](http://git-scm.com/videos)
|
||||
|
||||
* [git-scm - Documentation](http://git-scm.com/docs)
|
||||
|
||||
* [Atlassian Git - Tutorials & Workflows](https://www.atlassian.com/git/)
|
||||
|
||||
* [SalesForce Cheat Sheet](https://na1.salesforce.com/help/doc/en/salesforce_git_developer_cheatsheet.pdf)
|
||||
|
||||
* [GitGuys](http://www.gitguys.com/)
|
@ -2,6 +2,7 @@
|
||||
language: python
|
||||
contributors:
|
||||
- ["Louie Dinh", "http://ldinh.ca"]
|
||||
- ["Amin Bandali", "http://aminbandali.com"]
|
||||
filename: learnpython.py
|
||||
---
|
||||
|
||||
@ -93,8 +94,8 @@ not False #=> True
|
||||
# None is an object
|
||||
None #=> None
|
||||
|
||||
# Don't use the equality `==` symbol to compare objects to None
|
||||
# Use `is` instead
|
||||
# Don't use the equality "==" symbol to compare objects to None
|
||||
# Use "is" instead
|
||||
"etc" is None #=> False
|
||||
None is None #=> True
|
||||
|
||||
@ -112,8 +113,10 @@ None is None #=> True
|
||||
## 2. Variables and Collections
|
||||
####################################################
|
||||
|
||||
# Printing is pretty easy
|
||||
print "I'm Python. Nice to meet you!"
|
||||
# Python has a print function, available in versions 2.7 and 3...
|
||||
print("I'm Python. Nice to meet you!")
|
||||
# and an older print statement, in all 2.x versions but removed from 3.
|
||||
print "I'm also Python!"
|
||||
|
||||
|
||||
# No need to declare variables before assigning to them.
|
||||
@ -157,20 +160,22 @@ li[1:3] #=> [2, 4]
|
||||
li[2:] #=> [4, 3]
|
||||
# Omit the end
|
||||
li[:3] #=> [1, 2, 4]
|
||||
# Revert the list
|
||||
li[::-1] #=> [3, 4, 2, 1]
|
||||
|
||||
# Remove arbitrary elements from a list with del
|
||||
# Remove arbitrary elements from a list with "del"
|
||||
del li[2] # li is now [1, 2, 3]
|
||||
|
||||
# You can add lists
|
||||
li + other_li #=> [1, 2, 3, 4, 5, 6] - Note: li and other_li is left alone
|
||||
|
||||
# Concatenate lists with extend
|
||||
# Concatenate lists with "extend()"
|
||||
li.extend(other_li) # Now li is [1, 2, 3, 4, 5, 6]
|
||||
|
||||
# Check for existence in a list with in
|
||||
# Check for existence in a list with "in"
|
||||
1 in li #=> True
|
||||
|
||||
# Examine the length with len
|
||||
# Examine the length with "len()"
|
||||
len(li) #=> 6
|
||||
|
||||
|
||||
@ -201,41 +206,41 @@ filled_dict = {"one": 1, "two": 2, "three": 3}
|
||||
# Look up values with []
|
||||
filled_dict["one"] #=> 1
|
||||
|
||||
# Get all keys as a list
|
||||
# Get all keys as a list with "keys()"
|
||||
filled_dict.keys() #=> ["three", "two", "one"]
|
||||
# Note - Dictionary key ordering is not guaranteed.
|
||||
# Your results might not match this exactly.
|
||||
|
||||
# Get all values as a list
|
||||
# Get all values as a list with "values()"
|
||||
filled_dict.values() #=> [3, 2, 1]
|
||||
# Note - Same as above regarding key ordering.
|
||||
|
||||
# Check for existence of keys in a dictionary with in
|
||||
# Check for existence of keys in a dictionary with "in"
|
||||
"one" in filled_dict #=> True
|
||||
1 in filled_dict #=> False
|
||||
|
||||
# Looking up a non-existing key is a KeyError
|
||||
filled_dict["four"] # KeyError
|
||||
|
||||
# Use get method to avoid the KeyError
|
||||
# Use "get()" method to avoid the KeyError
|
||||
filled_dict.get("one") #=> 1
|
||||
filled_dict.get("four") #=> None
|
||||
# The get method supports a default argument when the value is missing
|
||||
filled_dict.get("one", 4) #=> 1
|
||||
filled_dict.get("four", 4) #=> 4
|
||||
|
||||
# Setdefault method is a safe way to add new key-value pair into dictionary
|
||||
# "setdefault()" inserts into a dictionary only if the given key isn't present
|
||||
filled_dict.setdefault("five", 5) #filled_dict["five"] is set to 5
|
||||
filled_dict.setdefault("five", 6) #filled_dict["five"] is still 5
|
||||
|
||||
|
||||
# Sets store ... well sets
|
||||
empty_set = set()
|
||||
# Initialize a set with a bunch of values
|
||||
# Initialize a "set()" with a bunch of values
|
||||
some_set = set([1,2,2,3,4]) # some_set is now set([1, 2, 3, 4])
|
||||
|
||||
# Since Python 2.7, {} can be used to declare a set
|
||||
filled_set = {1, 2, 2, 3, 4} # => {1 2 3 4}
|
||||
filled_set = {1, 2, 2, 3, 4} # => {1, 2, 3, 4}
|
||||
|
||||
# Add more items to a set
|
||||
filled_set.add(5) # filled_set is now {1, 2, 3, 4, 5}
|
||||
@ -265,11 +270,11 @@ some_var = 5
|
||||
# Here is an if statement. Indentation is significant in python!
|
||||
# prints "some_var is smaller than 10"
|
||||
if some_var > 10:
|
||||
print "some_var is totally bigger than 10."
|
||||
print("some_var is totally bigger than 10.")
|
||||
elif some_var < 10: # This elif clause is optional.
|
||||
print "some_var is smaller than 10."
|
||||
print("some_var is smaller than 10.")
|
||||
else: # This is optional too.
|
||||
print "some_var is indeed 10."
|
||||
print("some_var is indeed 10.")
|
||||
|
||||
|
||||
"""
|
||||
@ -281,10 +286,10 @@ prints:
|
||||
"""
|
||||
for animal in ["dog", "cat", "mouse"]:
|
||||
# You can use % to interpolate formatted strings
|
||||
print "%s is a mammal" % animal
|
||||
|
||||
print("%s is a mammal" % animal)
|
||||
|
||||
"""
|
||||
`range(number)` returns a list of numbers
|
||||
"range(number)" returns a list of numbers
|
||||
from zero to the given number
|
||||
prints:
|
||||
0
|
||||
@ -293,7 +298,7 @@ prints:
|
||||
3
|
||||
"""
|
||||
for i in range(4):
|
||||
print i
|
||||
print(i)
|
||||
|
||||
"""
|
||||
While loops go until a condition is no longer met.
|
||||
@ -305,14 +310,14 @@ prints:
|
||||
"""
|
||||
x = 0
|
||||
while x < 4:
|
||||
print x
|
||||
print(x)
|
||||
x += 1 # Shorthand for x = x + 1
|
||||
|
||||
# Handle exceptions with a try/except block
|
||||
|
||||
# Works on Python 2.6 and up:
|
||||
try:
|
||||
# Use raise to raise an error
|
||||
# Use "raise" to raise an error
|
||||
raise IndexError("This is an index error")
|
||||
except IndexError as e:
|
||||
pass # Pass is just a no-op. Usually you would do recovery here.
|
||||
@ -322,9 +327,9 @@ except IndexError as e:
|
||||
## 4. Functions
|
||||
####################################################
|
||||
|
||||
# Use def to create new functions
|
||||
# Use "def" to create new functions
|
||||
def add(x, y):
|
||||
print "x is %s and y is %s" % (x, y)
|
||||
print("x is %s and y is %s" % (x, y))
|
||||
return x + y # Return values with a return statement
|
||||
|
||||
# Calling functions with parameters
|
||||
@ -351,15 +356,15 @@ keyword_args(big="foot", loch="ness") #=> {"big": "foot", "loch": "ness"}
|
||||
|
||||
# You can do both at once, if you like
|
||||
def all_the_args(*args, **kwargs):
|
||||
print args
|
||||
print kwargs
|
||||
print(args)
|
||||
print(kwargs)
|
||||
"""
|
||||
all_the_args(1, 2, a=3, b=4) prints:
|
||||
(1, 2)
|
||||
{"a": 3, "b": 4}
|
||||
"""
|
||||
|
||||
# When calling functions, you can do the opposite of varargs/kwargs!
|
||||
# When calling functions, you can do the opposite of args/kwargs!
|
||||
# Use * to expand tuples and use ** to expand kwargs.
|
||||
args = (1, 2, 3, 4)
|
||||
kwargs = {"a": 3, "b": 4}
|
||||
@ -402,7 +407,7 @@ class Human(object):
|
||||
# Assign the argument to the instance's name attribute
|
||||
self.name = name
|
||||
|
||||
# An instance method. All methods take self as the first argument
|
||||
# An instance method. All methods take "self" as the first argument
|
||||
def say(self, msg):
|
||||
return "%s: %s" % (self.name, msg)
|
||||
|
||||
@ -420,10 +425,10 @@ class Human(object):
|
||||
|
||||
# Instantiate a class
|
||||
i = Human(name="Ian")
|
||||
print i.say("hi") # prints out "Ian: hi"
|
||||
print(i.say("hi")) # prints out "Ian: hi"
|
||||
|
||||
j = Human("Joel")
|
||||
print j.say("hello") #prints out "Joel: hello"
|
||||
print(j.say("hello")) #prints out "Joel: hello"
|
||||
|
||||
# Call our class method
|
||||
i.get_species() #=> "H. sapiens"
|
||||
@ -443,12 +448,12 @@ Human.grunt() #=> "*grunt*"
|
||||
|
||||
# You can import modules
|
||||
import math
|
||||
print math.sqrt(16) #=> 4
|
||||
print(math.sqrt(16) )#=> 4
|
||||
|
||||
# You can get specific functions from a module
|
||||
from math import ceil, floor
|
||||
print ceil(3.7) #=> 4.0
|
||||
print floor(3.7) #=> 3.0
|
||||
print(ceil(3.7)) #=> 4.0
|
||||
print(floor(3.7)) #=> 3.0
|
||||
|
||||
# You can import all functions from a module.
|
||||
# Warning: this is not recommended
|
||||
@ -459,7 +464,7 @@ import math as m
|
||||
math.sqrt(16) == m.sqrt(16) #=> True
|
||||
|
||||
# Python modules are just ordinary python files. You
|
||||
# can write your own, and import them. The name of the
|
||||
# can write your own, and import them. The name of the
|
||||
# module is the same as the name of the file.
|
||||
|
||||
# You can find out which functions and attributes
|
||||
@ -479,6 +484,7 @@ dir(math)
|
||||
* [The Official Docs](http://docs.python.org/2.6/)
|
||||
* [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/)
|
||||
* [Python Module of the Week](http://pymotw.com/2/)
|
||||
* [A Crash Course in Python for Scientists](http://nbviewer.ipython.org/5920182)
|
||||
|
||||
### Dead Tree
|
||||
|
||||
|
@ -298,7 +298,7 @@ if (4 > 3) {
|
||||
|
||||
# Defined like so:
|
||||
jiggle <- function(x) {
|
||||
x+ rnorm(x, sd=.1) #add in a bit of (controlled) noise
|
||||
x = x + rnorm(1, sd=.1) #add in a bit of (controlled) noise
|
||||
return(x)
|
||||
}
|
||||
|
||||
|
490
ro-ro/python-ro.html.markdown
Normal file
490
ro-ro/python-ro.html.markdown
Normal file
@ -0,0 +1,490 @@
|
||||
---
|
||||
language: python
|
||||
contributors:
|
||||
- ["Louie Dinh", "http://ldinh.ca"]
|
||||
translators:
|
||||
- ["Ovidiu Ciule", "https://github.com/ociule"]
|
||||
filename: learnpython-ro.py
|
||||
lang: ro-ro
|
||||
---
|
||||
|
||||
Python a fost creat de Guido Van Rossum la începutul anilor '90. Python a devenit astăzi unul din
|
||||
cele mai populare limbaje de programare. M-am indrăgostit de Python pentru claritatea sa sintactică.
|
||||
Python este aproape pseudocod executabil.
|
||||
|
||||
Opinia dumneavoastră este binevenită! Puteţi sa imi scrieţi la [@ociule](http://twitter.com/ociule) sau ociule [at] [google's email service]
|
||||
|
||||
Notă: Acest articol descrie Python 2.7, dar este util şi pentru Python 2.x. O versiune Python 3 va apărea
|
||||
în curând, în limba engleză mai întâi.
|
||||
|
||||
```python
|
||||
# Comentariile pe o singură linie încep cu un caracter diez.
|
||||
""" Şirurile de caractere pe mai multe linii pot fi încadrate folosind trei caractere ", şi sunt des
|
||||
folosite ca şi comentarii pe mai multe linii.
|
||||
"""
|
||||
|
||||
####################################################
|
||||
## 1. Operatori şi tipuri de date primare
|
||||
####################################################
|
||||
|
||||
# Avem numere
|
||||
3 #=> 3
|
||||
|
||||
# Matematica se comportă cum ne-am aştepta
|
||||
1 + 1 #=> 2
|
||||
8 - 1 #=> 7
|
||||
10 * 2 #=> 20
|
||||
35 / 5 #=> 7
|
||||
|
||||
# Împărţirea este un pic surprinzătoare. Este de fapt împărţire pe numere întregi şi rotunjeşte
|
||||
# automat spre valoarea mai mică
|
||||
5 / 2 #=> 2
|
||||
|
||||
# Pentru a folosi împărţirea fără rest avem nevoie de numere reale
|
||||
2.0 # Acesta e un număr real
|
||||
11.0 / 4.0 #=> 2.75 ahhh ... cum ne aşteptam
|
||||
|
||||
# Ordinea operaţiilor se poate forţa cu paranteze
|
||||
(1 + 3) * 2 #=> 8
|
||||
|
||||
# Valoriile boolene sunt şi ele valori primare
|
||||
True
|
||||
False
|
||||
|
||||
# Pot fi negate cu operatorul not
|
||||
not True #=> False
|
||||
not False #=> True
|
||||
|
||||
# Egalitatea este ==
|
||||
1 == 1 #=> True
|
||||
2 == 1 #=> False
|
||||
|
||||
# Inegalitate este !=
|
||||
1 != 1 #=> False
|
||||
2 != 1 #=> True
|
||||
|
||||
# Comparaţii
|
||||
1 < 10 #=> True
|
||||
1 > 10 #=> False
|
||||
2 <= 2 #=> True
|
||||
2 >= 2 #=> True
|
||||
|
||||
# Comparaţiile pot fi inlănţuite!
|
||||
1 < 2 < 3 #=> True
|
||||
2 < 3 < 2 #=> False
|
||||
|
||||
# Şirurile de caractere pot fi încadrate cu " sau '
|
||||
"Acesta e un şir de caractere."
|
||||
'Şi acesta este un şir de caractere.'
|
||||
|
||||
# Şirurile de caractere pot fi adăugate!
|
||||
"Hello " + "world!" #=> "Hello world!"
|
||||
|
||||
# Un şir de caractere poate fi folosit ca o listă
|
||||
"Acesta e un şir de caractere"[0] #=> 'A'
|
||||
|
||||
# Caracterul % (procent) poate fi folosit pentru a formata şiruri de caractere :
|
||||
"%s pot fi %s" % ("şirurile", "interpolate")
|
||||
|
||||
# O metodă mai nouă de a formata şiruri este metoda "format"
|
||||
# Este metoda recomandată
|
||||
"{0} pot fi {1}".format("şirurile", "formatate")
|
||||
# Puteţi folosi cuvinte cheie dacă nu doriţi sa număraţi
|
||||
"{nume} vrea să mănânce {fel}".format(nume="Bob", fel="lasagna")
|
||||
|
||||
# "None", care reprezintă valoarea nedefinită, e un obiect
|
||||
None #=> None
|
||||
|
||||
# Nu folosiţi operatorul == pentru a compara un obiect cu None
|
||||
# Folosiţi operatorul "is"
|
||||
"etc" is None #=> False
|
||||
None is None #=> True
|
||||
|
||||
# Operatorul "is" testeaza dacă obiectele sunt identice.
|
||||
# Acastă operaţie nu e foarte folositoare cu tipuri primare,
|
||||
# dar e foarte folositoare cu obiecte.
|
||||
|
||||
# None, 0, şi şiruri de caractere goale sunt evaluate ca si fals, False.
|
||||
# Toate celelalte valori sunt adevărate, True.
|
||||
0 == False #=> True
|
||||
"" == False #=> True
|
||||
|
||||
|
||||
####################################################
|
||||
## 2. Variabile şi colecţii
|
||||
####################################################
|
||||
|
||||
# Printarea este uşoară
|
||||
print "Eu sunt Python. Încântat de cunoştinţă!"
|
||||
|
||||
|
||||
# Nu este nevoie sa declari variabilele înainte de a le folosi
|
||||
o_variabila = 5 # Convenţia este de a folosi caractere_minuscule_cu_underscore
|
||||
o_variabila #=> 5
|
||||
|
||||
# Dacă accesăm o variabilă nefolosită declanşăm o excepţie.
|
||||
# Vezi secţiunea Control de Execuţie pentru mai multe detalii despre excepţii.
|
||||
alta_variabila # Declanşează o eroare de nume
|
||||
|
||||
# "If" poate fi folosit într-o expresie.
|
||||
"yahoo!" if 3 > 2 else 2 #=> "yahoo!"
|
||||
|
||||
# Listele sunt folosite pentru colecţii
|
||||
li = []
|
||||
# O listă poate avea valori de la început
|
||||
alta_li = [4, 5, 6]
|
||||
|
||||
# Se adaugă valori la sfârşitul lister cu append
|
||||
li.append(1) #li e acum [1]
|
||||
li.append(2) #li e acum [1, 2]
|
||||
li.append(4) #li e acum [1, 2, 4]
|
||||
li.append(3) #li este acum [1, 2, 4, 3]
|
||||
# Se şterg de la sfarşit cu pop
|
||||
li.pop() #=> 3 şi li e acum [1, 2, 4]
|
||||
# Să o adaugăm înapoi valoarea
|
||||
li.append(3) # li e din nou [1, 2, 4, 3]
|
||||
|
||||
# Putem accesa valorile individuale dintr-o listă cu operatorul index
|
||||
li[0] #=> 1
|
||||
# Valoarea speciala -1 pentru index accesează ultima valoare
|
||||
li[-1] #=> 3
|
||||
|
||||
# Dacă depaşim limitele listei declanşăm o eroare IndexError
|
||||
li[4] # Declanşează IndexError
|
||||
|
||||
# Putem să ne uităm la intervale folosind sintaxa de "felii"
|
||||
# În Python, intervalele sunt închise la început si deschise la sfârşit.
|
||||
li[1:3] #=> [2, 4]
|
||||
# Fără început
|
||||
li[2:] #=> [4, 3]
|
||||
# Fără sfarşit
|
||||
li[:3] #=> [1, 2, 4]
|
||||
|
||||
# Putem şterge elemente arbitrare din lista cu operatorul "del" care primeşte indexul lor
|
||||
del li[2] # li e acum [1, 2, 3]
|
||||
|
||||
# Listele pot fi adăugate
|
||||
li + alta_li #=> [1, 2, 3, 4, 5, 6] - Notă: li si alta_li nu sunt modificate!
|
||||
|
||||
# Concatenăm liste cu "extend()"
|
||||
li.extend(alta_li) # Acum li este [1, 2, 3, 4, 5, 6]
|
||||
|
||||
# Se verifică existenţa valorilor in lista cu "in"
|
||||
1 in li #=> True
|
||||
|
||||
# Şi lungimea cu "len()"
|
||||
len(li) #=> 6
|
||||
|
||||
|
||||
# Tuplele sunt ca şi listele dar imutabile
|
||||
tup = (1, 2, 3)
|
||||
tup[0] #=> 1
|
||||
tup[0] = 3 # Declanşează TypeError
|
||||
|
||||
# Pot fi folosite ca şi liste
|
||||
len(tup) #=> 3
|
||||
tup + (4, 5, 6) #=> (1, 2, 3, 4, 5, 6)
|
||||
tup[:2] #=> (1, 2)
|
||||
2 in tup #=> True
|
||||
|
||||
# Tuplele pot fi despachetate
|
||||
a, b, c = (1, 2, 3) # a este acum 1, b este acum 2 şi c este acum 3
|
||||
# Tuplele pot fi folosite şi fără paranteze
|
||||
d, e, f = 4, 5, 6
|
||||
# Putem inversa valori foarte uşor!
|
||||
e, d = d, e # d este acum 5 şi e este acum 4
|
||||
|
||||
|
||||
# Dicţionarele stochează chei şi o valoare pentru fiecare cheie
|
||||
dict_gol = {}
|
||||
# Şi un dicţionar cu valori
|
||||
dict_cu_valori = {"unu": 1, "doi": 2, "trei": 3}
|
||||
|
||||
# Căutaţi valori cu []
|
||||
dict_cu_valori["unu"] #=> 1
|
||||
|
||||
# Obţinem lista cheilor cu "keys()"
|
||||
dict_cu_valori.keys() #=> ["trei", "doi", "unu"]
|
||||
# Notă - ordinea cheilor obţinute cu keys() nu este garantată.
|
||||
# Puteţi obţine rezultate diferite de exemplul de aici.
|
||||
|
||||
# Obţinem valorile cu values()
|
||||
dict_cu_valori.values() #=> [3, 2, 1]
|
||||
# Notă - aceeaşi ca mai sus, aplicată asupra valorilor.
|
||||
|
||||
# Verificăm existenţa unei valori cu "in"
|
||||
"unu" in dict_cu_valori #=> True
|
||||
1 in dict_cu_valori #=> False
|
||||
|
||||
# Accesarea unei chei care nu exista declanşează o KeyError
|
||||
dict_cu_valori["four"] # KeyError
|
||||
|
||||
# Putem folosi metoda "get()" pentru a evita KeyError
|
||||
dict_cu_valori.get("one") #=> 1
|
||||
dict_cu_valori.get("four") #=> None
|
||||
# Metoda get poate primi ca al doilea argument o valoare care va fi returnată
|
||||
# când cheia nu este prezentă.
|
||||
dict_cu_valori.get("one", 4) #=> 1
|
||||
dict_cu_valori.get("four", 4) #=> 4
|
||||
|
||||
# "setdefault()" este o metodă pentru a adăuga chei-valori fără a le modifica, dacă cheia există deja
|
||||
dict_cu_valori.setdefault("five", 5) #dict_cu_valori["five"] este acum 5
|
||||
dict_cu_valori.setdefault("five", 6) #dict_cu_valori["five"] exista deja, nu este modificată, tot 5
|
||||
|
||||
|
||||
# Set este colecţia mulţime
|
||||
set_gol = set()
|
||||
# Putem crea un set cu valori
|
||||
un_set = set([1,2,2,3,4]) # un_set este acum set([1, 2, 3, 4]), amintiţi-vă ca mulţimile garantează unicatul!
|
||||
|
||||
# În Python 2.7, {} poate fi folosit pentru un set
|
||||
set_cu_valori = {1, 2, 2, 3, 4} # => {1 2 3 4}
|
||||
|
||||
# Putem adăuga valori cu add
|
||||
set_cu_valori.add(5) # set_cu_valori este acum {1, 2, 3, 4, 5}
|
||||
|
||||
# Putem intersecta seturi
|
||||
alt_set = {3, 4, 5, 6}
|
||||
set_cu_valori & alt_set #=> {3, 4, 5}
|
||||
|
||||
# Putem calcula uniunea cu |
|
||||
set_cu_valori | alt_set #=> {1, 2, 3, 4, 5, 6}
|
||||
|
||||
# Diferenţa între seturi se face cu -
|
||||
{1,2,3,4} - {2,3,5} #=> {1, 4}
|
||||
|
||||
# Verificăm existenţa cu "in"
|
||||
2 in set_cu_valori #=> True
|
||||
10 in set_cu_valori #=> False
|
||||
|
||||
|
||||
####################################################
|
||||
## 3. Controlul Execuţiei
|
||||
####################################################
|
||||
|
||||
# O variabilă
|
||||
o_variabila = 5
|
||||
|
||||
# Acesta este un "if". Indentarea este importanta în python!
|
||||
# Printează "o_variabila este mai mică ca 10"
|
||||
if o_variabila > 10:
|
||||
print "o_variabila e mai mare ca 10."
|
||||
elif o_variabila < 10: # Clauza elif e opţională.
|
||||
print "o_variabila este mai mică ca 10."
|
||||
else: # Şi else e opţional.
|
||||
print "o_variabila este exact 10."
|
||||
|
||||
|
||||
"""
|
||||
Buclele "for" pot fi folosite pentru a parcurge liste
|
||||
Vom afişa:
|
||||
câinele este un mamifer
|
||||
pisica este un mamifer
|
||||
şoarecele este un mamifer
|
||||
"""
|
||||
for animal in ["câinele", "pisica", "şoarecele"]:
|
||||
# Folosim % pentru a compune mesajul
|
||||
print "%s este un mamifer" % animal
|
||||
|
||||
"""
|
||||
"range(număr)" crează o lista de numere
|
||||
de la zero la numărul dat
|
||||
afişează:
|
||||
0
|
||||
1
|
||||
2
|
||||
3
|
||||
"""
|
||||
for i in range(4):
|
||||
print i
|
||||
|
||||
"""
|
||||
While repetă pana când condiţia dată nu mai este adevărată.
|
||||
afişează:
|
||||
0
|
||||
1
|
||||
2
|
||||
3
|
||||
"""
|
||||
x = 0
|
||||
while x < 4:
|
||||
print x
|
||||
x += 1 # Prescurtare pentru x = x + 1
|
||||
|
||||
# Recepţionăm excepţii cu blocuri try/except
|
||||
|
||||
# Acest cod e valid in Python > 2.6:
|
||||
try:
|
||||
# Folosim "raise" pentru a declanşa o eroare
|
||||
raise IndexError("Asta este o IndexError")
|
||||
except IndexError as e:
|
||||
pass # Pass nu face nimic. În mod normal aici ne-am ocupa de eroare.
|
||||
|
||||
|
||||
####################################################
|
||||
## 4. Funcţii
|
||||
####################################################
|
||||
|
||||
# Folosim "def" pentru a defini funcţii
|
||||
def add(x, y):
|
||||
print "x este %s şi y este %s" % (x, y)
|
||||
return x + y # Funcţia poate returna valori cu "return"
|
||||
|
||||
# Apelăm funcţia "add" cu parametrii
|
||||
add(5, 6) #=> Va afişa "x este 5 şi y este 6" şi va returna 11
|
||||
|
||||
# Altă cale de a apela funcţii: cu parametrii numiţi
|
||||
add(y=6, x=5) # Ordinea parametrilor numiţi nu contează
|
||||
|
||||
# Putem defini funcţii care primesc un număr variabil de parametrii nenumiţi
|
||||
# Aceşti parametrii nenumiţi se cheamă si poziţinali
|
||||
def varargs(*args):
|
||||
return args
|
||||
|
||||
varargs(1, 2, 3) #=> (1,2,3)
|
||||
|
||||
|
||||
# Şi putem defini funcţii care primesc un număr variabil de parametrii numiţi
|
||||
def keyword_args(**kwargs):
|
||||
return kwargs
|
||||
|
||||
# Hai să vedem cum merge
|
||||
keyword_args(big="foot", loch="ness") #=> {"big": "foot", "loch": "ness"}
|
||||
|
||||
# Se pot combina
|
||||
def all_the_args(*args, **kwargs):
|
||||
print args
|
||||
print kwargs
|
||||
"""
|
||||
all_the_args(1, 2, a=3, b=4) va afişa:
|
||||
(1, 2)
|
||||
{"a": 3, "b": 4}
|
||||
"""
|
||||
|
||||
# Când apelăm funcţii, putem face inversul args/kwargs!
|
||||
# Folosim * pentru a expanda tuple şi ** pentru a expanda kwargs.
|
||||
args = (1, 2, 3, 4)
|
||||
kwargs = {"a": 3, "b": 4}
|
||||
all_the_args(*args) # echivalent cu foo(1, 2, 3, 4)
|
||||
all_the_args(**kwargs) # echivalent cu foo(a=3, b=4)
|
||||
all_the_args(*args, **kwargs) # echivalent cu foo(1, 2, 3, 4, a=3, b=4)
|
||||
|
||||
# În Python, funcţiile sunt obiecte primare
|
||||
def create_adder(x):
|
||||
def adder(y):
|
||||
return x + y
|
||||
return adder
|
||||
|
||||
add_10 = create_adder(10)
|
||||
add_10(3) #=> 13
|
||||
|
||||
# Funcţiile pot fi anonime
|
||||
(lambda x: x > 2)(3) #=> True
|
||||
|
||||
# Există funcţii de ordin superior (care operează pe alte funcţii) predefinite
|
||||
map(add_10, [1,2,3]) #=> [11, 12, 13]
|
||||
filter(lambda x: x > 5, [3, 4, 5, 6, 7]) #=> [6, 7]
|
||||
|
||||
# Putem folosi scurtături de liste pentru a simplifica munca cu map si filter
|
||||
[add_10(i) for i in [1, 2, 3]] #=> [11, 12, 13]
|
||||
[x for x in [3, 4, 5, 6, 7] if x > 5] #=> [6, 7]
|
||||
|
||||
####################################################
|
||||
## 5. Clase
|
||||
####################################################
|
||||
|
||||
# Moştenim object pentru a crea o nouă clasă
|
||||
class Om(object):
|
||||
|
||||
# Acesta este un atribut al clasei. Va fi moştenit de toate instanţele.
|
||||
species = "H. sapiens"
|
||||
|
||||
# Constructor (mai degrabă, configurator de bază)
|
||||
def __init__(self, nume):
|
||||
# Valoarea parametrului este stocată in atributul instanţei
|
||||
self.nume = nume
|
||||
|
||||
# Aceasta este o metoda a instanţei.
|
||||
# Toate metodele primesc "self" ca si primul argument.
|
||||
def spune(self, mesaj):
|
||||
return "%s: %s" % (self.nume, mesaj)
|
||||
|
||||
# O metodă a clasei. Este partajată de toate instanţele.
|
||||
# Va primi ca si primul argument clasa căreia îi aparţine.
|
||||
@classmethod
|
||||
def get_species(cls):
|
||||
return cls.species
|
||||
|
||||
# O metoda statica nu primeste un argument automat.
|
||||
@staticmethod
|
||||
def exclama():
|
||||
return "*Aaaaaah*"
|
||||
|
||||
|
||||
# Instanţiem o clasă
|
||||
i = Om(nume="Ion")
|
||||
print i.spune("salut") # afişează: "Ion: salut"
|
||||
|
||||
j = Om("George")
|
||||
print j.spune("ciau") # afişează George: ciau"
|
||||
|
||||
# Apelăm metoda clasei
|
||||
i.get_species() #=> "H. sapiens"
|
||||
|
||||
# Modificăm atributul partajat
|
||||
Om.species = "H. neanderthalensis"
|
||||
i.get_species() #=> "H. neanderthalensis"
|
||||
j.get_species() #=> "H. neanderthalensis"
|
||||
|
||||
# Apelăm metoda statică
|
||||
Om.exclama() #=> "*Aaaaaah*"
|
||||
|
||||
|
||||
####################################################
|
||||
## 6. Module
|
||||
####################################################
|
||||
|
||||
# Pentru a folosi un modul, trebuie importat
|
||||
import math
|
||||
print math.sqrt(16) #=> 4
|
||||
|
||||
# Putem importa doar anumite funcţii dintr-un modul
|
||||
from math import ceil, floor
|
||||
print ceil(3.7) #=> 4.0
|
||||
print floor(3.7) #=> 3.0
|
||||
|
||||
# Putem importa toate funcţiile dintr-un modul, dar nu este o idee bună
|
||||
# Nu faceţi asta!
|
||||
from math import *
|
||||
|
||||
# Numele modulelor pot fi modificate la import, de exemplu pentru a le scurta
|
||||
import math as m
|
||||
math.sqrt(16) == m.sqrt(16) #=> True
|
||||
|
||||
# Modulele python sunt pur şi simplu fişiere cu cod python.
|
||||
# Puteţi sa creaţi modulele voastre, şi sa le importaţi.
|
||||
# Numele modulului este acelasi cu numele fişierului.
|
||||
|
||||
# Cu "dir" inspectăm ce funcţii conţine un modul
|
||||
import math
|
||||
dir(math)
|
||||
|
||||
|
||||
```
|
||||
|
||||
## Doriţi mai mult?
|
||||
|
||||
### Gratis online, în limba engleză
|
||||
|
||||
* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/)
|
||||
* [Dive Into Python](http://www.diveintopython.net/)
|
||||
* [The Official Docs](http://docs.python.org/2.6/)
|
||||
* [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/)
|
||||
* [Python Module of the Week](http://pymotw.com/2/)
|
||||
|
||||
### Cărţi, în limba engleză
|
||||
|
||||
* [Programming Python](http://www.amazon.com/gp/product/0596158106/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596158106&linkCode=as2&tag=homebits04-20)
|
||||
* [Dive Into Python](http://www.amazon.com/gp/product/1441413022/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1441413022&linkCode=as2&tag=homebits04-20)
|
||||
* [Python Essential Reference](http://www.amazon.com/gp/product/0672329786/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0672329786&linkCode=as2&tag=homebits04-20)
|
||||
|
483
ru-ru/c-ru.html.markdown
Normal file
483
ru-ru/c-ru.html.markdown
Normal file
@ -0,0 +1,483 @@
|
||||
---
|
||||
language: c
|
||||
filename: learnc.c
|
||||
contributors:
|
||||
- ["Adam Bard", "http://adambard.com/"]
|
||||
- ["Árpád Goretity", "http://twitter.com/H2CO3_iOS"]
|
||||
translators:
|
||||
- ["Evlogy Sutormin", "http://evlogii.com"]
|
||||
lang: ru-ru
|
||||
---
|
||||
|
||||
Что ж, Си всё ещё является лидером среди современных высокопроизводительных языков.
|
||||
|
||||
Для большинствоа программистов, Си – это самый низкоуровневый язык на котором они когда-либо писали,
|
||||
но этот язык даёт больше, чем просто повышение производительности.
|
||||
Держите это руководство в памяти и вы сможете использовать Си максимально эффективно.
|
||||
|
||||
```c
|
||||
// Однострочный комментарий начинается с // - доступен только после С99.
|
||||
|
||||
/*
|
||||
Многострочный комментарий выглядит так. Работает начиная с С89.
|
||||
*/
|
||||
|
||||
// Импорт файлов происходит с помощью **#include**
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
// Файлы <в угловых скобочках> будут подключаться из стандартной библиотеки.
|
||||
// Свои файлы необходимо подключать с помощью "двойных кавычек".
|
||||
#include "my_header.h"
|
||||
|
||||
// Объявление функций должно происходить в .h файлах или вверху .c файла.
|
||||
void function_1();
|
||||
void function_2();
|
||||
|
||||
// Точка входа в программу – это функция main.
|
||||
int main() {
|
||||
// для форматированного вывода в консоль используется printf
|
||||
// %d – означает, что будем выводить целое число, \n переводит указатель вывода
|
||||
// на новую строчку
|
||||
printf("%d\n", 0); // => напечатает "0"
|
||||
// Каждый оператор заканчивается точкой с запятой.
|
||||
|
||||
///////////////////////////////////////
|
||||
// Типы
|
||||
///////////////////////////////////////
|
||||
|
||||
// int обычно имеет длину 4 байта
|
||||
int x_int = 0;
|
||||
|
||||
// short обычно имеет длину 2 байта
|
||||
short x_short = 0;
|
||||
|
||||
// char гарантированно имеет длину 1 байта
|
||||
char x_char = 0;
|
||||
char y_char = 'y'; // Символьные литералы заключаются в кавычки ''
|
||||
|
||||
// long как правило занимает от 4 до 8 байт
|
||||
// long long занимает как минимум 64 бита
|
||||
long x_long = 0;
|
||||
long long x_long_long = 0;
|
||||
|
||||
// float это 32-битное число с плавающей точкой
|
||||
float x_float = 0.0;
|
||||
|
||||
// double это 64-битное число с плавающей точкой
|
||||
double x_double = 0.0;
|
||||
|
||||
// Целые типы могут быть беззнаковыми.
|
||||
unsigned short ux_short;
|
||||
unsigned int ux_int;
|
||||
unsigned long long ux_long_long;
|
||||
|
||||
// sizeof(T) возвращает размер переменной типа Т в байтах.
|
||||
// sizeof(obj) возвращает размер объекта obj в байтах.
|
||||
printf("%zu\n", sizeof(int)); // => 4 (на большинстве машин int занимает 4 байта)
|
||||
|
||||
// Если аргуметом sizeof будет выражение, то этот аргумент вычисляется
|
||||
// ещё во время компиляции кода (кроме динамических массивов).
|
||||
int a = 1;
|
||||
// size_t это беззнаковый целый тип который использует как минимум 2 байта
|
||||
// для записи размера объекта
|
||||
size_t size = sizeof(a++); // a++ не выполнится
|
||||
printf("sizeof(a++) = %zu, где a = %d\n", size, a);
|
||||
// выведет строку "sizeof(a++) = 4, где a = 1" (на 32-битной архитектуре)
|
||||
|
||||
// Можно задать размер массива при объявлении.
|
||||
char my_char_array[20]; // Этот массив занимает 1 * 20 = 20 байт
|
||||
int my_int_array[20]; // Этот массив занимает 4 * 20 = 80 байт (сумма 4-битных слов)
|
||||
|
||||
// Можно обнулить массив при объявлении.
|
||||
char my_array[20] = {0};
|
||||
|
||||
// Индексация массива происходит также как и в других Си-подобных языках.
|
||||
my_array[0]; // => 0
|
||||
|
||||
// Массивы изменяемы. Это просто память как и другие переменные.
|
||||
my_array[1] = 2;
|
||||
printf("%d\n", my_array[1]); // => 2
|
||||
|
||||
// В C99 (а также опционально в C11), массив может быть объявлен динамически.
|
||||
// Размер массива не обязательно должен быть рассчитан на этапе компиляции.
|
||||
printf("Enter the array size: "); // спрашиваем юзера размер массива
|
||||
char buf[0x100];
|
||||
fgets(buf, sizeof buf, stdin);
|
||||
size_t size = strtoul(buf, NULL, 10); // strtoul парсит строку в беззнаковое целое
|
||||
int var_length_array[size]; // объявление динамического массива
|
||||
printf("sizeof array = %zu\n", sizeof var_length_array);
|
||||
// Вывод программы (в зависимости от архитектуры) будет таким:
|
||||
// > Enter the array size: 10
|
||||
// > sizeof array = 40
|
||||
|
||||
// Строка – это просто массив символов, оканчивающийся нулевым (NUL (0x00)) байтом
|
||||
// представляемым в строке специальным символом '\0'.
|
||||
// Нам не нужно вставлять нулевой байт в строковой литерал,
|
||||
// компилятор всё сделает за нас.
|
||||
char a_string[20] = "This is a string";
|
||||
printf("%s\n", a_string); // %s обозначает вывод строки
|
||||
|
||||
printf("%d\n", a_string[16]); // => 0
|
||||
// байт #17 тоже равен 0 (а также 18, 19, и 20)
|
||||
|
||||
// Если между одинарными кавычками есть символ – это символьный литерал,
|
||||
// но это тип int, а не char (по историческим причинам).
|
||||
|
||||
int cha = 'a'; // хорошо
|
||||
char chb = 'a'; // тоже хорошо (подразумевается преобразование int в char)
|
||||
|
||||
///////////////////////////////////////
|
||||
// Операторы
|
||||
///////////////////////////////////////
|
||||
|
||||
// Можно использовать множественное объявление.
|
||||
int i1 = 1, i2 = 2;
|
||||
float f1 = 1.0, f2 = 2.0;
|
||||
|
||||
// Арифметика обычная
|
||||
i1 + i2; // => 3
|
||||
i2 - i1; // => 1
|
||||
i2 * i1; // => 2
|
||||
i1 / i2; // => 0 (0.5, но обрезается до 0)
|
||||
|
||||
f1 / f2; // => 0.5, плюс-минус погрешность потому что,
|
||||
// цифры с плавающей точкой вычисляются неточно!
|
||||
|
||||
// Модуль
|
||||
11 % 3; // => 2
|
||||
|
||||
// Операции сравнения вам уже знакомы, но в Си нет булевого типа.
|
||||
// Вместо него используется int. 0 это false, всё остальное это true.
|
||||
// Операции сравнения всегда возвращают 1 или 0.
|
||||
3 == 2; // => 0 (false)
|
||||
3 != 2; // => 1 (true)
|
||||
3 > 2; // => 1
|
||||
3 < 2; // => 0
|
||||
2 <= 2; // => 1
|
||||
2 >= 2; // => 1
|
||||
|
||||
// Си это не Питон – операции сравнения могут быть только парными.
|
||||
int a = 1;
|
||||
// ОШИБКА:
|
||||
int between_0_and_2 = 0 < a < 2;
|
||||
// Правильно:
|
||||
int between_0_and_2 = 0 < a && a < 2;
|
||||
|
||||
// Логика
|
||||
!3; // => 0 (логическое НЕ)
|
||||
!0; // => 1
|
||||
1 && 1; // => 1 (логическое И)
|
||||
0 && 1; // => 0
|
||||
0 || 1; // => 1 (лигическое ИЛИ)
|
||||
0 || 0; // => 0
|
||||
|
||||
// Битовые операторы
|
||||
~0x0F; // => 0xF0 (побитовое отрицание)
|
||||
0x0F & 0xF0; // => 0x00 (побитовое И)
|
||||
0x0F | 0xF0; // => 0xFF (побитовое ИЛИ)
|
||||
0x04 ^ 0x0F; // => 0x0B (исключающее ИЛИ (XOR))
|
||||
0x01 << 1; // => 0x02 (побитовый сдвиг влево (на 1))
|
||||
0x02 >> 1; // => 0x01 (побитовый сдвиг вправо (на 1))
|
||||
|
||||
// Будьте осторожны при сдвиге беззнакового int, эти операции не определены:
|
||||
// - сдвиг в знаковый бит у целого числа (int a = 1 << 32)
|
||||
// - сдвиг влево отрицательных чисел (int a = -1 << 2)
|
||||
|
||||
///////////////////////////////////////
|
||||
// Структуры ветвления
|
||||
///////////////////////////////////////
|
||||
|
||||
// Условный оператор
|
||||
if (0) {
|
||||
printf("I am never run\n");
|
||||
} else if (0) {
|
||||
printf("I am also never run\n");
|
||||
} else {
|
||||
printf("I print\n");
|
||||
}
|
||||
|
||||
// Цикл с предусловием
|
||||
int ii = 0;
|
||||
while (ii < 10) {
|
||||
printf("%d, ", ii++); // инкрементация происходит после того как
|
||||
// знаечние ii передано ("postincrement")
|
||||
} // => prints "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "
|
||||
|
||||
printf("\n");
|
||||
|
||||
//Цикл с постусловием
|
||||
int kk = 0;
|
||||
do {
|
||||
printf("%d, ", kk);
|
||||
} while (++kk < 10); // инкрементация происходит перед тем как
|
||||
// передаётся знаечние kk ("preincrement")
|
||||
// => prints "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "
|
||||
|
||||
printf("\n");
|
||||
|
||||
// Цикл со счётчиком
|
||||
int jj;
|
||||
for (jj=0; jj < 10; jj++) {
|
||||
printf("%d, ", jj);
|
||||
} // => prints "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "
|
||||
|
||||
printf("\n");
|
||||
|
||||
// Ветвление с множественным выбором
|
||||
switch (some_integral_expression) {
|
||||
case 0: // значения должны быть целыми константами (и могут быть выражениями)
|
||||
do_stuff();
|
||||
break; // если не написать break; то управление будет передено следующему блоку
|
||||
case 1:
|
||||
do_something_else();
|
||||
break;
|
||||
default:
|
||||
// если не было совпадения, то выполняется блок default:
|
||||
fputs("ошибка!\n", stderr);
|
||||
exit(-1);
|
||||
break;
|
||||
}
|
||||
|
||||
///////////////////////////////////////
|
||||
// Форматирование вывода
|
||||
///////////////////////////////////////
|
||||
|
||||
// Каждое выражение в Си имеет тип, но вы можете привести один тип к другому,
|
||||
// если хотите (с некоторыми искажениями).
|
||||
|
||||
int x_hex = 0x01; // Вы можете назначать переменные с помощью шеснадцатеричного кода.
|
||||
|
||||
// Приведение типов будет пытаться сохранять цифровые значения.
|
||||
printf("%d\n", x_hex); // => Prints 1
|
||||
printf("%d\n", (short) x_hex); // => Prints 1
|
||||
printf("%d\n", (char) x_hex); // => Prints 1
|
||||
|
||||
// Типы могут переполняться без вызова предупреждения.
|
||||
printf("%d\n", (unsigned char) 257); // => 1 (Max char = 255 if char is 8 bits long)
|
||||
|
||||
// Для определения максимального значения типов `char`, `signed char` и `unisigned char`,
|
||||
// соответственно используйте CHAR_MAX, SCHAR_MAX и UCHAR_MAX макросы из <limits.h>
|
||||
|
||||
// Целые типы могут быть приведены к вещественным и наоборот.
|
||||
printf("%f\n", (float)100); // %f formats a float
|
||||
printf("%lf\n", (double)100); // %lf formats a double
|
||||
printf("%d\n", (char)100.0);
|
||||
|
||||
///////////////////////////////////////
|
||||
// Указатели
|
||||
///////////////////////////////////////
|
||||
|
||||
// Указатель – это переменная которая хранит адрес в памяти.
|
||||
// При объявлении указателя указывается тип данных переменной на которую он будет ссылаться.
|
||||
// Вы можете получить адрес любой переменной, а потом работать с ним.
|
||||
|
||||
// Используйте & для получения адреса переменной.
|
||||
int x = 0;
|
||||
printf("%p\n", (void *)&x); // => Напечатает адрес в памяти, где лежит переменная x
|
||||
// (%p выводит указатель на void *)
|
||||
|
||||
// Для объявления указателя нужно поставить * перед именем.
|
||||
int *px, not_a_pointer; // px это указатель на int
|
||||
px = &x; // сохранит адрес x в px
|
||||
printf("%p\n", (void *)px); // => Напечатает адрес в памяти, где лежит переменная px
|
||||
printf("%zu, %zu\n", sizeof(px), sizeof(not_a_pointer));
|
||||
// => Напечатает "8, 4" в 64 битной системе
|
||||
|
||||
// Для того, чтобы получить знаечние по адресу, напечатайте * перед именем.
|
||||
// Да, использование * при объявлении указателя и получении значения по адресу
|
||||
// немного запутано, но вы привыкнете.
|
||||
printf("%d\n", *px); // => Напечаатет 0, значение перемененной x
|
||||
|
||||
// Вы также можете изменять значение, на которое указывает указатель.
|
||||
(*px)++; // Инкрементирует значение на которое указывает px на единицу
|
||||
printf("%d\n", *px); // => Напечатает 1
|
||||
printf("%d\n", x); // => Напечатает 1
|
||||
|
||||
// Массивы удобно использовать для болшого количества однотипных данных.
|
||||
int x_array[20];
|
||||
int xx;
|
||||
for (xx = 0; xx < 20; xx++) {
|
||||
x_array[xx] = 20 - xx;
|
||||
} // Объявление x_array с значениями 20, 19, 18,... 2, 1
|
||||
|
||||
// Объявление указателя на int с адресом массива.
|
||||
int* x_ptr = x_array;
|
||||
// x_ptr сейчас указывает на первый элемент массива (со значением 20).
|
||||
// Это рабоатет, потому что имя массива возвращает указатель на первый элемент.
|
||||
// Например, когда массив передаётся в функцию или назначается указателю, он
|
||||
// невявно преобразуется в указатель.
|
||||
// Исключения: когда массив является аргументом для оператор '&':
|
||||
int arr[10];
|
||||
int (*ptr_to_arr)[10] = &arr; // &arr не является 'int *'!
|
||||
// он является "указателем на массив" (из десяти 'int'ов).
|
||||
// или когда массив это строчный литерал, используемый при объявлении массива символов:
|
||||
char arr[] = "foobarbazquirk";
|
||||
// или когда массив является аргументом `sizeof` или `alignof` операторов:
|
||||
int arr[10];
|
||||
int *ptr = arr; // то же самое что и "int *ptr = &arr[0];"
|
||||
printf("%zu %zu\n", sizeof arr, sizeof ptr); // напечатает "40, 4" или "40, 8"
|
||||
|
||||
// Декрементация и инкрементация указателей зависит от их типа
|
||||
// (это называется арифметика указателей)
|
||||
printf("%d\n", *(x_ptr + 1)); // => Напечатает 19
|
||||
printf("%d\n", x_array[1]); // => Напечатает 19
|
||||
|
||||
// Вы также можете динамически выделять несколько блоков памяти с помощью
|
||||
// функции malloc из стандартной библиотеки, которая принимает один
|
||||
// аргумент типа size_t – количество байт необходимых для выделения.
|
||||
int *my_ptr = malloc(sizeof(*my_ptr) * 20);
|
||||
for (xx = 0; xx < 20; xx++) {
|
||||
*(my_ptr + xx) = 20 - xx; // my_ptr[xx] = 20-xx
|
||||
} // Выделяет память для 20, 19, 18, 17... 2, 1 (как int'ы)
|
||||
|
||||
// Работа с памятью с помощью указателей может давать неожиданные и
|
||||
// непредсказуемые результаты.
|
||||
printf("%d\n", *(my_ptr + 21)); // => Напечатает кто-нибудь-знает-что?
|
||||
// Скорей всего программа вылетит.
|
||||
|
||||
// Когда вы закончили работать с памятью, которую ранее выделили, вам необходимо
|
||||
// освободить её, иначе это может вызвать утечку памяти или ошибки.
|
||||
free(my_ptr);
|
||||
|
||||
// Строки это массивы символов, но обычно они представляются как
|
||||
// указатели на символ (как указатели на первый элемент массива).
|
||||
// Хорошей практикой считается использование `const char *' при объявлении
|
||||
// строчного литерала. При таком подходе литерал не может быть изменён.
|
||||
// (например "foo"[0] = 'a' вызовет ошибку!)
|
||||
|
||||
const char *my_str = "This is my very own string literal";
|
||||
printf("%c\n", *my_str); // => 'T'
|
||||
|
||||
// Это не работает, если строка является массивом
|
||||
// (потенциально задаваемой с помощью строкового литерала)
|
||||
// который находиться в перезаписываемой части памяти:
|
||||
|
||||
char foo[] = "foo";
|
||||
foo[0] = 'a'; // это выполнится и строка теперь "aoo"
|
||||
|
||||
void function_1()
|
||||
} // конец функции main()
|
||||
|
||||
///////////////////////////////////////
|
||||
// Функции
|
||||
///////////////////////////////////////
|
||||
|
||||
// Синтаксис объявления функции:
|
||||
// <возвращаемый тип> <имя функции>(аргументы)
|
||||
|
||||
int add_two_ints(int x1, int x2) {
|
||||
return x1 + x2; // Используйте return для возврата значения
|
||||
}
|
||||
|
||||
/*
|
||||
Данные в функцию передаются "по значению", но никто не мешает
|
||||
вам передавать в функцию указатели и менять данные по указателям.
|
||||
|
||||
Например: инвертировать строку прямо в функции
|
||||
*/
|
||||
|
||||
// void означает, что функция ничего не возвращает
|
||||
void str_reverse(char *str_in) {
|
||||
char tmp;
|
||||
int ii = 0;
|
||||
size_t len = strlen(str_in); // `strlen()` является частью стандартной библиотеки
|
||||
for (ii = 0; ii < len / 2; ii++) {
|
||||
tmp = str_in[ii];
|
||||
str_in[ii] = str_in[len - ii - 1]; // ii-тый символ с конца
|
||||
str_in[len - ii - 1] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
char c[] = "This is a test.";
|
||||
str_reverse(c);
|
||||
printf("%s\n", c); // => Выведет ".tset a si sihT"
|
||||
|
||||
///////////////////////////////////////
|
||||
// Типы и структуры определяемые пользователем
|
||||
///////////////////////////////////////
|
||||
|
||||
// typedef используется для задания стандартным типам своих названий
|
||||
typedef int my_type;
|
||||
my_type my_type_var = 0;
|
||||
|
||||
// Структуры это просто коллекция данных, память выделяется последовательно,
|
||||
// в том порядке в котором записаны данные.
|
||||
struct rectangle {
|
||||
int width;
|
||||
int height;
|
||||
};
|
||||
|
||||
// sizeof(struct rectangle) == sizeof(int) + sizeof(int) – не всегда верно
|
||||
// из-за особенностей компиляции (необычное поведение при отступах)[1].
|
||||
|
||||
void function_1() {
|
||||
struct rectangle my_rec;
|
||||
|
||||
// Доступ к структурам через точку
|
||||
my_rec.width = 10;
|
||||
my_rec.height = 20;
|
||||
|
||||
// Вы можете объявить указатель на структуру
|
||||
struct rectangle *my_rec_ptr = &my_rec;
|
||||
|
||||
// Можно доступаться к структуре и через указатель
|
||||
(*my_rec_ptr).width = 30;
|
||||
|
||||
// ... или ещё лучше: используйте оператор -> для лучшей читабельночти
|
||||
my_rec_ptr->height = 10; // то же что и "(*my_rec_ptr).height = 10;"
|
||||
}
|
||||
|
||||
// Вы можете применить typedef к структуре, для удобства.
|
||||
typedef struct rectangle rect;
|
||||
|
||||
int area(rect r) {
|
||||
return r.width * r.height;
|
||||
}
|
||||
|
||||
// Если вы имеете большую структуру, можно доступаться к ней "по указателю",
|
||||
// чтобы избежать копирования всей структуры.
|
||||
int area(const rect *r) {
|
||||
return r->width * r->height;
|
||||
}
|
||||
|
||||
///////////////////////////////////////
|
||||
// Указатели на функции
|
||||
///////////////////////////////////////
|
||||
|
||||
/*
|
||||
Во время исполнения функции находятся по известным адресам в памяти.
|
||||
Указатель на функцию может быть использован для непосредственного вызова функции.
|
||||
Однако синтаксис может сбивать с толку.
|
||||
|
||||
Пример: использование str_reverse по указателю
|
||||
*/
|
||||
|
||||
void str_reverse_through_pointer(char *str_in) {
|
||||
// Определение функции через указатель.
|
||||
void (*f)(char *); // Сигнатура должна полность совпадать с целевой функцией.
|
||||
f = &str_reverse; // Присвоить фактический адрес (во время исполнения)
|
||||
// "f = str_reverse;" тоже будет работать.
|
||||
//Имя функции (как и массива) возвращает указатель на начало.
|
||||
(*f)(str_in); // Просто вызываем функцию через указатель.
|
||||
// "f(str_in);" или вот так
|
||||
}
|
||||
```
|
||||
|
||||
## На почитать
|
||||
|
||||
Лучше всего найдите копию [K&R, aka "The C Programming Language"](https://en.wikipedia.org/wiki/The_C_Programming_Language)
|
||||
Это **книга** написанная создателями Си. Но будьте осторожны, она содержит идеи которые больше не считаются хорошими.
|
||||
|
||||
Другой хороший ресурс: [Learn C the hard way](http://c.learncodethehardway.org/book/).
|
||||
|
||||
Если у вас появился вопрос, почитайте [compl.lang.c Frequently Asked Questions](http://c-faq.com).
|
||||
|
||||
Очень важно использовать правильные отступы и ставить пробелы в нужных местах.
|
||||
Читаемый код лучше чем красивый или быстрый код.
|
||||
Чтобы научиться писать хороший код, почитайте [Linux kernel coding stlye](https://www.kernel.org/doc/Documentation/CodingStyle).
|
||||
|
||||
Также не забывайте, что [Google](http://google.com) и [Яндекс](http://yandex.ru) – ваши хорошие друзья.
|
||||
|
||||
[1] http://stackoverflow.com/questions/119123/why-isnt-sizeof-for-a-struct-equal-to-the-sum-of-sizeof-of-each-member
|
@ -3,6 +3,7 @@ language: clojure
|
||||
filename: learnclojure-ru.clj
|
||||
contributors:
|
||||
- ["Adam Bard", "http://adambard.com/"]
|
||||
translators:
|
||||
- ["Alexey Pirogov", "http://twitter.com/alex_pir"]
|
||||
lang: ru-ru
|
||||
---
|
||||
|
256
ru-ru/erlang-ru.html.markdown
Normal file
256
ru-ru/erlang-ru.html.markdown
Normal file
@ -0,0 +1,256 @@
|
||||
---
|
||||
language: erlang
|
||||
contributors:
|
||||
- ["Giovanni Cappellotto", "http://www.focustheweb.com/"]
|
||||
translators:
|
||||
- ["Nikita Kalashnikov", "https://root.yuuzukiyo.net/"]
|
||||
filename: learnerlang-ru.erl
|
||||
lang: ru-ru
|
||||
---
|
||||
|
||||
```erlang
|
||||
% Символ процента предваряет однострочный комментарий.
|
||||
|
||||
%% Два символа процента обычно используются для комментариев к функциям.
|
||||
|
||||
%%% Три символа процента используются для комментариев к модулям.
|
||||
|
||||
% Пунктуационные знаки, используемые в Erlang:
|
||||
% Запятая (`,`) разделяет аргументы в вызовах функций, структурах данных и
|
||||
% образцах.
|
||||
% Точка (`.`) (с пробелом после них) разделяет функции и выражения в
|
||||
% оболочке.
|
||||
% Точка с запятой (`;`) разделяет выражения в следующих контекстах:
|
||||
% формулы функций, выражения `case`, `if`, `try..catch` и `receive`.
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%% 1. Переменные и сопоставление с образцом.
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
Num = 42. % Все названия переменных начинаются с большой буквы.
|
||||
|
||||
% Erlang использует единичное присваивание переменным. Если вы попытаетесь
|
||||
% присвоить другое значение переменной `Num`, вы получите ошибку.
|
||||
Num = 43. % ** exception error: no match of right hand side value 43
|
||||
|
||||
% В большинстве языков `=` обозначает операцию присвоения. В отличие от них, в
|
||||
% Erlang `=` — операция сопоставления с образцом. `Lhs = Rhs` на самом
|
||||
% деле подразумевает «вычисли правую часть выражения (Rhs) и затем сопоставь
|
||||
% результат с образцом слева (Lhs)».
|
||||
Num = 7 * 6.
|
||||
|
||||
% Числа с плавающей точкой.
|
||||
Pi = 3.14159.
|
||||
|
||||
% Атомы используются для представления различных нечисловых констант. Названия
|
||||
% атомов начинаются с буквы в нижнем регистре, за которой могут следовать другие
|
||||
% буквы английского алфавита, цифры, символ подчёркивания (`_`) или «собака»
|
||||
% (`@`).
|
||||
Hello = hello.
|
||||
OtherNode = example@node.
|
||||
|
||||
% Если в имени атома нужно использовать другие символы, кроме допустимых,
|
||||
% имя атома необходимо взять в одинарные кавычки (`'`).
|
||||
AtomWithSpace = 'some atom with space'.
|
||||
|
||||
% Кортежы подобны структурам в языке C.
|
||||
Point = {point, 10, 45}.
|
||||
|
||||
% Если нужно извлечь определённые данные из кортежа, используется оператор
|
||||
% сопоставления с образцом — `=`.
|
||||
{point, X, Y} = Point. % X = 10, Y = 45
|
||||
|
||||
% Символ `_` может использоваться как «заполнитель» для переменных, значения
|
||||
% которых в текущем выражении нас не интересуют. Он называется анонимной
|
||||
% переменной. В отличие от остальных переменных, множественные использования
|
||||
% `_` в одном образце не требуют, чтобы все значения, присваевыемые этой
|
||||
% переменной, были идентичными.
|
||||
Person = {person, {name, {first, joe}, {last, armstrong}}, {footsize, 42}}.
|
||||
{_, {_, {_, Who}, _}, _} = Person. % Who = joe
|
||||
|
||||
% Список создаётся путём заключения его элементов в квадратные скобки и
|
||||
% разделения их запятыми. Отдельные элементы списка могут быть любого типа.
|
||||
% Первый элемент списка называется головой списка. Список, получающийся в
|
||||
% результате отделения головы, называется хвостом списка.
|
||||
ThingsToBuy = [{apples, 10}, {pears, 6}, {milk, 3}].
|
||||
|
||||
% Если `T` — список, то `[H|T]` — тоже список, где `H` является головой, а `T` —
|
||||
% хвостом. Вертикальная черта (`|`) разделяет голову и хвост списка.
|
||||
% `[]` — пустой список.
|
||||
% Мы можем извлекать элементы из списка с помощью сопоставления с образцом.
|
||||
% Если у нас есть непустой список `L`, тогда выражение `[X|Y] = L`, где `X` и
|
||||
% `Y` — свободные (не связанные с другими значениям) переменные, извлечёт голову
|
||||
% списка в `X` и его хвост в `Y`.
|
||||
[FirstThing|OtherThingsToBuy] = ThingsToBuy.
|
||||
% FirstThing = {apples, 10}
|
||||
% OtherThingsToBuy = {pears, 6}, {milk, 3}
|
||||
|
||||
% В Erlang нет строк как отдельного типа. Все используемые в программах строки
|
||||
% являются обычным списком целых чисел. Строковые значения всегда должны быть в
|
||||
% двойных кавычках (`"`).
|
||||
Name = "Hello".
|
||||
[72, 101, 108, 108, 111] = "Hello".
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%% 2. Последовательное программирование.
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
% Модуль — основная единица кода в Erlang. В них пишутся и сохраняются все
|
||||
% функции. Модули хранятся в файлах с расширением `.erl`.
|
||||
% Модули должны быть скомпилированы перед тем, как использовать код из них.
|
||||
% Скомпилированный файл модуля имеет разрешение `.beam`.
|
||||
-module(geometry).
|
||||
-export([area/1]). % список функций, экспортируемых из модуля.
|
||||
|
||||
% Функция `area` состоит из двух формул (clauses). Формулы отделяются друг от
|
||||
% друга точкой с запятой, после последнего определения должна стоять точка с
|
||||
% пробелом после неё.
|
||||
% Каждое определение имеет заголовок и тело. Заголовок состоит из названия
|
||||
% функции и образца (в скобках); тело состоит из последовательных выражений,
|
||||
% вычисляемых, когда аргументы функции совпадают с образцом в заголовке.
|
||||
% Сопоставление с образцами в заголовках происходит в том порядке, в котором
|
||||
% они перечислены в определении функции.
|
||||
area({rectangle, Width, Ht}) -> Width * Ht;
|
||||
area({circle, R}) -> 3.14159 * R * R.
|
||||
|
||||
% Компиляция файла с исходным кодом geometry.erl.
|
||||
c(geometry). % {ok,geometry}
|
||||
|
||||
% Необходимо указывать имя модуля вместе с именем функции для определения, какую
|
||||
% именно фукнцию мы хотим вызвать.
|
||||
geometry:area({rectangle, 10, 5}). % 50
|
||||
geometry:area({circle, 1.4}). % 6.15752
|
||||
|
||||
% В Erlang две функции с разной арностью (числом аргументов) в пределах одного
|
||||
% модуля представляются как две разные функции.
|
||||
-module(lib_misc).
|
||||
-export([sum/1]). % экспорт функции `sum` с арностью 1, принимающую один аргумент.
|
||||
sum(L) -> sum(L, 0).
|
||||
sum([], N) -> N;
|
||||
sum([H|T], N) -> sum(T, H+N).
|
||||
|
||||
% Fun'ы — анонимные функции, называемые так по причине отсутствия имени. Зато
|
||||
% их можно присваивать переменным.
|
||||
Double = fun(X) -> 2*X end. % `Double` указывает на анонимную функцию с идентификатором: #Fun<erl_eval.6.17052888>
|
||||
Double(2). % 4
|
||||
|
||||
% Функции могут принимать fun'ы как параметры и возвращать их в качестве
|
||||
% результата вычислений.
|
||||
Mult = fun(Times) -> ( fun(X) -> X * Times end ) end.
|
||||
Triple = Mult(3).
|
||||
Triple(5). % 15
|
||||
|
||||
% Выделения списоков (list comprehensions) — выражения, создающие списки без
|
||||
% применения анонимных функций, фильтров или map'ов.
|
||||
% Запись `[F(X) || X <- L]` значит «список `F(X)`, где `X` последовательно
|
||||
% выбирается из списка `L`».
|
||||
L = [1,2,3,4,5].
|
||||
[2*X || X <- L]. % [2,4,6,8,10]
|
||||
% В выделениях списков могут быть генераторы и фильтры для отделения подмножеств
|
||||
% генерируемых значений.
|
||||
EvenNumbers = [N || N <- [1, 2, 3, 4], N rem 2 == 0]. % [2, 4]
|
||||
|
||||
% Охранные выражения используются для простых проверок переменных в образцах,
|
||||
% что значительно расширяет возможности сопоставления. Они могут использоваться
|
||||
% в заголовках определений функций, предварённые ключевым словом `when`, а также
|
||||
% в условных конструкциях.
|
||||
max(X, Y) when X > Y -> X;
|
||||
max(X, Y) -> Y.
|
||||
|
||||
% Охранные выражения можно группировать, разделяя запятой.
|
||||
% Последовательность `GuardExpr1, GuardExpr2, ..., GuardExprN` является истинной
|
||||
% только в том случае, когда все выражения, которые она содержат, являются
|
||||
% истинными.
|
||||
is_cat(A) when is_atom(A), A =:= cat -> true;
|
||||
is_cat(A) -> false.
|
||||
is_dog(A) when is_atom(A), A =:= dog -> true;
|
||||
is_dog(A) -> false.
|
||||
|
||||
% Последовательность охранных выражений, разделённых точками с запятой, является
|
||||
% истинной в том случае, если хотя бы одно выражение из списка `G1; G2; ...; Gn`
|
||||
% является истинным.
|
||||
is_pet(A) when is_dog(A); is_cat(A) -> true;
|
||||
is_pet(A) -> false.
|
||||
|
||||
% Записи предоставляют возможность именования определённых элементов в кортежах.
|
||||
% Определения записей могут быть включены в исходный код модулей Erlang или же
|
||||
% в заголовочные файлы с расширением `.hrl`.
|
||||
-record(todo, {
|
||||
status = reminder, % Значение по умолчанию.
|
||||
who = joe,
|
||||
text
|
||||
}).
|
||||
|
||||
% Для чтения определений записей из файлов в оболочке можно использовать команду
|
||||
% `rr`.
|
||||
rr("records.hrl"). % [todo]
|
||||
|
||||
% Создание и изменение записей.
|
||||
X = #todo{}.
|
||||
% #todo{status = reminder, who = joe, text = undefined}
|
||||
X1 = #todo{status = urgent, text = "Fix errata in book"}.
|
||||
% #todo{status = urgent, who = joe, text = "Fix errata in book"}
|
||||
X2 = X1#todo{status = done}.
|
||||
% #todo{status = done,who = joe,text = "Fix errata in book"}
|
||||
|
||||
% Условное выражение `case`.
|
||||
% Функция `filter` возвращет список всех элементов `X` из списка `L`, для
|
||||
% которых выражение `P(X)` является истинным.
|
||||
filter(P, [H|T]) ->
|
||||
case P(H) of
|
||||
true -> [H|filter(P, T)];
|
||||
false -> filter(P, T)
|
||||
end;
|
||||
filter(P, []) -> [].
|
||||
filter(fun(X) -> X rem 2 == 0 end, [1, 2, 3, 4]). % [2, 4]
|
||||
|
||||
% Условное выражение `if`.
|
||||
max(X, Y) ->
|
||||
if
|
||||
X > Y -> X;
|
||||
X < Y -> Y;
|
||||
true -> nil;
|
||||
end.
|
||||
|
||||
% Внимание: в выражении `if` должно быть как минимум одно охранное выраженние,
|
||||
% вычисляющееся в true, иначе возникнет исключение.
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%% 3. Обработка исключений.
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
% Исключения возникают в случае внутренних ошибок системы или вызываются
|
||||
% непосредственно из кода программы с помощью вызовов `throw(Exception)`,
|
||||
% `exit(Exception)` или `erlang:error(Exception)`.
|
||||
generate_exception(1) -> a;
|
||||
generate_exception(2) -> throw(a);
|
||||
generate_exception(3) -> exit(a);
|
||||
generate_exception(4) -> {'EXIT', a};
|
||||
generate_exception(5) -> erlang:error(a).
|
||||
|
||||
% В Erlang есть два способа обработки исключений. Первый заключается в
|
||||
% использовании выражения `try..catch` в функции, в которой возможен выброс
|
||||
% исключения.
|
||||
catcher(N) ->
|
||||
try generate_exception(N) of
|
||||
Val -> {N, normal, Val}
|
||||
catch
|
||||
throw:X -> {N, caught, thrown, X};
|
||||
exit:X -> {N, caught, exited, X};
|
||||
error:X -> {N, caught, error, X}
|
||||
end.
|
||||
|
||||
% Второй способ заключается в использовании `catch`. Во время поимки исключения
|
||||
% оно преобразуется в кортеж с информацией об ошибке.
|
||||
catcher(N) -> catch generate_exception(N).
|
||||
|
||||
```
|
||||
|
||||
## Ссылки:
|
||||
|
||||
* ["Learn You Some Erlang for great good!"](http://learnyousomeerlang.com/)
|
||||
* ["Programming Erlang: Software for a Concurrent World" by Joe Armstrong](http://pragprog.com/book/jaerlang/programming-erlang)
|
||||
* [Erlang/OTP Reference Documentation](http://www.erlang.org/doc/)
|
||||
* [Erlang - Programming Rules and Conventions](http://www.erlang.se/doc/programming_rules.shtml)
|
306
ru-ru/go-ru.html.markdown
Normal file
306
ru-ru/go-ru.html.markdown
Normal file
@ -0,0 +1,306 @@
|
||||
---
|
||||
language: Go
|
||||
filename: learngo-ru.go
|
||||
contributors:
|
||||
- ["Sonia Keys", "https://github.com/soniakeys"]
|
||||
translators:
|
||||
- ["Artem Medeusheyev", "https://github.com/armed"]
|
||||
lang: ru-ru
|
||||
---
|
||||
|
||||
Go - это язык общего назначения, целью которого является удобство, простота,
|
||||
конкуррентность. Это не тренд в компьютерных науках, а новейший и быстрый
|
||||
способ решать насущные проблемы.
|
||||
|
||||
Концепции Go схожи с другими императивными статически типизированными языками.
|
||||
Быстро компилируется и быстро исполняется, имеет легкие в понимании конструкции
|
||||
для создания масштабируемых и многопоточных программ.
|
||||
|
||||
Может похвастаться отличной стандартной библиотекой и большим комьюнити, полным
|
||||
энтузиазтов.
|
||||
|
||||
```go
|
||||
// Однострочный комментарий
|
||||
/* Многострочный
|
||||
комментарий */
|
||||
|
||||
// Ключевое слово package присутствует в начале каждого файла.
|
||||
// Main это специальное имя, обозначающее исполняемый файл, нежели библиотеку.
|
||||
package main
|
||||
|
||||
// Import предназначен для указания зависимостей этого файла.
|
||||
import (
|
||||
"fmt" // Пакет в стандартной библиотеке Go
|
||||
"net/http" // Да, это web server!
|
||||
"strconv" // Конвертирование типов в строки и обратно
|
||||
)
|
||||
|
||||
// Объявление функции. Main это специальная функция, служащая точкой входа для
|
||||
// исполняемой программы. Нравится вам или нет, но Go использует фигурные
|
||||
// скобки.
|
||||
func main() {
|
||||
// Println выводит строку в stdout.
|
||||
// В данном случае фигурирует вызов функции из пакета fmt.
|
||||
fmt.Println("Hello world!")
|
||||
|
||||
// Вызов другой функции из текущего пакета.
|
||||
beyondHello()
|
||||
}
|
||||
|
||||
// Функции содержат входные параметры в круглых скобках.
|
||||
// Пустые скобки все равно обязательны, даже если параметров нет.
|
||||
func beyondHello() {
|
||||
var x int // Переменные должны быть объявлены до их использования.
|
||||
x = 3 // Присвоение значения переменной.
|
||||
// Краткое определение := позволяет объявить перменную с автоматической
|
||||
// подстановкой типа из значения.
|
||||
y := 4
|
||||
sum, prod := learnMultiple(x, y) // функция возвращает два значения
|
||||
fmt.Println("sum:", sum, "prod:", prod) // простой вывод
|
||||
learnTypes() // < y minutes, learn more!
|
||||
}
|
||||
|
||||
// Функция имеющая входные параметры и возврат нескольких значений.
|
||||
func learnMultiple(x, y int) (sum, prod int) {
|
||||
return x + y, x * y // возврат двух результатов
|
||||
}
|
||||
|
||||
// Некотрые встроенные типы и литералы.
|
||||
func learnTypes() {
|
||||
// Краткое определение переменной говорит само за себя.
|
||||
s := "Learn Go!" // тип string
|
||||
|
||||
s2 := `"Чистый" строковой литерал
|
||||
может содержать переносы строк` // тоже тип данных string
|
||||
|
||||
// символ не из ASCII. Исходный код Go в кодировке UTF-8.
|
||||
g := 'Σ' // тип rune, это алиас для типа uint32, содержит юникод символ
|
||||
|
||||
f := 3.14195 // float64, 64-х битное число с плавающей точкой (IEEE-754)
|
||||
c := 3 + 4i // complex128, внутри себя содержит два float64
|
||||
|
||||
// Синтаксис var с инициализациями
|
||||
var u uint = 7 // беззнаковое, но размер зависит от реализации, как и у int
|
||||
var pi float32 = 22. / 7
|
||||
|
||||
// Синтаксис приведения типа с кратким определением
|
||||
n := byte('\n') // byte алиас для uint8
|
||||
|
||||
// Массивы (Array) имеют фиксированный размер на момент компиляции.
|
||||
var a4 [4]int // массив из 4-х int, проинициализирован нулями
|
||||
a3 := [...]int{3, 1, 5} // массив из 3-х int, ручная инициализация
|
||||
|
||||
// Slice имеют динамическую длину. И массивы и slice-ы имеют каждый свои
|
||||
// преимущества, но slice-ы используются гораздо чаще.
|
||||
s3 := []int{4, 5, 9} // по сравнению с a3 тут нет троеточия
|
||||
s4 := make([]int, 4) // выделение памяти для slice из 4-х int (нули)
|
||||
var d2 [][]float64 // только объявление, память не выделяется
|
||||
bs := []byte("a slice") // конвертирование строки в slice байтов
|
||||
|
||||
p, q := learnMemory() // объявление p и q как указателей на int.
|
||||
fmt.Println(*p, *q) // * извлекает указатель. Печатает два int-а.
|
||||
|
||||
// Map как словарь или хеш теблица из других языков является ассоциативным
|
||||
// массивом с динамически изменяемым размером.
|
||||
m := map[string]int{"three": 3, "four": 4}
|
||||
m["one"] = 1
|
||||
|
||||
delete(m, "three") // встроенная функция, удаляет элемент из map-а.
|
||||
|
||||
// Неиспользуемые переменные в Go являются ошибкой.
|
||||
// Нижнее подчеркивание позволяет игнорировать такие переменные.
|
||||
_, _, _, _, _, _, _, _, _ = s2, g, f, u, pi, n, a3, s4, bs
|
||||
// Вывод считается использованием переменной.
|
||||
fmt.Println(s, c, a4, s3, d2, m)
|
||||
|
||||
learnFlowControl() // идем далее
|
||||
}
|
||||
|
||||
// У Go есть полноценный сборщик мусора. В нем есть указатели но нет арифметики
|
||||
// указатеей. Вы можете допустить ошибку с указателем на nil, но не с его
|
||||
// инкрементацией.
|
||||
func learnMemory() (p, q *int) {
|
||||
// Именованные возвращаемые значения p и q являются указателями на int.
|
||||
p = new(int) // встроенная функция new выделяет память.
|
||||
// Выделенный int проинициализирован нулем, p больше не содержит nil.
|
||||
s := make([]int, 20) // Выделение единого блока памяти под 20 int-ов,
|
||||
s[3] = 7 // назначение одному из них,
|
||||
r := -2 // опредление еще одной локальной переменной,
|
||||
return &s[3], &r // амперсанд обозначает получение адреса переменной.
|
||||
}
|
||||
|
||||
func expensiveComputation() int {
|
||||
return 1e6
|
||||
}
|
||||
|
||||
func learnFlowControl() {
|
||||
// If-ы всегда требуют наличине фигурных скобок, но круглые скобки
|
||||
// необязательны.
|
||||
if true {
|
||||
fmt.Println("told ya")
|
||||
}
|
||||
// Форматирование кода стандартизировано утилитой "go fmt".
|
||||
if false {
|
||||
// все тлен
|
||||
} else {
|
||||
// жизнь прекрасна
|
||||
}
|
||||
// Использоване switch на замену нескольким if-else
|
||||
x := 1
|
||||
switch x {
|
||||
case 0:
|
||||
case 1:
|
||||
// case-ы в Go не проваливаются, т.е. break по умолчанию
|
||||
case 2:
|
||||
// не выполнится
|
||||
}
|
||||
// For, как и if не требует круглых скобок
|
||||
for x := 0; x < 3; x++ { // ++ это операция
|
||||
fmt.Println("итерация", x)
|
||||
}
|
||||
// тут x == 1.
|
||||
|
||||
// For это единственный цикл в Go, но у него несколько форм.
|
||||
for { // бесконечный цикл
|
||||
break // не такой уж и бесконечный
|
||||
continue // не выполнится
|
||||
}
|
||||
// Как и в for, := в if-е означает объявление и присвоение значения y,
|
||||
// затем проверка y > x.
|
||||
if y := expensiveComputation(); y > x {
|
||||
x = y
|
||||
}
|
||||
// Функции являются замыканиями.
|
||||
xBig := func() bool {
|
||||
return x > 100 // ссылается на x, объявленый выше switch.
|
||||
}
|
||||
fmt.Println("xBig:", xBig()) // true (т.к. мы присвоили x = 1e6)
|
||||
x /= 1e5 // тут х == 10
|
||||
fmt.Println("xBig:", xBig()) // теперь false
|
||||
|
||||
// Метки, куда же без них, их все любят.
|
||||
goto love
|
||||
love:
|
||||
|
||||
learnInterfaces() // О! Интерфейсы, идем далее.
|
||||
}
|
||||
|
||||
// Объявление Stringer как интерфейса с одним мметодом, String.
|
||||
type Stringer interface {
|
||||
String() string
|
||||
}
|
||||
|
||||
// Объявление pair как структуры с двумя полями x и y типа int.
|
||||
type pair struct {
|
||||
x, y int
|
||||
}
|
||||
|
||||
// Объявление метода для типа pair. Теперь pair реализует интерфейс Stringer.
|
||||
func (p pair) String() string { // p в данном случае называют receiver-ом
|
||||
// Sprintf - еще одна функция из пакета fmt.
|
||||
// Обращение к полям p через точку.
|
||||
return fmt.Sprintf("(%d, %d)", p.x, p.y)
|
||||
}
|
||||
|
||||
func learnInterfaces() {
|
||||
// Синтаксис с фигурными скобками это "литерал структуры". Он возвращает
|
||||
// проинициализированную структуру, а оператор := присваивает ее в p.
|
||||
p := pair{3, 4}
|
||||
fmt.Println(p.String()) // вызов метода String у p, типа pair.
|
||||
var i Stringer // объявление i как типа с интерфейсом Stringer.
|
||||
i = p // валидно, т.к. pair реализует Stringer.
|
||||
// Вызов метода String у i, типа Stringer. Вывод такой же что и выше.
|
||||
fmt.Println(i.String())
|
||||
|
||||
// Функции в пакете fmt сами всегда вызывают метод String у объектов для
|
||||
// получения строкового представления о них.
|
||||
fmt.Println(p) // Вывод такой же что и выше. Println вызывает метод String.
|
||||
fmt.Println(i) // тоже самое
|
||||
|
||||
learnErrorHandling()
|
||||
}
|
||||
|
||||
func learnErrorHandling() {
|
||||
// Идиома ", ok" служит для обозначения сработало что-то или нет.
|
||||
m := map[int]string{3: "three", 4: "four"}
|
||||
if x, ok := m[1]; !ok { // ok будет false, потому что 1 нет в map-е.
|
||||
fmt.Println("тут никого")
|
||||
} else {
|
||||
fmt.Print(x) // x содержал бы значение, если бы 1 был в map-е.
|
||||
}
|
||||
// Идиома ", err" служит для обозначения была ли ошибка или нет.
|
||||
if _, err := strconv.Atoi("non-int"); err != nil { // _ игнорирует значение
|
||||
// выведет "strconv.ParseInt: parsing "non-int": invalid syntax"
|
||||
fmt.Println(err)
|
||||
}
|
||||
// Мы еще обратимся к интерфейсам чуть позже, а пока...
|
||||
learnConcurrency()
|
||||
}
|
||||
|
||||
// c это тип данных channel (канал), объект для конкуррентного взаимодействия.
|
||||
func inc(i int, c chan int) {
|
||||
c <- i + 1 // когда channel слева, <- являтся оператором "отправки".
|
||||
}
|
||||
|
||||
// Будем использовать функцию inc для конкуррентной инкрементации чисел.
|
||||
func learnConcurrency() {
|
||||
// Тот же make, что и в случае со slice. Он предназначен для выделения
|
||||
// памяти и инициализации типов slice, map и channel.
|
||||
c := make(chan int)
|
||||
// Старт трех конкуррентных goroutine. Числа будут инкрементированы
|
||||
// конкуррентно и, может быть параллельно, если машина правильно
|
||||
// сконфигурирована и позволяет это делать. Все они будут отправлены в один
|
||||
// и тот же канал.
|
||||
go inc(0, c) // go начинает новую горутину.
|
||||
go inc(10, c)
|
||||
go inc(-805, c)
|
||||
// Считывание всех трех результатов из канала и вывод на экран.
|
||||
// Нет никакой гарантии в каком порядке они будут выведены.
|
||||
fmt.Println(<-c, <-c, <-c) // канал справа, <- обозначает "получение".
|
||||
|
||||
cs := make(chan string) // другой канал, содержит строки.
|
||||
cc := make(chan chan string) // канал каналов со строками.
|
||||
go func() { c <- 84 }() // пуск новой горутины для отправки значения
|
||||
go func() { cs <- "wordy" }() // еще раз, теперь для cs
|
||||
// Select тоже что и switch, но работает с каналами. Он случайно выбирает
|
||||
// готовый для взаимодействия канал.
|
||||
select {
|
||||
case i := <-c: // полученное значение можно присвоить переменной
|
||||
fmt.Printf("это %T", i)
|
||||
case <-cs: // либо значение можно игнорировать
|
||||
fmt.Println("это строка")
|
||||
case <-cc: // пустой канал, не готов для коммуникации.
|
||||
fmt.Println("это не выполнится.")
|
||||
}
|
||||
// В этой точке значение будет получено из c или cs. Одна горутина будет
|
||||
// завершена, другая останется заблокированной.
|
||||
|
||||
learnWebProgramming() // Да, Go это может.
|
||||
}
|
||||
|
||||
// Всего одна функция из пакета http запускает web-сервер.
|
||||
func learnWebProgramming() {
|
||||
// У ListenAndServe первый параметр это TCP адрес, который нужно слушать.
|
||||
// Второй параметр это интерфейс типа http.Handler.
|
||||
err := http.ListenAndServe(":8080", pair{})
|
||||
fmt.Println(err) // не игнорируйте сообщения об ошибках
|
||||
}
|
||||
|
||||
// Реализация интерфейса http.Handler для pair, только один метод ServeHTTP.
|
||||
func (p pair) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
// Обработка запроса и отправка данных методом из http.ResponseWriter
|
||||
w.Write([]byte("You learned Go in Y minutes!"))
|
||||
}
|
||||
```
|
||||
|
||||
## Что дальше
|
||||
|
||||
Основа всех основ в Go это [официальный веб сайт](http://golang.org/).
|
||||
Там можно пройти туториал, поиграться с интерактивной средой Go и почитать
|
||||
объемную документацию.
|
||||
|
||||
Для живого ознакомления рекомендуется почитать исходные коды [стандартной
|
||||
библиотеки Go](http://golang.org/src/pkg/). Отлично задокументированая, она
|
||||
является лучшим источником для чтения и понимания Go, его стиля и идиом. Либо
|
||||
можно, кликнув на имени функции в [документации](http://golang.org/pkg/),
|
||||
перейти к ее исходным кодам.
|
317
ru-ru/objective-c-ru.html.markdown
Normal file
317
ru-ru/objective-c-ru.html.markdown
Normal file
@ -0,0 +1,317 @@
|
||||
---
|
||||
language: Objective-C
|
||||
filename: LearnObjectiveC.m
|
||||
contributors:
|
||||
- ["Eugene Yagrushkin", "www.about.me/yagrushkin"]
|
||||
- ["Yannick Loriot", "https://github.com/YannickL"]
|
||||
translators:
|
||||
- ["Evlogy Sutormin", "http://evlogii.com"]
|
||||
lang: ru-ru
|
||||
---
|
||||
|
||||
Objective-C — компилируемый объектно-ориентированный язык программирования, используемый корпорацией Apple,
|
||||
построенный на основе языка Си и парадигм Smalltalk.
|
||||
В частности, объектная модель построена в стиле Smalltalk — то есть объектам посылаются сообщения.
|
||||
|
||||
```cpp
|
||||
// Однострочный комментарий
|
||||
|
||||
/*
|
||||
Многострочный
|
||||
комментарий
|
||||
*/
|
||||
|
||||
// Импорт файлов фреймворка Foundation с помощью #import
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "MyClass.h"
|
||||
|
||||
// Точка входа в программу это функция main,
|
||||
// которая возвращает целый тип integer
|
||||
int main (int argc, const char * argv[])
|
||||
{
|
||||
// Создание autorelease pool для управления памятью
|
||||
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
// Используйте NSLog для печати в консоль
|
||||
NSLog(@"Hello World!"); // Напечатает строку "Hello World!"
|
||||
|
||||
///////////////////////////////////////
|
||||
// Типы и переменные
|
||||
///////////////////////////////////////
|
||||
|
||||
// Простое объявление
|
||||
int myPrimitive1 = 1;
|
||||
long myPrimitive2 = 234554664565;
|
||||
|
||||
// Помещайте * в начало названия объекта для строго типизированного объявления
|
||||
MyClass *myObject1 = nil; // Строгая типизация
|
||||
id myObject2 = nil; // Слабая типизация
|
||||
|
||||
NSLog(@"%@ and %@", myObject1, [myObject2 description]); // напечатает "(null) and (null)"
|
||||
// %@ – это объект
|
||||
// 'description' это общий для всех объектов метод вывода данных
|
||||
|
||||
// Строка
|
||||
NSString *worldString = @"World";
|
||||
NSLog(@"Hello %@!", worldString); // напечатает "Hello World!"
|
||||
|
||||
// Символьные литералы
|
||||
NSNumber *theLetterZNumber = @'Z';
|
||||
char theLetterZ = [theLetterZNumber charValue];
|
||||
NSLog(@"%c", theLetterZ);
|
||||
|
||||
// Целочисленный литералы
|
||||
NSNumber *fortyTwoNumber = @42;
|
||||
int fortyTwo = [fortyTwoNumber intValue];
|
||||
NSLog(@"%i", fortyTwo);
|
||||
|
||||
// Беззнаковый целочисленный литерал
|
||||
NSNumber *fortyTwoUnsignedNumber = @42U;
|
||||
unsigned int fortyTwoUnsigned = [fortyTwoUnsignedNumber unsignedIntValue];
|
||||
NSLog(@"%u", fortyTwoUnsigned);
|
||||
|
||||
NSNumber *fortyTwoShortNumber = [NSNumber numberWithShort:42];
|
||||
short fortyTwoShort = [fortyTwoShortNumber shortValue];
|
||||
NSLog(@"%hi", fortyTwoShort);
|
||||
|
||||
NSNumber *fortyTwoLongNumber = @42L;
|
||||
long fortyTwoLong = [fortyTwoLongNumber longValue];
|
||||
NSLog(@"%li", fortyTwoLong);
|
||||
|
||||
// Вещественный литерал
|
||||
NSNumber *piFloatNumber = @3.141592654F;
|
||||
float piFloat = [piFloatNumber floatValue];
|
||||
NSLog(@"%f", piFloat);
|
||||
|
||||
NSNumber *piDoubleNumber = @3.1415926535;
|
||||
double piDouble = [piDoubleNumber doubleValue];
|
||||
NSLog(@"%f", piDouble);
|
||||
|
||||
// BOOL (булевый) литерал
|
||||
NSNumber *yesNumber = @YES;
|
||||
NSNumber *noNumber = @NO;
|
||||
|
||||
// Массив
|
||||
NSArray *anArray = @[@1, @2, @3, @4];
|
||||
NSNumber *thirdNumber = anArray[2];
|
||||
NSLog(@"Third number = %@", thirdNumber); // Print "Third number = 3"
|
||||
|
||||
// Словарь
|
||||
NSDictionary *aDictionary = @{ @"key1" : @"value1", @"key2" : @"value2" };
|
||||
NSObject *valueObject = aDictionary[@"A Key"];
|
||||
NSLog(@"Object = %@", valueObject); // Напечатает "Object = (null)"
|
||||
|
||||
///////////////////////////////////////
|
||||
// Операторы
|
||||
///////////////////////////////////////
|
||||
|
||||
// Операторы работают также как в Си.
|
||||
// Например:
|
||||
2 + 5; // => 7
|
||||
4.2f + 5.1f; // => 9.3f
|
||||
3 == 2; // => 0 (НЕТ)
|
||||
3 != 2; // => 1 (ДА)
|
||||
1 && 1; // => 1 (логическое И)
|
||||
0 || 1; // => 1 (логическое ИЛИ)
|
||||
~0x0F; // => 0xF0 (побитовое отрицание)
|
||||
0x0F & 0xF0; // => 0x00 (побитовое И)
|
||||
0x01 << 1; // => 0x02 (побитовый сдвиг влево (на 1))
|
||||
|
||||
///////////////////////////////////////
|
||||
// Структуры ветвления
|
||||
///////////////////////////////////////
|
||||
|
||||
// Условный оператор
|
||||
if (NO)
|
||||
{
|
||||
NSLog(@"I am never run");
|
||||
} else if (0)
|
||||
{
|
||||
NSLog(@"I am also never run");
|
||||
} else
|
||||
{
|
||||
NSLog(@"I print");
|
||||
}
|
||||
|
||||
// Ветвление с множественным выбором
|
||||
switch (2)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
NSLog(@"I am never run");
|
||||
} break;
|
||||
case 1:
|
||||
{
|
||||
NSLog(@"I am also never run");
|
||||
} break;
|
||||
default:
|
||||
{
|
||||
NSLog(@"I print");
|
||||
} break;
|
||||
}
|
||||
|
||||
// Цикл с предусловием
|
||||
int ii = 0;
|
||||
while (ii < 4)
|
||||
{
|
||||
NSLog(@"%d,", ii++); // ii++ инкрементирует ii после передачи значения
|
||||
} // => напечатает "0,"
|
||||
// "1,"
|
||||
// "2,"
|
||||
// "3,"
|
||||
|
||||
// Цикл со счётчиком
|
||||
int jj;
|
||||
for (jj=0; jj < 4; jj++)
|
||||
{
|
||||
NSLog(@"%d,", jj);
|
||||
} // => напечатает "0,"
|
||||
// "1,"
|
||||
// "2,"
|
||||
// "3,"
|
||||
|
||||
// // Цикл просмотра
|
||||
NSArray *values = @[@0, @1, @2, @3];
|
||||
for (NSNumber *value in values)
|
||||
{
|
||||
NSLog(@"%@,", value);
|
||||
} // => напечатает "0,"
|
||||
// "1,"
|
||||
// "2,"
|
||||
// "3,"
|
||||
|
||||
// Обработка исключений
|
||||
@try
|
||||
{
|
||||
// Ваше исключение здесь
|
||||
@throw [NSException exceptionWithName:@"FileNotFoundException"
|
||||
reason:@"File Not Found on System" userInfo:nil];
|
||||
} @catch (NSException * e)
|
||||
{
|
||||
NSLog(@"Exception: %@", e);
|
||||
} @finally
|
||||
{
|
||||
NSLog(@"Finally");
|
||||
} // => напечатает "Exception: File Not Found on System"
|
||||
// "Finally"
|
||||
|
||||
///////////////////////////////////////
|
||||
// Объекты
|
||||
///////////////////////////////////////
|
||||
|
||||
// Создание объектов через выделение памяти и инициализацию.
|
||||
// Объект не является полнофункциональным пока обе части не выполнятся.
|
||||
MyClass *myObject = [[MyClass alloc] init];
|
||||
|
||||
// В Objective-C можель ООП базируется на передаче сообщений.
|
||||
// В Objective-C Вы не просто вызваете метод; вы посылаете сообщение.
|
||||
[myObject instanceMethodWithParameter:@"Steve Jobs"];
|
||||
|
||||
// Очищайте память, перед завершением работы программы.
|
||||
[pool drain];
|
||||
|
||||
// Конец программы.
|
||||
return 0;
|
||||
}
|
||||
|
||||
///////////////////////////////////////
|
||||
// Классы и функции
|
||||
///////////////////////////////////////
|
||||
|
||||
// Объявляйте свой класс в файле МойКласс.h
|
||||
// Синтаксис объявления:
|
||||
// @interface ИмяКласса : ИмяКлассаРодителя <ИмплементируемыеПротоколы>
|
||||
// {
|
||||
// Объявление переменных;
|
||||
// }
|
||||
// -/+ (тип) Объявление метода(ов).
|
||||
// @end
|
||||
|
||||
|
||||
@interface MyClass : NSObject <MyProtocol>
|
||||
{
|
||||
int count;
|
||||
id data;
|
||||
NSString *name;
|
||||
}
|
||||
// При объявлении свойств сразу генерируются геттер и сеттер
|
||||
@property int count;
|
||||
@property (copy) NSString *name; // Скопировать объект в ходе присвоения.
|
||||
@property (readonly) id data; // Генерация только геттера
|
||||
|
||||
// Методы
|
||||
+/- (return type)methodSignature:(Parameter Type *)parameterName;
|
||||
|
||||
// + для методов класса
|
||||
+ (NSString *)classMethod;
|
||||
|
||||
// - для метода объекта
|
||||
- (NSString *)instanceMethodWithParameter:(NSString *)string;
|
||||
- (NSNumber *)methodAParameterAsString:(NSString*)string andAParameterAsNumber:(NSNumber *)number;
|
||||
|
||||
@end
|
||||
|
||||
// Имплементируйте методы в файле МойКласс.m:
|
||||
|
||||
@implementation MyClass
|
||||
|
||||
// Вызывается при высвобождении памяти под объектом
|
||||
- (void)dealloc
|
||||
{
|
||||
}
|
||||
|
||||
// Конструкторы – это способ осздания объектов класса.
|
||||
// Это обычный конструктор вызываемый при создании объекта клсааа.
|
||||
- (id)init
|
||||
{
|
||||
if ((self = [super init]))
|
||||
{
|
||||
self.count = 1;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (NSString *)classMethod
|
||||
{
|
||||
return [[self alloc] init];
|
||||
}
|
||||
|
||||
- (NSString *)instanceMethodWithParameter:(NSString *)string
|
||||
{
|
||||
return @"New string";
|
||||
}
|
||||
|
||||
- (NSNumber *)methodAParameterAsString:(NSString*)string andAParameterAsNumber:(NSNumber *)number
|
||||
{
|
||||
return @42;
|
||||
}
|
||||
|
||||
// Методы объявленные в МyProtocol (см. далее)
|
||||
- (void)myProtocolMethod
|
||||
{
|
||||
// имплементация
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
/*
|
||||
* Протокол объявляет методы которые должны быть имплементированы
|
||||
* Протокол не является классом. Он просто определяет интерфейс,
|
||||
* который должен быть имплементирован.
|
||||
*/
|
||||
|
||||
@protocol MyProtocol
|
||||
- (void)myProtocolMethod;
|
||||
@end
|
||||
```
|
||||
## На почитать
|
||||
|
||||
[Wikipedia Objective-C](http://en.wikipedia.org/wiki/Objective-C)
|
||||
|
||||
[Learning Objective-C](http://developer.apple.com/library/ios/referencelibrary/GettingStarted/Learning_Objective-C_A_Primer/)
|
||||
|
||||
[iOS For High School Students: Getting Started](http://www.raywenderlich.com/5600/ios-for-high-school-students-getting-started)
|
||||
|
||||
[iOS разработчик: Обзор книг для новичка](http://habrahabr.ru/post/166213/)
|
||||
|
||||
[Хочешь быть iOS разработчиком? Будь им!](http://www.pvsm.ru/ios/12662/print/)
|
@ -3,6 +3,7 @@ language: php
|
||||
contributors:
|
||||
- ["Malcolm Fell", "http://emarref.net/"]
|
||||
- ["Trismegiste", "https://github.com/Trismegiste"]
|
||||
translators:
|
||||
- ["SlaF", "https://github.com/SlaF"]
|
||||
lang: ru-ru
|
||||
filename: learnphp-ru.php
|
||||
|
@ -2,16 +2,18 @@
|
||||
language: python
|
||||
lang: ru-ru
|
||||
contributors:
|
||||
- ["Louie Dinh", "http://ldinh.ca"]
|
||||
translators:
|
||||
- ["Yury Timofeev", "http://twitter.com/gagar1n"]
|
||||
filename: learnpython-ru.py
|
||||
---
|
||||
|
||||
Язык Python был создан Гвидо ван Россумом в ранние 90-е. Сегодня это один из самых популярных
|
||||
языков. Я влюбился в него благодаря его понятному и доходчивому синтаксису - это почти что исполняемый псевдокод.
|
||||
Язык Python был создан Гвидо ван Россумом в начале 90-х. Сейчас это один из самых популярных
|
||||
языков. Я люблю его за его понятный и доходчивый синтаксис - это почти что исполняемый псевдокод.
|
||||
|
||||
Обратная связь будет высоко оценена! Вы можете связаться со мной: [@louiedinh](http://twitter.com/louiedinh) или louiedinh [at] [google's email service]
|
||||
С благодарностью жду ваших отзывов: [@louiedinh](http://twitter.com/louiedinh) или louiedinh [at] [google's email service]
|
||||
|
||||
Замечание: Эта статья относится к Python 2.7, но должна быть применима к Python 2.x. Скоро ожидается версия и для Python 3!
|
||||
Замечание: Эта статья относится к Python 2.7, но должно работать и в Python 2.x. Скоро будет версия и для Python 3!
|
||||
|
||||
```python
|
||||
# Однострочные комментарии начинаются с hash-символа.
|
||||
@ -21,25 +23,25 @@ filename: learnpython-ru.py
|
||||
"""
|
||||
|
||||
####################################################
|
||||
## 1. Примитивные типы данных и операторв
|
||||
## 1. Примитивные типы данных и операторов
|
||||
####################################################
|
||||
|
||||
# У вас есть числа
|
||||
3 #=> 3
|
||||
|
||||
# Математика работает так, как вы и думаете
|
||||
# Математика работает вполне ожидаемо
|
||||
1 + 1 #=> 2
|
||||
8 - 1 #=> 7
|
||||
10 * 2 #=> 20
|
||||
35 / 5 #=> 7
|
||||
|
||||
# Деление немного сложнее. Это деление целых чисел и результат
|
||||
# автоматически округляется в меньшую сторону.
|
||||
# А вот деление немного сложнее. В этом случае происходит деление
|
||||
№ целых чисел и результат автоматически округляется в меньшую сторону.
|
||||
5 / 2 #=> 2
|
||||
|
||||
# Чтобы научиться делить, сначала нужно немного узнать о дробных числах.
|
||||
2.0 # Это дробное число.
|
||||
11.0 / 4.0 #=> 2.75 вооот... гораздо лучше
|
||||
2.0 # Это дробное число
|
||||
11.0 / 4.0 #=> 2.75 Вооот... Так гораздо лучше
|
||||
|
||||
# Приоритет операций указывается скобками
|
||||
(1 + 3) * 2 #=> 8
|
||||
@ -60,7 +62,7 @@ not False #=> True
|
||||
1 != 1 #=> False
|
||||
2 != 1 #=> True
|
||||
|
||||
# Больше сравнений
|
||||
# Еще немного сравнений
|
||||
1 < 10 #=> True
|
||||
1 > 10 #=> False
|
||||
2 <= 2 #=> True
|
||||
@ -70,36 +72,36 @@ not False #=> True
|
||||
1 < 2 < 3 #=> True
|
||||
2 < 3 < 2 #=> False
|
||||
|
||||
# Строки создаются при символом " или '
|
||||
# Строки определяются символом " или '
|
||||
"Это строка."
|
||||
'Это тоже строка.'
|
||||
|
||||
# Строки тоже могут складываться!
|
||||
# И строки тоже могут складываться!
|
||||
"Привет " + "мир!" #=> "Привет мир!"
|
||||
|
||||
# Со строкой можно работать как со списком символов
|
||||
# Со строкой можно работать, как со списком символов
|
||||
"Это строка"[0] #=> 'Э'
|
||||
|
||||
# % используется для форматирования строк, например:
|
||||
# Символ % используется для форматирования строк, например:
|
||||
"%s могут быть %s" % ("строки", "интерполированы")
|
||||
|
||||
# Новый метод форматирования строк - использование метода format.
|
||||
# Это предпочитаемый способ.
|
||||
"{0} могут быть {1}".format("строки", "форматированы")
|
||||
# Вы можете использовать ключевые слова, если не хотите считать.
|
||||
# Если вы не хотите считать, можете использовать ключевые слова.
|
||||
"{name} хочет есть {food}".format(name="Боб", food="лазанью")
|
||||
|
||||
# None является объектом
|
||||
None #=> None
|
||||
|
||||
# Не используйте оператор равенства `==` для сравнения
|
||||
# объектов с None. Используйте для этого `is`
|
||||
# Не используйте оператор равенства '=='' для сравнения
|
||||
# объектов с None. Используйте для этого 'is'
|
||||
"etc" is None #=> False
|
||||
None is None #=> True
|
||||
|
||||
# Оператор 'is' проверяет идентичность объектов. Он не
|
||||
# очень полезен при работе с примитивными типами, но
|
||||
# очень полезен при работе с объектами.
|
||||
# зато просто незаменим при работе с объектами.
|
||||
|
||||
# None, 0, и пустые строки/списки равны False.
|
||||
# Все остальные значения равны True
|
||||
@ -111,15 +113,15 @@ None is None #=> True
|
||||
## 2. Переменные и коллекции
|
||||
####################################################
|
||||
|
||||
# Печать довольно проста
|
||||
# Печатать довольно просто
|
||||
print "Я Python. Приятно познакомиться!"
|
||||
|
||||
|
||||
# Необязательно объявлять переменные перед присваиванием им значения.
|
||||
# Необязательно объявлять переменные перед их инициализацией.
|
||||
some_var = 5 # По соглашению используется нижний_регистр_с_подчеркиваниями
|
||||
some_var #=> 5
|
||||
|
||||
# При попытке доступа к переменной, которой не было ранее присвоено значение,
|
||||
# При попытке доступа к неинициализированной переменной,
|
||||
# выбрасывается исключение.
|
||||
# См. раздел "Поток управления" для информации об исключениях.
|
||||
some_other_var # Выбрасывает ошибку именования
|
||||
@ -133,25 +135,25 @@ li = []
|
||||
other_li = [4, 5, 6]
|
||||
|
||||
# Объекты добавляются в конец списка методом append
|
||||
li.append(1) #li содержит [1]
|
||||
li.append(2) #li содержит [1, 2]
|
||||
li.append(4) #li содержит [1, 2, 4]
|
||||
li.append(3) #li содержит [1, 2, 4, 3]
|
||||
# Удаляются с конца методом pop
|
||||
li.pop() #=> 3 и li содержит [1, 2, 4]
|
||||
# Положим его обратно
|
||||
li.append(3) # li содержит [1, 2, 4, 3] опять.
|
||||
li.append(1) # [1]
|
||||
li.append(2) # [1, 2]
|
||||
li.append(4) # [1, 2, 4]
|
||||
li.append(3) # [1, 2, 4, 3]
|
||||
# И удаляются с конца методом pop
|
||||
li.pop() #=> возвращает 3 и li становится равен [1, 2, 4]
|
||||
# Положим элемент обратно
|
||||
li.append(3) # [1, 2, 4, 3].
|
||||
|
||||
# Обращайтесь со списком, как с обычным массивом
|
||||
li[0] #=> 1
|
||||
# Посмотрим на последний элемент
|
||||
# Обратимся к последнему элементу
|
||||
li[-1] #=> 3
|
||||
|
||||
# Попытка выйти за границы массива приводит к IndexError
|
||||
# Попытка выйти за границы массива приведет к IndexError
|
||||
li[4] # Выдает IndexError
|
||||
|
||||
# Можно обращаться к диапазону, используя "кусочный синтаксис" (slice syntax)
|
||||
# (Для тех из вас, кто любит математику, это замкнуто/открытый интервал.)
|
||||
# (Для тех, кто любит математику, это называется замкнуто/открытый интервал.)
|
||||
li[1:3] #=> [2, 4]
|
||||
# Опускаем начало
|
||||
li[2:] #=> [4, 3]
|
||||
@ -159,38 +161,38 @@ li[2:] #=> [4, 3]
|
||||
li[:3] #=> [1, 2, 4]
|
||||
|
||||
# Удаляем произвольные элементы из списка оператором del
|
||||
del li[2] # li содержит [1, 2, 3]
|
||||
del li[2] # [1, 2, 3]
|
||||
|
||||
# Вы можете складывать списки
|
||||
li + other_li #=> [1, 2, 3, 4, 5, 6] - ЗАмечание: li и other_li остаются нетронутыми
|
||||
li + other_li #=> [1, 2, 3, 4, 5, 6] - Замечание: li и other_li остаются нетронутыми
|
||||
|
||||
# Конкатенировать списки можно методом extend
|
||||
li.extend(other_li) # Теперь li содержит [1, 2, 3, 4, 5, 6]
|
||||
|
||||
# Проверять элемент на вхождение на список оператором in
|
||||
# Проверить элемент на вхождение в список можно оператором in
|
||||
1 in li #=> True
|
||||
|
||||
# Длина списка вычисляется при помощи len
|
||||
# Длина списка вычисляется функцией len
|
||||
len(li) #=> 6
|
||||
|
||||
|
||||
# Кортежи - это как списки, только неизменяемые
|
||||
# Кортежи - это такие списки, только неизменяемые
|
||||
tup = (1, 2, 3)
|
||||
tup[0] #=> 1
|
||||
tup[0] = 3 # Выдает TypeError
|
||||
|
||||
# Все те же штуки можно делать и с кортежами
|
||||
# Все то же самое можно делать и с кортежами
|
||||
len(tup) #=> 3
|
||||
tup + (4, 5, 6) #=> (1, 2, 3, 4, 5, 6)
|
||||
tup[:2] #=> (1, 2)
|
||||
2 in tup #=> True
|
||||
|
||||
# Вы можете распаковывать кортежи (или списки) в переменные
|
||||
a, b, c = (1, 2, 3) # a теперь равно 1, b равно 2 и c равно 3
|
||||
a, b, c = (1, 2, 3) # a == 1, b == 2 и c == 3
|
||||
# Кортежи создаются по умолчанию, если опущены скобки
|
||||
d, e, f = 4, 5, 6
|
||||
# Обратите внимание, как легко поменять местами значения двух переменных
|
||||
e, d = d, e # d теперь равно 5 and e равно 4
|
||||
e, d = d, e # теперь d == 5, а e == 4
|
||||
|
||||
|
||||
# Словари содержат ассоциативные массивы
|
||||
@ -208,7 +210,7 @@ filled_dict.keys() #=> ["three", "two", "one"]
|
||||
|
||||
# Можно получить и все значения в виде списка
|
||||
filled_dict.values() #=> [3, 2, 1]
|
||||
# Замечание - то же самое, что и выше, насчет порядка ключей
|
||||
# То же самое замечание насчет порядка ключей справедливо и здесь
|
||||
|
||||
# При помощи оператора in можно проверять ключи на вхождение в словарь
|
||||
"one" in filled_dict #=> True
|
||||
@ -260,7 +262,7 @@ filled_set | other_set #=> {1, 2, 3, 4, 5, 6}
|
||||
## 3. Поток управления
|
||||
####################################################
|
||||
|
||||
# Давайте заведем переменную
|
||||
# Для начала заведем переменную
|
||||
some_var = 5
|
||||
|
||||
# Так выглядит выражение if. Отступы в python очень важны!
|
||||
@ -274,8 +276,9 @@ else: # Это тоже необязательно.
|
||||
|
||||
|
||||
"""
|
||||
Циклы For проходят по циклам
|
||||
результат:
|
||||
Циклы For проходят по спискам
|
||||
|
||||
Результат:
|
||||
собака это млекопитающее
|
||||
кошка это млекопитающее
|
||||
мышь это млекопитающее
|
||||
@ -287,7 +290,7 @@ for animal in ["собака", "кошка", "мышь"]:
|
||||
"""
|
||||
`range(number)` возвращает список чисел
|
||||
от нуля до заданного числа
|
||||
результат:
|
||||
Результат:
|
||||
0
|
||||
1
|
||||
2
|
||||
@ -298,7 +301,7 @@ for i in range(4):
|
||||
|
||||
"""
|
||||
Циклы while продолжаются до тех пор, пока указанное условие не станет ложным.
|
||||
результат:
|
||||
Результат:
|
||||
0
|
||||
1
|
||||
2
|
||||
@ -422,10 +425,10 @@ class Human(object):
|
||||
|
||||
# Инстанцирование класса
|
||||
i = Human(name="Иван")
|
||||
print i.say("привет") # выводит "Иван: привет"
|
||||
print i.say("привет") # "Иван: привет"
|
||||
|
||||
j = Human("Петр")
|
||||
print j.say("Привет") #выводит "Петр: привет"
|
||||
print j.say("Привет") # "Петр: привет"
|
||||
|
||||
# Вызов метода класса
|
||||
i.get_species() #=> "H. sapiens"
|
||||
@ -453,7 +456,7 @@ print ceil(3.7) #=> 4.0
|
||||
print floor(3.7) #=> 3.0
|
||||
|
||||
# Можете импортировать все функции модуля.
|
||||
# Предупреждение: не рекомендуется
|
||||
# (Хотя это и не рекомендуется)
|
||||
from math import *
|
||||
|
||||
# Можете сокращать имена модулей
|
||||
@ -472,7 +475,7 @@ dir(math)
|
||||
|
||||
```
|
||||
|
||||
## Хочется большего?
|
||||
## Хотите еще?
|
||||
|
||||
### Бесплатные онлайн-материалы
|
||||
|
||||
@ -482,7 +485,7 @@ dir(math)
|
||||
* [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/)
|
||||
* [Python Module of the Week](http://pymotw.com/2/)
|
||||
|
||||
### Готовьте деньги
|
||||
### Платные
|
||||
|
||||
* [Programming Python](http://www.amazon.com/gp/product/0596158106/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596158106&linkCode=as2&tag=homebits04-20)
|
||||
* [Dive Into Python](http://www.amazon.com/gp/product/1441413022/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1441413022&linkCode=as2&tag=homebits04-20)
|
||||
|
@ -8,6 +8,7 @@ contributors:
|
||||
- ["Luke Holder", "http://twitter.com/lukeholder"]
|
||||
- ["Tristan Hume", "http://thume.ca/"]
|
||||
- ["Nick LaMuro", "https://github.com/NickLaMuro"]
|
||||
translators:
|
||||
- ["Alexey Makarov", "https://github.com/Anakros"]
|
||||
---
|
||||
|
||||
@ -42,7 +43,7 @@ contributors:
|
||||
|
||||
# Логические величины -- это объекты
|
||||
nil # Здесь ничего нет
|
||||
true # правда
|
||||
true # истина
|
||||
false # ложь
|
||||
|
||||
nil.class #=> NilClass
|
||||
@ -78,7 +79,8 @@ false.class #=> FalseClass
|
||||
|
||||
placeholder = "использовать интерполяцию строк"
|
||||
"Я могу #{placeholder}, когда создаю строку с двойными кавычками"
|
||||
#=> "Я могу использовать интерполяцию строк, когда создаю строку с двойными кавычками"
|
||||
#=> "Я могу использовать интерполяцию строк,
|
||||
# когда создаю строку с двойными кавычками"
|
||||
|
||||
|
||||
# печатать в стандартный вывод
|
||||
@ -106,10 +108,10 @@ path = '/bad/name/'
|
||||
# Идентификаторы (тоже объекты)
|
||||
|
||||
# Идентификаторы -- это неизменяемые, многоразовые константы.
|
||||
# Для каждого идентификатора (кроме текста) сохраняется цифровой хэш. При последующем
|
||||
# использовании идентификатора, заместо создания нового объекта, будет найден уже
|
||||
# существующий по цифровому хэшу. Они часто используются вместо строк
|
||||
# для ускорения работы приложений
|
||||
# Для каждого идентификатора (кроме текста) сохраняется цифровой хэш.
|
||||
# При последующем использовании идентификатора, заместо создания нового объекта,
|
||||
# будет найден уже существующий по цифровому хэшу.
|
||||
# Они часто используются вместо строк для ускорения работы приложений
|
||||
|
||||
:pending.class #=> Symbol
|
||||
|
||||
@ -177,15 +179,15 @@ new_hash.keys #=> [:defcon, :action]
|
||||
# Управление ходом выполнения (Управляющие структуры)
|
||||
|
||||
if true
|
||||
"if условие"
|
||||
"Если истина"
|
||||
elsif false
|
||||
"else if, условие"
|
||||
"Иначе, если ложь (опционально)"
|
||||
else
|
||||
"else, условие"
|
||||
"Во всех других случаях"
|
||||
end
|
||||
|
||||
for counter in 1..5
|
||||
puts "#итерация {counter}"
|
||||
puts "итерация #{counter}"
|
||||
end
|
||||
#=> итерация 1
|
||||
#=> итерация 2
|
||||
@ -196,10 +198,11 @@ end
|
||||
# Однако, никто не использует "for" для циклов.
|
||||
# Вместо него Вы должны использовать метод "each" вместе с блоком кода.
|
||||
#
|
||||
# Блок кода -- это один из вариантов создания замыканий (лямбды, анонимные функции).
|
||||
# Блок кода -- это один из вариантов создания замыканий (лямбды,
|
||||
# анонимные функции).
|
||||
# Блок может только передаваться методу, сам по себе он существовать не может.
|
||||
# "for" не имеет своей области видимости и все переменные, объявленные в нём
|
||||
# будут доступны отовсюду. "each" вместе с блоком создаёт свою область видимости.
|
||||
# будут доступны отовсюду. "each" вместе с блоком создаёт свою область видимости
|
||||
|
||||
# Метод "each" для диапазона значений запускает блок кода один раз
|
||||
# для каждого из значений диапазона
|
||||
@ -218,7 +221,7 @@ end
|
||||
# Вы также можете ограничивать блоки фигурными скобками:
|
||||
(1..5).each {|counter| puts "итерация #{counter}"}
|
||||
|
||||
# Содержимое управляющих структур также можно перебирать используя "each":
|
||||
# Содержимое структурных данных также можно перебирать используя "each":
|
||||
array.each do |element|
|
||||
puts "#{element} -- часть массива"
|
||||
end
|
||||
@ -349,10 +352,27 @@ dwight.name #=> "Dwight K. Schrute"
|
||||
# Вызов метода класса
|
||||
Human.say("Hi") #=> "Hi"
|
||||
|
||||
# Класс тоже объект в Ruby. Потому класс может иметь переменные экземпляра.
|
||||
# Область видимости переменной определяется тем, как мы даём имя переменной.
|
||||
# Переменные, имя которых начинается с "$" имеют глобальную область видимости
|
||||
$var = "I'm a global var"
|
||||
defined? $var #=> "global-variable"
|
||||
|
||||
# Переменная экземпляра класса, она видна только в экземпляре
|
||||
@var = "I'm an instance var"
|
||||
defined? @var #=> "instance-variable"
|
||||
|
||||
# Переменная класса, видна для всех экземпляров этого класса и в самом классе
|
||||
@@var = "I'm a class var"
|
||||
defined? @@var #=> "class variable"
|
||||
|
||||
# Имена переменных с большой буквы используются для создания констант
|
||||
Var = "I'm a constant"
|
||||
defined? Var #=> "constant"
|
||||
|
||||
# Класс тоже объект в Ruby. Класс может иметь переменные экземпляра.
|
||||
# Переменная класса доступна в классе, его экземплярах и его потомках.
|
||||
|
||||
# Базовый класс
|
||||
# Пример класса
|
||||
class Human
|
||||
@@foo = 0
|
||||
|
||||
@ -395,4 +415,54 @@ end
|
||||
Human.bar # 0
|
||||
Doctor.bar # nil
|
||||
|
||||
module ModuleExample
|
||||
def foo
|
||||
'foo'
|
||||
end
|
||||
end
|
||||
|
||||
# Включение модулей в класс добавляет их методы в экземпляр класса
|
||||
# Или в сам класс, зависит только от метода подключения
|
||||
class Person
|
||||
include ModuleExample
|
||||
end
|
||||
|
||||
class Book
|
||||
extend ModuleExample
|
||||
end
|
||||
|
||||
Person.foo # => NoMethodError: undefined method `foo' for Person:Class
|
||||
Person.new.foo # => 'foo'
|
||||
Book.foo # => 'foo'
|
||||
Book.new.foo # => NoMethodError: undefined method `foo'
|
||||
|
||||
# Коллбэки при подключении модуля
|
||||
|
||||
module ConcernExample
|
||||
def self.included(base)
|
||||
base.extend(ClassMethods)
|
||||
base.send(:include, InstanceMethods)
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
def bar
|
||||
'bar'
|
||||
end
|
||||
end
|
||||
|
||||
module InstanceMethods
|
||||
def qux
|
||||
'qux'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Something
|
||||
include ConcernExample
|
||||
end
|
||||
|
||||
Something.bar # => 'bar'
|
||||
Something.qux # => NoMethodError: undefined method `qux'
|
||||
Something.new.bar # => NoMethodError: undefined method `bar'
|
||||
Something.new.qux # => 'qux'
|
||||
```
|
||||
|
@ -121,9 +121,9 @@ dependency graph to resolve.
|
||||
|
||||
# Testing
|
||||
|
||||
Testing is a large of ruby culture. Ruby comes with its own Unit-style testing
|
||||
framework called minitest (Or TestUnit for ruby version 1.8.x). There are many
|
||||
testing libraries with different goals.
|
||||
Testing is a large part of ruby culture. Ruby comes with its own Unit-style
|
||||
testing framework called minitest (Or TestUnit for ruby version 1.8.x). There
|
||||
are many testing libraries with different goals.
|
||||
|
||||
* TestUnit - Ruby 1.8's built-in "Unit-style" testing framework
|
||||
* minitest - Ruby 1.9/2.0's built-in testing framework
|
||||
|
@ -7,6 +7,7 @@ contributors:
|
||||
- ["Luke Holder", "http://twitter.com/lukeholder"]
|
||||
- ["Tristan Hume", "http://thume.ca/"]
|
||||
- ["Nick LaMuro", "https://github.com/NickLaMuro"]
|
||||
- ["Marcos Brizeno", "http://www.about.me/marcosbrizeno"]
|
||||
---
|
||||
|
||||
```ruby
|
||||
@ -138,8 +139,8 @@ array.[] 12 #=> nil
|
||||
# From the end
|
||||
array[-1] #=> 5
|
||||
|
||||
# With a start and end index
|
||||
array[2, 4] #=> [3, 4, 5]
|
||||
# With a start index and length
|
||||
array[2, 3] #=> [3, 4, 5]
|
||||
|
||||
# Or with a range
|
||||
array[1..3] #=> [2, 3, 4]
|
||||
@ -286,6 +287,18 @@ surround { puts 'hello world' }
|
||||
# }
|
||||
|
||||
|
||||
# You can pass a block to a function
|
||||
# "&" marks a reference to a passed block
|
||||
def guests(&block)
|
||||
block.call "some_argument"
|
||||
end
|
||||
|
||||
# You can pass a list of arguments, which will be converted into an array
|
||||
# That's what splat operator ("*") is for
|
||||
def guests(*array)
|
||||
array.each { |guest| puts "#{guest}" }
|
||||
end
|
||||
|
||||
# Define a class with the class keyword
|
||||
class Human
|
||||
|
||||
@ -339,6 +352,23 @@ dwight.name #=> "Dwight K. Schrute"
|
||||
# Call the class method
|
||||
Human.say("Hi") #=> "Hi"
|
||||
|
||||
# Variable's scopes are defined by the way we name them.
|
||||
# Variables that start with $ have global scope
|
||||
$var = "I'm a global var"
|
||||
defined? $var #=> "global-variable"
|
||||
|
||||
# Variables that start with @ have instance scope
|
||||
@var = "I'm an instance var"
|
||||
defined? @var #=> "instance-variable"
|
||||
|
||||
# Variables that start with @@ have class scope
|
||||
@@var = "I'm a class var"
|
||||
defined? @@var #=> "class variable"
|
||||
|
||||
# Variables that start with a capital letter are constants
|
||||
Var = "I'm a constant"
|
||||
defined? Var #=> "constant"
|
||||
|
||||
# Class also is object in ruby. So class can have instance variables.
|
||||
# Class variable is shared among the class and all of its descendants.
|
||||
|
||||
@ -385,4 +415,55 @@ end
|
||||
Human.bar # 0
|
||||
Doctor.bar # nil
|
||||
|
||||
module ModuleExample
|
||||
def foo
|
||||
'foo'
|
||||
end
|
||||
end
|
||||
|
||||
# Including modules binds the methods to the object instance
|
||||
# Extending modules binds the methods to the class instance
|
||||
|
||||
class Person
|
||||
include ModuleExample
|
||||
end
|
||||
|
||||
class Book
|
||||
extend ModuleExample
|
||||
end
|
||||
|
||||
Person.foo # => NoMethodError: undefined method `foo' for Person:Class
|
||||
Person.new.foo # => 'foo'
|
||||
Book.foo # => 'foo'
|
||||
Book.new.foo # => NoMethodError: undefined method `foo'
|
||||
|
||||
# Callbacks when including and extending a module are executed
|
||||
|
||||
module ConcernExample
|
||||
def self.included(base)
|
||||
base.extend(ClassMethods)
|
||||
base.send(:include, InstanceMethods)
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
def bar
|
||||
'bar'
|
||||
end
|
||||
end
|
||||
|
||||
module InstanceMethods
|
||||
def qux
|
||||
'qux'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Something
|
||||
include ConcernExample
|
||||
end
|
||||
|
||||
Something.bar # => 'bar'
|
||||
Something.qux # => NoMethodError: undefined method `qux'
|
||||
Something.new.bar # => NoMethodError: undefined method `bar'
|
||||
Something.new.qux # => 'qux'
|
||||
```
|
||||
|
@ -374,7 +374,7 @@ import scala.collection.immutable._
|
||||
import scala.collection.immutable.{List, Map}
|
||||
|
||||
// Rename an import using '=>'
|
||||
import scala.collection.immutable{ List => ImmutableList }
|
||||
import scala.collection.immutable.{ List => ImmutableList }
|
||||
|
||||
// Import all classes, except some. The following excludes Map and Set:
|
||||
import scala.collection.immutable.{Map => _, Set => _, _}
|
||||
|
87
tr-tr/brainfuck-tr.html.markdown
Normal file
87
tr-tr/brainfuck-tr.html.markdown
Normal file
@ -0,0 +1,87 @@
|
||||
---
|
||||
language: brainfuck
|
||||
filename: brainfuck-tr
|
||||
contributors:
|
||||
- ["Prajit Ramachandran", "http://prajitr.github.io"]
|
||||
translators:
|
||||
- ["Haydar KULEKCI", "http://scanf.info/"]
|
||||
lang: tr-tr
|
||||
---
|
||||
|
||||
Brainfuck (normalde brainfuck olarak bütün harfleri küçük olarak yazılır.)
|
||||
son derece minimal bir programlama dilidir. (Sadece 8 komut) ve tamamen
|
||||
Turing'dir.
|
||||
|
||||
```
|
||||
"><+-.,[]" (tırnak işaretleri hariç) karakterleri dışındaki her karakter
|
||||
gözardı edilir.
|
||||
|
||||
Brainfuck 30,000 hücresi olan ve ilk değerleri sıfır olarak atanmış bir
|
||||
dizidir. İşaretçi ilk hücreyi işaret eder.
|
||||
|
||||
Sekik komut vardır:
|
||||
+ : Geçerli hücrenin değerini bir artırır.
|
||||
- : Geçerli hücrenin değerini bir azaltır.
|
||||
> : Veri işaretçisini bir sonraki hücreye hareket ettirir(sağdaki hücreye).
|
||||
< : Veri işaretçisini bir önceki hücreye hareket ettirir(soldaki hücreye).
|
||||
. : Geçerli hücrenin ASCII değerini yazdırır (örn: 65 = 'A').
|
||||
, : Bir girdilik karakteri aktif hücre için okur.
|
||||
[ : Eğer geçerli hücredeki değer sıfır ise, ]ifadesine atlar.
|
||||
Diğer durumlarda bir sonraki yönergeye geçer.
|
||||
] : Eğer geçerli hücredeki değer sıfır ise, bir sonraki yönergeye geçer.
|
||||
Diğer durumlarda, [ ifadesine karşılık gelen yönergelere döner.
|
||||
|
||||
[ ve ] bir while döngüsü oluşturur. Açıkça, dengeli olmalıdırlar.
|
||||
|
||||
Basit bir brainfuck programına göz atalım.
|
||||
|
||||
++++++ [ > ++++++++++ < - ] > +++++ .
|
||||
|
||||
Bu program 'A' karaterini ekrana basar. İlk olarak, #1'inci hücre 6'ya artırılır.
|
||||
#1'inci hücre döngü için kullanılacaktır. Sonra, ([) döngüsüne girilir ve
|
||||
#2'inci hücreye hareket edilir. #2'inci hücre 10 kez artırılır, #1'inci hücreye
|
||||
geri dönülür. #1 hücresini bir azaltır. Bu döngü 6 kez gerçekleşir. (Bu 6 kez
|
||||
azaltmak demektir, #1 hücresi 0 değerini alır ve bu noktada ] ifadesini atlar).
|
||||
|
||||
Bu noktada, biz #1 hücresindeyiz, değeri şu anda 0 ve #2 hücresinin değeri
|
||||
60'tır. Biz #2 hücresine hareket diyoruz ve bu hücreyi 5 defa artırıyoruz.
|
||||
#2'nin şu anki değeri 65 olur. Sonra #2 hücresinin ASCII karşılığını
|
||||
yazdırıyoruz. 65 değerinin ASCII karşılığı 'A'dır. Ekrana 'A' yazılacaktır.
|
||||
|
||||
|
||||
, [ > + < - ] > .
|
||||
|
||||
Bu program kullanıcıdan bir girdi okur, ve karakteri bir diğer hücreye yazdırır,
|
||||
ve daha sonra aynı karakteri ekrana yazdırır.
|
||||
|
||||
, ifadesi kullanıcıdan karakteri #1 hücresine okur. Sonra bir döngü
|
||||
başlar. #2 hücresine hareket edilir, #2 hücresinin değeri bir artırılır, #1
|
||||
hücresine geri dönülür, ve #1 hücresinin değer bir azaltılır. Bu #1 hücresinin
|
||||
değeri 0 olana kadar devam eder ve #2 hücresi #1'in eski değerini tutar. Çünkü
|
||||
biz #1 hücresindeki verileri döngü süresince #2 hücresine taşıyoruz, ve sonunda
|
||||
#2 hücresinin ASCII değerini yazdırıyoruz.
|
||||
|
||||
Boşluk karakteri sadece okunabilirliği artırmak içindir. Aşağıdaki gibi de
|
||||
yazabilirsiniz.
|
||||
|
||||
,[>+<-]>.
|
||||
|
||||
|
||||
Bu uygulamanın ne yaptığına bakalım:
|
||||
|
||||
,>,< [ > [ >+ >+ << -] >> [- << + >>] <<< -] >>
|
||||
|
||||
Bu program 2 sayı alır, ve birbiri ile çarpar.
|
||||
|
||||
Özetle, ilk olarak iki girdi alır. Sonra, #1 hücresinde şarta bağlı harici bir
|
||||
döngü başlar. Sonra #2 ye hareket edilir, ve içerde #2 hücresine bağlı bir döngü
|
||||
daha başlar ve #3 hücresinin değerini artırır. Ama, Bir problem vardır: iç
|
||||
döngünün sonunda #2'inci hücrenin değeri 0 olacaktır. Bunu çözmek için #4
|
||||
hücresinin de değerini yükseltiyoruz, ve sonra #4 hücresinin değerini #2'ye
|
||||
kopyalıyoruz.
|
||||
```
|
||||
|
||||
İşte brainfuck. Zor değil değil mi? Eğlenmek için kendi programınızı
|
||||
yazabilirsiniz, veya farklı bir dilde brainfuck yorumlayıcısı yazabilirsiniz.
|
||||
Yorumlayıcı oldukça basittir, ama mazoşist iseniz, brainfuck içerisinde bir
|
||||
brainfuck yorumlayıcısı yazmayı deneyebilirsiniz.
|
@ -95,6 +95,10 @@ int main() {
|
||||
// is not evaluated (except VLAs (see below)).
|
||||
// The value it yields in this case is a compile-time constant.
|
||||
int a = 1;
|
||||
|
||||
// size_t bir objeyi temsil etmek için kullanılan 2 byte uzunluğundaki bir
|
||||
// işaretsiz tam sayı tipidir
|
||||
|
||||
size_t size = sizeof(a++); // a++ is not evaluated
|
||||
printf("sizeof(a++) = %zu where a = %d\n", size, a);
|
||||
// prints "sizeof(a++) = 4 where a = 1" (on a 32-bit architecture)
|
||||
|
320
tr-tr/objective-c-tr.html.markdown
Normal file
320
tr-tr/objective-c-tr.html.markdown
Normal file
@ -0,0 +1,320 @@
|
||||
---
|
||||
language: Objective-C
|
||||
contributors:
|
||||
- ["Eugene Yagrushkin", "www.about.me/yagrushkin"]
|
||||
- ["Yannick Loriot", "https://github.com/YannickL"]
|
||||
filename: LearnObjectiveC-tr.m
|
||||
translators:
|
||||
- ["Haydar KULEKCI", "http://scanf.info/"]
|
||||
lang: tr-tr
|
||||
---
|
||||
|
||||
Objective-C Apple tarafından, OSX ve iOS işletim sistemleri ve onların
|
||||
kendi çatıları olan Cocoa ve Cocoa Touch için kullanılan bir programlama dilidir.
|
||||
Genel açamlı, object-oriented bir yapıya sahip programlama dilidir. C
|
||||
programlama diline Smalltalk stilinde mesajlaşma ekler.
|
||||
|
||||
```cpp
|
||||
// Tek satır yorum // işaretleri ile başlar
|
||||
|
||||
/*
|
||||
Çoklu satır yorum bu şekilde görünür.
|
||||
*/
|
||||
|
||||
// #import ile Foundation başlıklarını projeye import edebiliriz.
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "MyClass.h"
|
||||
|
||||
// Progarmınızı girişi bir main fonksiyonudur ve bir integer değer döner.
|
||||
int main (int argc, const char * argv[])
|
||||
{
|
||||
// Programdaki bellek kullanımını kontrol etmek için autorelease bir
|
||||
// oluşturuyoruz. Autorelease bellekte kullanılmayan değerlerin kendi
|
||||
// kendini silmesi demektir.
|
||||
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
// NSLog konsola bir satırlık bilgi yazdırmak için kullanılır.
|
||||
NSLog(@"Hello World!"); // "Hello World!" değeri yazdırılır.
|
||||
|
||||
///////////////////////////////////////
|
||||
// Tipler & Değişkenler
|
||||
///////////////////////////////////////
|
||||
|
||||
// Basit Tanımlamalar
|
||||
int myPrimitive1 = 1;
|
||||
long myPrimitive2 = 234554664565;
|
||||
|
||||
// Nesne Tanımlamaları
|
||||
// strongly-typed nesne tanımlaması için karakter değişken isminin önüne
|
||||
// * karakteri konulur.
|
||||
MyClass *myObject1 = nil; // Strong typing
|
||||
id myObject2 = nil; // Weak typing
|
||||
// %@ bir nesnedir.
|
||||
// 'description' objelerin değerlerinin gösterilmesi için bir düzendir.
|
||||
NSLog(@"%@ and %@", myObject1, [myObject2 description]);
|
||||
// "(null) and (null)" yazdırılacaktır.
|
||||
|
||||
// Karakter Dizisi (String)
|
||||
NSString *worldString = @"World";
|
||||
NSLog(@"Hello %@!", worldString); // "Hello World!" yazdırılacaktır.
|
||||
|
||||
// Karakterler
|
||||
NSNumber *theLetterZNumber = @'Z';
|
||||
char theLetterZ = [theLetterZNumber charValue];
|
||||
NSLog(@"%c", theLetterZ);
|
||||
|
||||
// Tamsayılar
|
||||
NSNumber *fortyTwoNumber = @42;
|
||||
int fortyTwo = [fortyTwoNumber intValue];
|
||||
NSLog(@"%i", fortyTwo);
|
||||
|
||||
NSNumber *fortyTwoUnsignedNumber = @42U;
|
||||
unsigned int fortyTwoUnsigned = [fortyTwoUnsignedNumber unsignedIntValue];
|
||||
NSLog(@"%u", fortyTwoUnsigned);
|
||||
|
||||
NSNumber *fortyTwoShortNumber = [NSNumber numberWithShort:42];
|
||||
short fortyTwoShort = [fortyTwoShortNumber shortValue];
|
||||
NSLog(@"%hi", fortyTwoShort);
|
||||
|
||||
NSNumber *fortyTwoLongNumber = @42L;
|
||||
long fortyTwoLong = [fortyTwoLongNumber longValue];
|
||||
NSLog(@"%li", fortyTwoLong);
|
||||
|
||||
// Kayan Noktalı Sayılar (Floats)
|
||||
NSNumber *piFloatNumber = @3.141592654F;
|
||||
float piFloat = [piFloatNumber floatValue];
|
||||
NSLog(@"%f", piFloat);
|
||||
|
||||
NSNumber *piDoubleNumber = @3.1415926535;
|
||||
piDouble = [piDoubleNumber doubleValue];
|
||||
NSLog(@"%f", piDouble);
|
||||
|
||||
// BOOL Değerler
|
||||
NSNumber *yesNumber = @YES;
|
||||
NSNumber *noNumber = @NO;
|
||||
|
||||
// Dizi objeleri
|
||||
NSArray *anArray = @[@1, @2, @3, @4];
|
||||
NSNumber *thirdNumber = anArray[2];
|
||||
NSLog(@"Third number = %@", thirdNumber); // "Third number = 3" yazdırılır
|
||||
|
||||
// Dictionary objeleri
|
||||
NSDictionary *aDictionary = @{ @"key1" : @"value1", @"key2" : @"value2" };
|
||||
NSObject *valueObject = aDictionary[@"A Key"];
|
||||
NSLog(@"Object = %@", valueObject); // "Object = (null)" yazıdılır
|
||||
|
||||
///////////////////////////////////////
|
||||
// Operatörler
|
||||
///////////////////////////////////////
|
||||
|
||||
// Operatörler C dilindeki gibi çalışır.
|
||||
// Örneğin:
|
||||
2 + 5; // => 7
|
||||
4.2f + 5.1f; // => 9.3f
|
||||
3 == 2; // => 0 (NO)
|
||||
3 != 2; // => 1 (YES)
|
||||
1 && 1; // => 1 (Logical and)
|
||||
0 || 1; // => 1 (Logical or)
|
||||
~0x0F; // => 0xF0 (bitwise negation)
|
||||
0x0F & 0xF0; // => 0x00 (bitwise AND)
|
||||
0x01 << 1; // => 0x02 (bitwise left shift (by 1))
|
||||
|
||||
///////////////////////////////////////
|
||||
// Kontrol Yapıları
|
||||
///////////////////////////////////////
|
||||
|
||||
// If-Else ifadesi
|
||||
if (NO)
|
||||
{
|
||||
NSLog(@"I am never run");
|
||||
} else if (0)
|
||||
{
|
||||
NSLog(@"I am also never run");
|
||||
} else
|
||||
{
|
||||
NSLog(@"I print");
|
||||
}
|
||||
|
||||
// Switch ifadesi
|
||||
switch (2)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
NSLog(@"I am never run");
|
||||
} break;
|
||||
case 1:
|
||||
{
|
||||
NSLog(@"I am also never run");
|
||||
} break;
|
||||
default:
|
||||
{
|
||||
NSLog(@"I print");
|
||||
} break;
|
||||
}
|
||||
|
||||
// While döngü ifadesi
|
||||
int ii = 0;
|
||||
while (ii < 4)
|
||||
{
|
||||
NSLog(@"%d,", ii++); // ii++, ii değişkenini kullanıldıktan
|
||||
//sonra yerinde artırır.
|
||||
} // => "0,"
|
||||
// "1,"
|
||||
// "2,"
|
||||
// "3," yazdırılır
|
||||
|
||||
// For döngü ifadesi
|
||||
int jj;
|
||||
for (jj=0; jj < 4; jj++)
|
||||
{
|
||||
NSLog(@"%d,", jj++);
|
||||
} // => "0,"
|
||||
// "1,"
|
||||
// "2,"
|
||||
// "3," yazdırılır
|
||||
|
||||
// Foreach ifadesi
|
||||
NSArray *values = @[@0, @1, @2, @3];
|
||||
for (NSNumber *value in values)
|
||||
{
|
||||
NSLog(@"%@,", value);
|
||||
} // => "0,"
|
||||
// "1,"
|
||||
// "2,"
|
||||
// "3," yazdırılır
|
||||
|
||||
// Try-Catch-Finally ifadesi
|
||||
@try
|
||||
{
|
||||
// İfadelerinizi buraya yazın
|
||||
@throw [NSException exceptionWithName:@"FileNotFoundException"
|
||||
reason:@"Sistemde Dosya Bulunamadı" userInfo:nil];
|
||||
} @catch (NSException * e)
|
||||
{
|
||||
NSLog(@"Exception: %@", e);
|
||||
} @finally
|
||||
{
|
||||
NSLog(@"Finally");
|
||||
} // => "Exception: Sistemde Dosya Bulunamadı"
|
||||
// "Finally"
|
||||
// yazdırılacaktır
|
||||
|
||||
///////////////////////////////////////
|
||||
// Objeler
|
||||
///////////////////////////////////////
|
||||
|
||||
// Bellekten bir alan ayırmak ve objeyi burada oluşturmak bir obje örneği
|
||||
// oluşturalım. Bir obje allocate ve init aşamalarını bitirmeden tam olarak
|
||||
// işlevsel değildir.
|
||||
MyClass *myObject = [[MyClass alloc] init];
|
||||
|
||||
// Objective-C nesne yönelimli programlama modelinin temelinde objelere
|
||||
// mesaj gönderme vardır.
|
||||
// Objective-C'de bir method çağırılmaz, ona bir mesaj gönderilir.
|
||||
[myObject instanceMethodWithParameter:@"Steve Jobs"];
|
||||
|
||||
// Programda kullanılan bellek temizlenir
|
||||
[pool drain];
|
||||
|
||||
// Program Sonu
|
||||
return 0;
|
||||
}
|
||||
|
||||
///////////////////////////////////////
|
||||
// Sınıflar ve Fonksiyonlar
|
||||
///////////////////////////////////////
|
||||
|
||||
// Sınıfınızı (MyClass.h) header dosyasında tanımlayın:
|
||||
|
||||
// Sınıf tanımlama yapısı:
|
||||
// @interface ClassName : ParentClassName <ImplementedProtocols>
|
||||
// {
|
||||
// Üye değişken (member variable) tanımlaması;
|
||||
// }
|
||||
// -/+ (type) Method tanımlaması;
|
||||
// @end
|
||||
@interface MyClass : NSObject <MyCustomProtocol>
|
||||
{
|
||||
int count;
|
||||
id data;
|
||||
NSString *name;
|
||||
}
|
||||
// getter ve setter için otomatik oluşturulmuş gösterim.
|
||||
@property int count;
|
||||
@property (copy) NSString *name; // Copy the object during assignment.
|
||||
@property (readonly) id data; // Declare only a getter method.
|
||||
|
||||
// Metodlar
|
||||
+/- (return type)methodSignature:(Parameter Type *)parameterName;
|
||||
|
||||
// "+" class metodları içindir
|
||||
+ (NSString *)classMethod;
|
||||
|
||||
// "-" instance metodu içindir
|
||||
- (NSString *)instanceMethodWithParmeter:(NSString *)string;
|
||||
- (NSNumber *)methodAParameterAsString:(NSString*)string andAParameterAsNumber:(NSNumber *)number;
|
||||
|
||||
@end
|
||||
|
||||
// Metodların implementasyonlarını (MyClass.m) dosyasında yapıyoruz:
|
||||
|
||||
@implementation UserObject
|
||||
|
||||
// Obje bellekten silineceği (release) zaman çağırılır
|
||||
- (void)dealloc
|
||||
{
|
||||
}
|
||||
|
||||
// Constructor'lar sınıf oluşturmanın bir yoludur
|
||||
// Bu varsayılan bir constructor'dur ve bir obje oluşturulurken çağrılır.
|
||||
- (id)init
|
||||
{
|
||||
if ((self = [super init]))
|
||||
{
|
||||
self.count = 1;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (NSString *)classMethod
|
||||
{
|
||||
return [[self alloc] init];
|
||||
}
|
||||
|
||||
- (NSString *)instanceMethodWithParmeter:(NSString *)string
|
||||
{
|
||||
return @"New string";
|
||||
}
|
||||
|
||||
- (NSNumber *)methodAParameterAsString:(NSString*)string andAParameterAsNumber:(NSNumber *)number
|
||||
{
|
||||
return @42;
|
||||
}
|
||||
|
||||
// MyProtocol içerisinde metod tanımlamaları
|
||||
- (void)myProtocolMethod
|
||||
{
|
||||
// ifadeler
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
/*
|
||||
* Bir `protocol` herhangi bir sınıf tarafından implement edilen metodları tanımlar
|
||||
* `Protocol`ler sınıfların kendileri değildir. Onlar basitçe diğer objelerin
|
||||
* implementasyon için sorumlu oldukları bir arayüz (interface) tanımlarlar.
|
||||
*/
|
||||
@protocol MyProtocol
|
||||
- (void)myProtocolMethod;
|
||||
@end
|
||||
|
||||
|
||||
|
||||
```
|
||||
## Daha Fazla Okuma
|
||||
|
||||
[Vikipedi Objective-C](http://tr.wikipedia.org/wiki/Objective-C)
|
||||
|
||||
[Objective-C Öğrenme](http://developer.apple.com/library/ios/referencelibrary/GettingStarted/Learning_Objective-C_A_Primer/)
|
||||
|
||||
[Lise Öğrencileri için iOS: Başlangıç](http://www.raywenderlich.com/5600/ios-for-high-school-students-getting-started)
|
@ -67,6 +67,9 @@ $float = 1.234;
|
||||
$float = 1.2e3;
|
||||
$float = 7E-10;
|
||||
|
||||
// Değişken Silmek
|
||||
unset($int1)
|
||||
|
||||
// Aritmetik
|
||||
$sum = 1 + 1; // 2
|
||||
$difference = 2 - 1; // 1
|
||||
@ -143,6 +146,11 @@ echo $associative['One']; // 1 yazdıracaktır.
|
||||
$array = ['One', 'Two', 'Three'];
|
||||
echo $array[0]; // => "One"
|
||||
|
||||
// Dizinin sonuna bir eleman ekleme
|
||||
$array[] = 'Four';
|
||||
|
||||
// Diziden eleman silme
|
||||
unset($array[3]);
|
||||
|
||||
/********************************
|
||||
* Çıktı
|
||||
@ -183,6 +191,13 @@ $y = 0;
|
||||
echo $x; // => 2
|
||||
echo $z; // => 0
|
||||
|
||||
// Dump'lar değişkenin tipi ve değerini yazdırır
|
||||
var_dump($z); // int(0) yazdırılacaktır
|
||||
|
||||
// Print'ler ise değişkeni okunabilir bir formatta yazdıracaktır.
|
||||
print_r($array); // Çıktı: Array ( [0] => One [1] => Two [2] => Three )
|
||||
|
||||
|
||||
/********************************
|
||||
* Mantık
|
||||
*/
|
||||
@ -478,10 +493,18 @@ class MyClass
|
||||
print 'MyClass';
|
||||
}
|
||||
|
||||
//final anahtar kelimesi bu metodu override edilemez yapacaktır.
|
||||
final function youCannotOverrideMe()
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
Bir sınıfın özelliğini ya da metodunu statik yaptığınız takdirde sınıfın bir
|
||||
objesini oluşturmadan bu elemana erişebilirsiniz. Bir özellik statik tanımlanmış
|
||||
ise obje üzerinden bu elemana erişilemez. (Statik metodlar öyle değildir.)
|
||||
*/
|
||||
|
||||
|
||||
public static function myStaticMethod()
|
||||
{
|
||||
print 'I am static';
|
||||
@ -674,7 +697,7 @@ $cls = new SomeOtherNamespace\MyClass();
|
||||
|
||||
Referans ve topluluk yazıları için [official PHP documentation](http://www.php.net/manual/) adresini ziyaret edin.
|
||||
|
||||
Gncel en yi örnekler için [PHP Usulüne Uygun](http://kulekci.net/php-the-right-way/) adresini ziyaret edin.
|
||||
Güncel en yi örnekler için [PHP Usulüne Uygun](http://kulekci.net/php-the-right-way/) adresini ziyaret edin.
|
||||
|
||||
Eğer bir paket yöneticisi olan dil kullandıysanız, [Composer](http://getcomposer.org/)'a bir göz atın.
|
||||
|
||||
|
502
tr-tr/python-tr.html.markdown
Normal file
502
tr-tr/python-tr.html.markdown
Normal file
@ -0,0 +1,502 @@
|
||||
---
|
||||
language: python
|
||||
filename: learnpython-tr.py
|
||||
contributors:
|
||||
- ["Louie Dinh", "http://ldinh.ca"]
|
||||
translators:
|
||||
- ["Haydar KULEKCI", "http://scanf.info/"]
|
||||
lang: tr-tr
|
||||
---
|
||||
Python Guido Van Rossum tarafından 90'ların başında yaratılmıştır. Şu anda
|
||||
varolanlar arasında en iyi dillerden birisidir. Ben (Louie Dinh) Python
|
||||
dilinin syntax'ının belirginliğine aşığım. O basit olarak çalıştırılabilir
|
||||
pseudocode'dur.
|
||||
|
||||
Geri bildirimlerden son derece mutluluk duyarım! Bana [@louiedinh](http://twitter.com/louiedinh)
|
||||
adresinden ya da louiedinh [at] [google's email service] adresinden ulaşabilirsiniz.
|
||||
|
||||
Çeviri için geri bildirimleri de [@kulekci](http://twitter.com/kulekci)
|
||||
adresine yapabilirsiniz.
|
||||
|
||||
Not: Bu yazıdaki özellikler Python 2.7 için geçerlidir, ama Python 2.x için de
|
||||
uygulanabilir. Python 3 için başka bir zaman tekrar bakınız.
|
||||
|
||||
|
||||
```python
|
||||
# Tek satır yorum hash işareti ile başlar.
|
||||
""" Çoklu satır diziler üç tane çift tırnak
|
||||
arasında yazılır. Ve yorum olarak da
|
||||
kullanılabilir
|
||||
"""
|
||||
|
||||
|
||||
####################################################
|
||||
## 1. İlkel Veri Tipleri ve Operatörler
|
||||
####################################################
|
||||
|
||||
# Sayılar
|
||||
3 #=> 3
|
||||
|
||||
# Matematik beklediğiniz gibi
|
||||
1 + 1 #=> 2
|
||||
8 - 1 #=> 7
|
||||
10 * 2 #=> 20
|
||||
35 / 5 #=> 7
|
||||
|
||||
# Bölünme biraz ilginç. EĞer tam sayılar üzerinde bölünme işlemi yapıyorsanız
|
||||
# sonuç otomatik olarak kırpılır.
|
||||
5 / 2 #=> 2
|
||||
|
||||
# Bölünme işlemini düzenlemek için kayan noktalı sayıları bilmeniz gerekir.
|
||||
2.0 # Bu bir kayan noktalı sayı
|
||||
11.0 / 4.0 #=> 2.75 ahhh...daha iyi
|
||||
|
||||
# İşlem önceliğini parantezler ile sağlayabilirsiniz.
|
||||
(1 + 3) * 2 #=> 8
|
||||
|
||||
# Boolean değerleri bilindiği gibi
|
||||
True
|
||||
False
|
||||
|
||||
# not ile nagatif(mantıksal) değerini alma
|
||||
not True #=> False
|
||||
not False #=> True
|
||||
|
||||
# Eşitlik ==
|
||||
1 == 1 #=> True
|
||||
2 == 1 #=> False
|
||||
|
||||
# Eşitsizlik !=
|
||||
1 != 1 #=> False
|
||||
2 != 1 #=> True
|
||||
|
||||
# Daha fazla karşılaştırma
|
||||
1 < 10 #=> True
|
||||
1 > 10 #=> False
|
||||
2 <= 2 #=> True
|
||||
2 >= 2 #=> True
|
||||
|
||||
# Karşılaştırma zincirleme yapılabilir!
|
||||
1 < 2 < 3 #=> True
|
||||
2 < 3 < 2 #=> False
|
||||
|
||||
# Karakter dizisi " veya ' ile oluşturulabilir
|
||||
"This is a string."
|
||||
'This is also a string.'
|
||||
|
||||
# Karakter dizileri birbirleri ile eklenebilir
|
||||
"Hello " + "world!" #=> "Hello world!"
|
||||
|
||||
# A string can be treated like a list of characters
|
||||
# Bir string'e karakter listesi gibi davranabilirsiniz.
|
||||
"This is a string"[0] #=> 'T'
|
||||
|
||||
# % karakter dizisini(string) formatlamak için kullanılır, bunun gibi:
|
||||
"%s can be %s" % ("strings", "interpolated")
|
||||
|
||||
# String'leri formatlamanın yeni bir yöntem ise format metodudur.
|
||||
# Bu metod tercih edilen yöntemdir.
|
||||
"{0} can be {1}".format("strings", "formatted")
|
||||
# Eğer saymak istemiyorsanız anahtar kelime kullanabilirsiniz.
|
||||
"{name} wants to eat {food}".format(name="Bob", food="lasagna")
|
||||
|
||||
# None bir objedir
|
||||
None #=> None
|
||||
|
||||
# "==" eşitliğini non objesi ile karşılaştırmak için kullanmayın.
|
||||
# Onun yerine "is" kullanın.
|
||||
"etc" is None #=> False
|
||||
None is None #=> True
|
||||
|
||||
# 'is' operatörü obje kimliği için test etmektedir. Bu ilkel değerler
|
||||
# için kullanışlı değildir, ama objeleri karşılaştırmak için kullanışlıdır.
|
||||
|
||||
# None, 0 ve boş string/list'ler False olarak değerlendirilir.
|
||||
# Tüm eşitlikler True döner
|
||||
0 == False #=> True
|
||||
"" == False #=> True
|
||||
|
||||
|
||||
####################################################
|
||||
## 2. Değişkenler ve Kolleksiyonlar
|
||||
####################################################
|
||||
|
||||
# Ekrana yazdırma oldukça kolaydır.
|
||||
print "I'm Python. Nice to meet you!"
|
||||
|
||||
|
||||
# Değişkenlere bir değer atamadan önce tanımlamaya gerek yoktur.
|
||||
some_var = 5 # Değişken isimlerinde gelenek küçük karakter ve alt çizgi
|
||||
# kullanmaktır.
|
||||
some_var #=> 5
|
||||
|
||||
# Daha önceden tanımlanmamış ya da assign edilmemeiş bir değişkene erişmeye
|
||||
# çalıştığınızda bir hata fırlatılacaktır. Hata ayıklama hakkında daha fazla
|
||||
# bilgi için kontrol akışı kısmına göz atınız.
|
||||
some_other_var # isim hatası fırlatılır
|
||||
|
||||
# isterseniz "if"i bir ifade gibi kullanabilirsiniz.
|
||||
"yahoo!" if 3 > 2 else 2 #=> "yahoo!"
|
||||
|
||||
# Listeler
|
||||
li = []
|
||||
# Önceden değerleri tanımlanmış listeler
|
||||
other_li = [4, 5, 6]
|
||||
|
||||
# Bir listenin sonuna birşeyler eklemek
|
||||
li.append(1) #li şu anda [1]
|
||||
li.append(2) #li şu anda [1, 2]
|
||||
li.append(4) #li şu anda [1, 2, 4]
|
||||
li.append(3) #li şu anda [1, 2, 4, 3]
|
||||
# pop ile sondan birşeyler silmek
|
||||
li.pop() #=> 3 and li is now [1, 2, 4]
|
||||
# Tekrar sonuna eklemek
|
||||
li.append(3) # li is now [1, 2, 4, 3] again.
|
||||
|
||||
# Dizi gibi listenin elemanlarına erişmek
|
||||
li[0] #=> 1
|
||||
# Son elemanın değerine ulaşmak
|
||||
li[-1] #=> 3
|
||||
|
||||
# Listede bulunmayan bir index'teki elemana erişirken "IndexError" hatası
|
||||
# fırlatılır
|
||||
li[4] # IndexError fırlatılır
|
||||
|
||||
# slice syntax'ı ile belli aralıktakı değerlere bakabilirsiniz.
|
||||
# (Açık ve kapalı aralıklıdır.)
|
||||
li[1:3] #=> [2, 4]
|
||||
# Başlangıcı ihmal etme
|
||||
li[2:] #=> [4, 3]
|
||||
# Sonu ihmal etme
|
||||
li[:3] #=> [1, 2, 4]
|
||||
|
||||
# "del" ile istenilen bir elemanı listeden silmek
|
||||
del li[2] # li is now [1, 2, 3]
|
||||
|
||||
# Listeleri birbiri ile birleştirebilirsiniz.
|
||||
li + other_li #=> [1, 2, 3, 4, 5, 6] - Not: li ve other_li yanlız bırakılır
|
||||
|
||||
# extend ile listeleri birleştirmek
|
||||
li.extend(other_li) # Now li is [1, 2, 3, 4, 5, 6]
|
||||
|
||||
# bir değerin liste içerisinde varlığını "in" ile kontrol etmek
|
||||
1 in li #=> True
|
||||
|
||||
# "len" ile listenin uzunluğunu bulmak
|
||||
len(li) #=> 6
|
||||
|
||||
# Tüpler listeler gibidir sadece değişmezler(immutable)
|
||||
tup = (1, 2, 3)
|
||||
tup[0] #=> 1
|
||||
tup[0] = 3 # TypeError fırlatılır.
|
||||
|
||||
# Litelerde yapılanların hepsini tüplerde de yapılabilir
|
||||
len(tup) #=> 3
|
||||
tup + (4, 5, 6) #=> (1, 2, 3, 4, 5, 6)
|
||||
tup[:2] #=> (1, 2)
|
||||
2 in tup #=> True
|
||||
|
||||
# Tüplerin(veya listelerin) içerisindeki değerleri değişkenelere
|
||||
# atanabilir
|
||||
a, b, c = (1, 2, 3) # a şu anda 1, b şu anda 2 ve c şu anda 3
|
||||
# Eğer parantez kullanmaz iseniz tüpler varsayılan olarak oluşturulur
|
||||
d, e, f = 4, 5, 6
|
||||
# şimdi iki değeri değiş tokuş etmek çok kolaydır.
|
||||
e, d = d, e # d şimdi 5 ve e şimdi 4
|
||||
|
||||
|
||||
# Sözlükler (Dictionaries) key-value saklanır.
|
||||
empty_dict = {}
|
||||
# Sözlüklere önceden değer atama örneği
|
||||
filled_dict = {"one": 1, "two": 2, "three": 3}
|
||||
|
||||
# Değere ulaşmak için [] kullanılır
|
||||
filled_dict["one"] #=> 1
|
||||
|
||||
# Tüm anahtarlara(key) "keys()" metodu ile ulaşılır
|
||||
filled_dict.keys() #=> ["three", "two", "one"]
|
||||
# Not - Sözlüklerin anahtarlarının sıralı geleceği garanti değildir
|
||||
# Sonuçlarınız değer listesini aldığınızda tamamen eşleşmeyebilir
|
||||
|
||||
# Tüm değerleri almak için "values()" kullanabilirsiniz.
|
||||
filled_dict.values() #=> [3, 2, 1]
|
||||
# Not - Sıralama ile ilgili anahtarlar ile aynı durum geçerlidir.
|
||||
|
||||
# Bir anahtarın sözlükte oluş olmadığını "in" ile kontrol edilebilir
|
||||
"one" in filled_dict #=> True
|
||||
1 in filled_dict #=> False
|
||||
|
||||
# Olmayan bir anahtar çağrıldığında KeyError fırlatılır.
|
||||
filled_dict["four"] # KeyError
|
||||
|
||||
# "get()" metodu KeyError fırlatılmasını önler
|
||||
filled_dict.get("one") #=> 1
|
||||
filled_dict.get("four") #=> None
|
||||
# get() metodu eğer anahtar mevcut değilse varsayılan bir değer atama
|
||||
# imknaı sağlar.
|
||||
filled_dict.get("one", 4) #=> 1
|
||||
filled_dict.get("four", 4) #=> 4
|
||||
|
||||
# "setdefault()" metodu sözlüğe yeni bir key-value eşleşmesi eklemenin
|
||||
# güvenli bir yoludur.
|
||||
filled_dict.setdefault("five", 5) #filled_dict["five"] is set to 5
|
||||
filled_dict.setdefault("five", 6) #filled_dict["five"] is still 5
|
||||
|
||||
|
||||
# Sets store ... well sets
|
||||
empty_set = set()
|
||||
# Bir demek değer ile bir "set" oluşturmak
|
||||
some_set = set([1,2,2,3,4]) # some_set is now set([1, 2, 3, 4])
|
||||
|
||||
# Python 2.7'den beri {}'ler bir "set" tanımlaman için kullanılabilir
|
||||
filled_set = {1, 2, 2, 3, 4} # => {1 2 3 4}
|
||||
|
||||
# Bir set'e daha fazla eleman eklemek
|
||||
filled_set.add(5) # filled_set is now {1, 2, 3, 4, 5}
|
||||
|
||||
# "&" işareti ile iki set'in kesişimlerini alınabilir
|
||||
other_set = {3, 4, 5, 6}
|
||||
filled_set & other_set #=> {3, 4, 5}
|
||||
|
||||
# | işareti ile
|
||||
filled_set | other_set #=> {1, 2, 3, 4, 5, 6}
|
||||
|
||||
# "-" işareti ile iki set'in farkları alınabilir
|
||||
{1,2,3,4} - {2,3,5} #=> {1, 4}
|
||||
|
||||
# "in" ile değerin set içerisinde olup olmadığını kontrol edebilirsiniz
|
||||
2 in filled_set #=> True
|
||||
10 in filled_set #=> False
|
||||
|
||||
|
||||
####################################################
|
||||
## 3. Akış Denetimi
|
||||
####################################################
|
||||
|
||||
# Bir değişken oluşturmak
|
||||
some_var = 5
|
||||
|
||||
# Buradaki bir if ifadesi. Girintiler(Intentation) Python'da önemlidir!
|
||||
# "some_var is smaller than 10" yazdırılır.
|
||||
if some_var > 10:
|
||||
print "some_var is totally bigger than 10."
|
||||
elif some_var < 10: # elif ifadesi isteğe bağlıdır
|
||||
print "some_var is smaller than 10."
|
||||
else: # Bu da isteğe bağlıdır.
|
||||
print "some_var is indeed 10."
|
||||
|
||||
|
||||
"""
|
||||
For döngüleri listeler üzerinde iterasyon yapar
|
||||
Ekrana yazdırılan:
|
||||
dog is a mammal
|
||||
cat is a mammal
|
||||
mouse is a mammal
|
||||
"""
|
||||
for animal in ["dog", "cat", "mouse"]:
|
||||
# Biçimlendirmeleri string'e katmak için % kullanabilirsiniz
|
||||
print "%s is a mammal" % animal
|
||||
|
||||
"""
|
||||
"range(number)" ifadesi sıfırdan verilen sayıya kadar bir sayı listesi döner
|
||||
Ekrana yazdırılan:
|
||||
0
|
||||
1
|
||||
2
|
||||
3
|
||||
"""
|
||||
for i in range(4):
|
||||
print i
|
||||
|
||||
"""
|
||||
While döngüsü koşul sağlanmayana kadar devam eder
|
||||
Ekrana yazdırılan:
|
||||
0
|
||||
1
|
||||
2
|
||||
3
|
||||
"""
|
||||
x = 0
|
||||
while x < 4:
|
||||
print x
|
||||
x += 1 # Shorthand for x = x + 1
|
||||
|
||||
# try/except bloğu ile hatalar ayıklanabilir
|
||||
|
||||
# Python 2.6 ve üstü için çalışacaktır:
|
||||
try:
|
||||
# "raise" bir hata fırlatmak için kullanılabilir
|
||||
raise IndexError("This is an index error")
|
||||
except IndexError as e:
|
||||
pass # Pass is just a no-op. Usually you would do recovery here.
|
||||
|
||||
|
||||
####################################################
|
||||
## 4. Fonksiyonlar
|
||||
####################################################
|
||||
|
||||
|
||||
# Yeni bir fonksiyon oluşturmak için "def" kullanılır
|
||||
def add(x, y):
|
||||
print "x is %s and y is %s" % (x, y)
|
||||
return x + y # Return values with a return statement
|
||||
|
||||
# Fonksiyonu parametre ile çağırmak
|
||||
add(5, 6) #=> prints out "x is 5 and y is 6" and returns 11
|
||||
|
||||
# Diğer bir yol fonksiyonları anahtar argümanları ile çağırmak
|
||||
add(y=6, x=5) # Anahtar argümanlarının sırası farklı da olabilir
|
||||
|
||||
# Değişken sayıda parametresi olan bir fonksiyon tanımlayabilirsiniz
|
||||
def varargs(*args):
|
||||
return args
|
||||
|
||||
varargs(1, 2, 3) #=> (1,2,3)
|
||||
|
||||
# Değişken sayıda anahtar argümanlı parametre alan fonksiyonlar da
|
||||
# tanımlayabilirsiniz.
|
||||
def keyword_args(**kwargs):
|
||||
return kwargs
|
||||
|
||||
# Şu şekilde kullanılacaktır
|
||||
keyword_args(big="foot", loch="ness") #=> {"big": "foot", "loch": "ness"}
|
||||
|
||||
# Eğer isterseniz ikisini aynı anda da yapabilirsiniz
|
||||
def all_the_args(*args, **kwargs):
|
||||
print args
|
||||
print kwargs
|
||||
"""
|
||||
all_the_args(1, 2, a=3, b=4) prints:
|
||||
(1, 2)
|
||||
{"a": 3, "b": 4}
|
||||
"""
|
||||
|
||||
# Fonksiyonu çağırırken, args/kwargs'ın tam tersini de yapabilirsiniz!
|
||||
# Tüpü yaymak için * ve kwargs'ı yaymak için ** kullanın.
|
||||
args = (1, 2, 3, 4)
|
||||
kwargs = {"a": 3, "b": 4}
|
||||
all_the_args(*args) # foo(1, 2, 3, 4) ile eşit
|
||||
all_the_args(**kwargs) # foo(a=3, b=4) ile eşit
|
||||
all_the_args(*args, **kwargs) # foo(1, 2, 3, 4, a=3, b=4) ile eşit
|
||||
|
||||
# Python first-class fonksiyonlara sahiptir
|
||||
def create_adder(x):
|
||||
def adder(y):
|
||||
return x + y
|
||||
return adder
|
||||
|
||||
add_10 = create_adder(10)
|
||||
add_10(3) #=> 13
|
||||
|
||||
# Anonymous fonksiyonlar da vardır
|
||||
(lambda x: x > 2)(3) #=> True
|
||||
|
||||
# Dahili yüksek seviye fonksiyonlar vardır
|
||||
map(add_10, [1,2,3]) #=> [11, 12, 13]
|
||||
filter(lambda x: x > 5, [3, 4, 5, 6, 7]) #=> [6, 7]
|
||||
|
||||
# Map etme(maps) ve filtreleme(filtres) için liste kullanabiliriz.
|
||||
[add_10(i) for i in [1, 2, 3]] #=> [11, 12, 13]
|
||||
[x for x in [3, 4, 5, 6, 7] if x > 5] #=> [6, 7]
|
||||
|
||||
|
||||
####################################################
|
||||
## 5. Sınıflar
|
||||
####################################################
|
||||
|
||||
# We subclass from object to get a class.
|
||||
class Human(object):
|
||||
|
||||
# Bir sınıf özelliği. Bu sınıfın tüm "instance"larına paylaşılmıştır.
|
||||
species = "H. sapiens"
|
||||
|
||||
# Basic initializer
|
||||
def __init__(self, name):
|
||||
# Metoda gelen argümanın değerini sınıfın elemanı olan "name"
|
||||
# değişkenine atama
|
||||
self.name = name
|
||||
|
||||
# Bir instance metodu. Tüm metodlar ilk argüman olarak "self"
|
||||
# parametresini alır
|
||||
def say(self, msg):
|
||||
return "%s: %s" % (self.name, msg)
|
||||
|
||||
# Bir sınıf metodu tüm "instance"lar arasında paylaşılır
|
||||
# İlk argüman olarak sınıfı çağırarak çağrılırlar
|
||||
@classmethod
|
||||
def get_species(cls):
|
||||
return cls.species
|
||||
|
||||
# Bir statik metod bir sınıf ya da instance referansı olmadan çağrılır
|
||||
@staticmethod
|
||||
def grunt():
|
||||
return "*grunt*"
|
||||
|
||||
|
||||
# Bir sınıf örneği oluşturmak
|
||||
i = Human(name="Ian")
|
||||
print i.say("hi") # "Ian: hi" çıktısı verir
|
||||
|
||||
j = Human("Joel")
|
||||
print j.say("hello") # "Joel: hello" çıktısı verir
|
||||
|
||||
# Sınıf metodunu çağıralım
|
||||
i.get_species() #=> "H. sapiens"
|
||||
|
||||
# Paylaşılan sınıf özellik değiştirelim.
|
||||
Human.species = "H. neanderthalensis"
|
||||
i.get_species() #=> "H. neanderthalensis"
|
||||
j.get_species() #=> "H. neanderthalensis"
|
||||
|
||||
# Statik metodu çağırma
|
||||
Human.grunt() #=> "*grunt*"
|
||||
|
||||
|
||||
####################################################
|
||||
## 6. Modüller
|
||||
####################################################
|
||||
|
||||
# Modülleri sayfaya dahil edebilirsiniz
|
||||
import math
|
||||
print math.sqrt(16) #=> 4
|
||||
|
||||
# Modül içerisinden spesifik bir fonksiyonu getirebilirsiniz
|
||||
from math import ceil, floor
|
||||
print ceil(3.7) #=> 4.0
|
||||
print floor(3.7) #=> 3.0
|
||||
|
||||
# Modüldeki tüm fonksiyonları dahil edebilirsiniz
|
||||
# Uyarı: bu önerilmez
|
||||
from math import *
|
||||
|
||||
# Modülün adını kısaltabilirsiniz
|
||||
import math as m
|
||||
math.sqrt(16) == m.sqrt(16) #=> True
|
||||
|
||||
# Python modülleri sıradan python dosyalarıdır. Kendinize bir modül
|
||||
# yazabilirsiniz, ve dahil edebilirsiniz. Modülün adı ile dosya adı
|
||||
# aynı olmalıdır.
|
||||
|
||||
# Modüllerde tanımlanmış fonksiyon ve metodları öğrenebilirsiniz.
|
||||
import math
|
||||
dir(math)
|
||||
|
||||
|
||||
|
||||
```
|
||||
|
||||
## Daha fazlası için hazır mısınız?
|
||||
|
||||
### Ücretsiz Dökümanlar
|
||||
|
||||
* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/)
|
||||
* [Dive Into Python](http://www.diveintopython.net/)
|
||||
* [The Official Docs](http://docs.python.org/2.6/)
|
||||
* [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/)
|
||||
* [Python Module of the Week](http://pymotw.com/2/)
|
||||
|
||||
### Dead Tree
|
||||
|
||||
* [Programming Python](http://www.amazon.com/gp/product/0596158106/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596158106&linkCode=as2&tag=homebits04-20)
|
||||
* [Dive Into Python](http://www.amazon.com/gp/product/1441413022/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1441413022&linkCode=as2&tag=homebits04-20)
|
||||
* [Python Essential Reference](http://www.amazon.com/gp/product/0672329786/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0672329786&linkCode=as2&tag=homebits04-20)
|
393
vi-vn/git-vi.html.markdown
Normal file
393
vi-vn/git-vi.html.markdown
Normal file
@ -0,0 +1,393 @@
|
||||
---
|
||||
category: tool
|
||||
tool: git
|
||||
contributors:
|
||||
- ["Jake Prather", "http://github.com/JakeHP"]
|
||||
filename: LearnGit-vi.txt
|
||||
lang: vi-vn
|
||||
---
|
||||
|
||||
Git là một hệ quản lý mã nguồn và phiên bản phân tán (distributed version control and source code management system).
|
||||
|
||||
Nó làm được điều này là do một loạt các snapshot từ đề án của bạn, and nó hoạt động
|
||||
với các snapshot đó để cung cấp cho bạn với chức năng đến phiên bản và
|
||||
quản lý mã nguồn của bạn.
|
||||
|
||||
## Khái Niệm Versioning
|
||||
|
||||
### Version Control là gì?
|
||||
|
||||
Version Control là một hệ thống ghi lại những thay đổi ở một tập tin, hay một nhóm các tập tin, theo thời gian.
|
||||
|
||||
### Centralized Versioning VS Distributed Versioning
|
||||
|
||||
* Quản lý phiên bản tập trung (Centralized Versioning) tập trung vào việc đồng bộ hóa, theo dõi, và lưu trữ tập tin.
|
||||
* Quản lý phiên bản phân tán (Distributed Versioning) tập trung vào việc chia sẻ các thay đổi. Mỗi sự thay đổi có một mã định dạng (id) duy nhất.
|
||||
* Các hệ phân tán không có cấu trúc định sẵn. Bạn có thể thay đổi một kiểu SVN, hệ phân tán, với git.
|
||||
|
||||
[Thông tin thêm](http://git-scm.com/book/en/Getting-Started-About-Version-Control)
|
||||
|
||||
### Tại Sao Dùng Git?
|
||||
|
||||
* Có thể hoạt động offline.
|
||||
* Cộng tác với nhau rất dễ dàng!
|
||||
* Phân nhánh dễ dàng!
|
||||
* Trộn (Merging)
|
||||
* Git nhanh.
|
||||
* Git linh hoạt.
|
||||
|
||||
## Kiến Trúc Git
|
||||
|
||||
|
||||
### Repository
|
||||
|
||||
Một nhóm các tập tin, thư mục, các ghi chép trong quá khứ, commit, và heads. Tưởng tượng nó như là một cấu trúc dữ liệu mã nguồn,
|
||||
với thuộc tính mà một "nhân tố" mã nguồn cho bạn quyền truy cập đến lịch sử sửa đổi, và một số thứ khác.
|
||||
|
||||
Một git repository bao gồm thư mục .git & tree đang làm việc.
|
||||
|
||||
### Thư mục .git (thành phần của một repository)
|
||||
|
||||
Thư mục .git chứa tất cả các cấu hình, log, nhánh, HEAD, và hơn nữa.
|
||||
[Danh Sách Chi Tiết.](http://gitready.com/advanced/2009/03/23/whats-inside-your-git-directory.html)
|
||||
|
||||
### Tree Đang Làm (thành phần của một repository)
|
||||
|
||||
Đây cơ bản là các thư mục và tập tin trong repository của bạn. Nó thường được tham chiếu
|
||||
thư mục đang làm việc của bạn
|
||||
|
||||
### Chỉ mục (thành phần của một thư mục .git)
|
||||
|
||||
Chỉ mục của là một staging area trong git. Nó đơn giản là một lớp riêng biệt với tree đang làm việc của bạn
|
||||
từ Git repository. Điều này cho nhà phát triền nhiều lựa chọn hơn trong việc xem xét những gì được gửi đến Git
|
||||
repository.
|
||||
|
||||
### Commit
|
||||
|
||||
Một git commit là một snapshot của một nhóm các thay đổi, hoặc các thao tác Working Tree của bạn.
|
||||
Ví dụ, nếu bạn thêm 5 tập tin, và xóa 2 tập tin khác, những thay đổi này sẽ được chứa trong
|
||||
một commit (hoặc snapshot). Commit này có thể được đẩy đến các repo khác, hoặc không!
|
||||
|
||||
### Nhánh
|
||||
|
||||
Nhánh thực chất là một con trỏ đến commit mới nhất mà bạn vừa thực hiện. Khi bạn commit,
|
||||
con trỏ này sẽ cập nhật tự động và trỏ đến commit mới nhất.
|
||||
|
||||
### HEAD và head (thành phần của thư mục .git)
|
||||
|
||||
HEAD là một con trỏ đến nhánh hiện tại. Một repo chỉ có một HEAD *đang hoạt động*.
|
||||
head là một con trỏ đến bất kỳ commit nào. Một repo có thể có nhiều head.
|
||||
|
||||
### Các Tài Nguyên Mang Tính Khái Niệm
|
||||
|
||||
* [Git For Computer Scientists](http://eagain.net/articles/git-for-computer-scientists/)
|
||||
* [Git For Designers](http://hoth.entp.com/output/git_for_designers.html)
|
||||
|
||||
|
||||
## Các Lệnh
|
||||
|
||||
|
||||
### init
|
||||
|
||||
Tạo một repo Git rỗng. Các cài đặt, thông tin lưu trữ... của Git
|
||||
được lưu ở một thư mục tên là ".git".
|
||||
|
||||
```bash
|
||||
$ git init
|
||||
```
|
||||
|
||||
### config
|
||||
|
||||
Để chỉnh tùy chọn. Bất kể là cho repo, hay cho hệ thống, hay điều chỉnh
|
||||
toàn cục (global)
|
||||
|
||||
|
||||
|
||||
```bash
|
||||
# In Ra & Và Gán Một Số Biến Tùy Chỉnh Cơ Bản (Toàn cục - Global)
|
||||
$ git config --global user.email
|
||||
$ git config --global user.name
|
||||
|
||||
$ git config --global user.email "MyEmail@Zoho.com"
|
||||
$ git config --global user.name "My Name"
|
||||
```
|
||||
|
||||
[Tìm hiểu thêm về git config.](http://git-scm.com/docs/git-config)
|
||||
|
||||
### help
|
||||
|
||||
Để cho bạn lối truy cập nhanh đến một chỉ dẫn cực kỳ chi tiết của từng lệnh. Hoặc chỉ để
|
||||
nhắc bạn một số cú pháp.
|
||||
|
||||
```bash
|
||||
# Xem nhanh các lệnh có sẵn
|
||||
$ git help
|
||||
|
||||
# Xem tất các các lệnh
|
||||
$ git help -a
|
||||
|
||||
# Lệnh help riêng biệt - tài liệu người dùng
|
||||
# git help <command_here>
|
||||
$ git help add
|
||||
$ git help commit
|
||||
$ git help init
|
||||
```
|
||||
|
||||
### status
|
||||
|
||||
Để hiển thị sự khác nhau giữa tập tin index (cơ bản là repo đang làm việc) và HEAD commit
|
||||
hiện tại.
|
||||
|
||||
|
||||
```bash
|
||||
# Sẽ hiển thị nhánh, các tập tin chưa track (chưa commit), các thay đổi và những khác biệt khác
|
||||
$ git status
|
||||
|
||||
# Để xem các "tid bits" về git status
|
||||
$ git help status
|
||||
```
|
||||
|
||||
### add
|
||||
|
||||
Để thêm các tập vào tree/thư mục/repo hiện tại. Nếu bạn không `git add` các tập tin mới đến
|
||||
tree/thư mục hiện tại, chúng sẽ không được kèm theo trong các commit!
|
||||
|
||||
```bash
|
||||
# thêm một file vào thư mục hiện tại
|
||||
$ git add HelloWorld.java
|
||||
|
||||
# thêm một file vào một thư mục khác
|
||||
$ git add /path/to/file/HelloWorld.c
|
||||
|
||||
# Hỗ trợ Regular Expression!
|
||||
$ git add ./*.java
|
||||
```
|
||||
|
||||
### branch
|
||||
|
||||
Quản lý nhánh. Bạn có thể xem, sửa, tạo, xóa các nhánh bằng cách dùng lệnh này.
|
||||
|
||||
```bash
|
||||
# liệt kê các nhanh đang có và ở remote
|
||||
$ git branch -a
|
||||
|
||||
# tạo nhánh mới
|
||||
$ git branch myNewBranch
|
||||
|
||||
# xóa một nhánh
|
||||
$ git branch -d myBranch
|
||||
|
||||
# đặt tên lại một nhánh
|
||||
# git branch -m <oldname> <newname>
|
||||
$ git branch -m myBranchName myNewBranchName
|
||||
|
||||
# chỉnh sủa diễn giải của một nhánh
|
||||
$ git branch myBranchName --edit-description
|
||||
```
|
||||
|
||||
### checkout
|
||||
|
||||
Cập nhật tất cả các file torng tree hiện tại để cho trùng khớp với phiên bản của index, hoặc tree cụ thể.
|
||||
|
||||
```bash
|
||||
# Checkout (chuyển) một repo - mặc định là nhánh master
|
||||
$ git checkout
|
||||
# Checkout một nhánh cụ thể
|
||||
$ git checkout branchName
|
||||
# Tạo một nhánh mới và chuyển đến nó, tương tự: "git branch <name>; git checkout <name>"
|
||||
$ git checkout -b newBranch
|
||||
```
|
||||
|
||||
### clone
|
||||
|
||||
Nhân bản, hoặc sao chép, một repo hiện có thành một thư mục mới. Nó cũng thêm
|
||||
các nhánh có remote-tracking cho mỗi nhánh trong một repo được nhân bản, mà
|
||||
cho phép bạn push đến một nhánh remote.
|
||||
|
||||
```bash
|
||||
# Nhân bản learnxinyminutes-docs
|
||||
$ git clone https://github.com/adambard/learnxinyminutes-docs.git
|
||||
```
|
||||
|
||||
### commit
|
||||
|
||||
Lưu trữ nội dung hiện tại của index trong một "commit" mới. Điều này cho phép tạo ra thay đổi và một lời nhắn (ghi chú) tạo ra bởi người dùng.
|
||||
|
||||
```bash
|
||||
# commit với một ghi chú
|
||||
$ git commit -m "Added multiplyNumbers() function to HelloWorld.c"
|
||||
```
|
||||
|
||||
### diff
|
||||
|
||||
Hiển thị sự khác biệt giữa một file trong thư mục hiện tại, index và commits.
|
||||
|
||||
```bash
|
||||
# Hiển thị sự khác biệt giữa thư mục hiện tại và index
|
||||
$ git diff
|
||||
|
||||
# Hiển thị khác biệt giữa index và commit mới nhất.
|
||||
$ git diff --cached
|
||||
|
||||
# Hiển thị khác biệt giữa thư mục đang làm việc và commit mới nhất
|
||||
$ git diff HEAD
|
||||
```
|
||||
|
||||
### grep
|
||||
|
||||
Cho phép bạn tìm kiếm nhanh một repo.
|
||||
|
||||
Các tinh chỉnh tùy chọn:
|
||||
|
||||
```bash
|
||||
# Cảm ơn Travis Jeffery vì những lệnh này
|
||||
# Đặt số của dòng được hiển thị trong kết quả tìm kiếm grep
|
||||
$ git config --global grep.lineNumber true
|
||||
|
||||
# Làm cho kết quả tìm kiếm dễ đọc hơn, bao gồm cả gom nhóm
|
||||
$ git config --global alias.g "grep --break --heading --line-number"
|
||||
```
|
||||
|
||||
```bash
|
||||
# Tìm "variableName" trong tất cả các file Java
|
||||
$ git grep 'variableName' -- '*.java'
|
||||
|
||||
# Tìm một dòng mà có chứa "arrayListName" và, "add" hoặc "remove"
|
||||
$ git grep -e 'arrayListName' --and \( -e add -e remove \)
|
||||
```
|
||||
|
||||
Google để xem thêm các ví dụ
|
||||
[Git Grep Ninja](http://travisjeffery.com/b/2012/02/search-a-git-repo-like-a-ninja)
|
||||
|
||||
### log
|
||||
|
||||
Hiển thị các commit đến repo.
|
||||
|
||||
```bash
|
||||
# Hiện tất cả các commit
|
||||
$ git log
|
||||
|
||||
# Hiện X commit
|
||||
$ git log -n 10
|
||||
|
||||
# Chỉ hiện các commit đã merge merge commits
|
||||
$ git log --merges
|
||||
```
|
||||
|
||||
### merge
|
||||
|
||||
"Trộn" các thay đổi từ commit bên ngoài vào trong nhánh hiện tại.
|
||||
|
||||
```bash
|
||||
# Merge nhánh cụ thể vào nhánh hiện tại.
|
||||
$ git merge branchName
|
||||
|
||||
# Luôn khởi tạo một merge commit khi trộn (merge)
|
||||
$ git merge --no-ff branchName
|
||||
```
|
||||
|
||||
### mv
|
||||
|
||||
Đặt lại tên hoặc di chuyển một file
|
||||
|
||||
```bash
|
||||
# Đặt lại tên một file
|
||||
$ git mv HelloWorld.c HelloNewWorld.c
|
||||
|
||||
# Di chuyển một file
|
||||
$ git mv HelloWorld.c ./new/path/HelloWorld.c
|
||||
|
||||
# Buộc đặt lại tên hoặc di chuyển
|
||||
# "existingFile" đã tồn tại trong thự mục, sẽ bị ghi đè
|
||||
$ git mv -f myFile existingFile
|
||||
```
|
||||
|
||||
### pull
|
||||
|
||||
Kéo (tải) về từ một repo và merge nó vào nhánh khác.
|
||||
|
||||
```bash
|
||||
# Cập nhật repo cục bộ của bạn, bằng cách merge các thay đổi mới
|
||||
# từ remote "origin" và nhánh "master".
|
||||
# git pull <remote> <branch>
|
||||
# git pull => hoàn toàn mặc định như => git pull origin master
|
||||
$ git pull origin master
|
||||
|
||||
# Merge các thay đổi từ nhánh remote và rebase
|
||||
# các commit nhánh lên trên thư mục cục bộ, như: "git pull <remote> <branch>, git rebase <branch>"
|
||||
$ git pull origin master --rebase
|
||||
```
|
||||
|
||||
### push
|
||||
|
||||
Đẩy và trộn (mege) các tay đổi từ một nhánh đế một remote & nhánh.
|
||||
|
||||
```bash
|
||||
# Push và merge các thay đổi từ repo cục bộ đến một
|
||||
# remote tên là "origin" và nhánh "master".
|
||||
# git push <remote> <branch>
|
||||
# git push => hoàn toàn defaults to => git push origin master
|
||||
$ git push origin master
|
||||
```
|
||||
|
||||
### rebase (thận trọng)
|
||||
|
||||
Lấy tất cả các thay đổi mà đã được commit trên một nhánh, và replay (?) chúng trên một nhánh khác.
|
||||
*Không rebase các commit mà bạn đã push đến một repo công khai*.
|
||||
|
||||
```bash
|
||||
# Rebase experimentBranch lên master
|
||||
# git rebase <basebranch> <topicbranch>
|
||||
$ git rebase master experimentBranch
|
||||
```
|
||||
|
||||
[Đọc Thêm.](http://git-scm.com/book/en/Git-Branching-Rebasing)
|
||||
|
||||
### reset (thận trọng)
|
||||
|
||||
Thiết lập lạo HEAD hiện tại đến một trạng thái cụ thể. Điều này cho phép bạn làm lại các merges,
|
||||
pulls, commits, thêm, and hơn nữa. Nó là một lệnh hay nhưng cũng nguy hiểm nếu bạn không
|
||||
biết mình đang làm gì.
|
||||
|
||||
```bash
|
||||
# Thiết lập lại staging area, để trùng với commit mới nhất (để thư mục không thay đổi)
|
||||
$ git reset
|
||||
|
||||
# Thiết lập lại staging area, để trùng với commit mới nhất, và ghi đè lên thư mục hiện tại
|
||||
$ git reset --hard
|
||||
|
||||
# Di chuyển nhánh hiện tại đến một commit cụ thể (để thư mục không thay đổi)
|
||||
# tất cả thay đổi vẫn duy trì trong thư mục.
|
||||
$ git reset 31f2bb1
|
||||
|
||||
# Di chuyển nhánh hiện tại lùi về một commit cụ thể
|
||||
# và làm cho thư mục hiện tại trùng (xóa các thay đổi chưa được commit và tất cả các commit
|
||||
# sau một commit cụ thể).
|
||||
$ git reset --hard 31f2bb1
|
||||
```
|
||||
|
||||
### rm
|
||||
|
||||
Ngược lại với git add, git rm xóa file từ tree đang làm việc.
|
||||
|
||||
```bash
|
||||
# xóa HelloWorld.c
|
||||
$ git rm HelloWorld.c
|
||||
|
||||
# Xóa file từ thư mục khác
|
||||
$ git rm /pather/to/the/file/HelloWorld.c
|
||||
```
|
||||
|
||||
## Thông tin thêm
|
||||
|
||||
* [tryGit - A fun interactive way to learn Git.](http://try.github.io/levels/1/challenges/1)
|
||||
|
||||
* [git-scm - Video Tutorials](http://git-scm.com/videos)
|
||||
|
||||
* [git-scm - Documentation](http://git-scm.com/docs)
|
||||
|
||||
* [Atlassian Git - Tutorials & Workflows](https://www.atlassian.com/git/)
|
||||
|
||||
* [SalesForce Cheat Sheet](https://na1.salesforce.com/help/doc/en/salesforce_git_developer_cheatsheet.pdf)
|
||||
|
||||
* [GitGuys](http://www.gitguys.com/)
|
318
vi-vn/objective-c-vi.html.markdown
Normal file
318
vi-vn/objective-c-vi.html.markdown
Normal file
@ -0,0 +1,318 @@
|
||||
---
|
||||
|
||||
language: Objective-C
|
||||
contributors:
|
||||
- ["Eugene Yagrushkin", "www.about.me/yagrushkin"]
|
||||
- ["Yannick Loriot", "https://github.com/YannickL"]
|
||||
lang: vi-vn
|
||||
filename: LearnObjectiveC-vi.m
|
||||
|
||||
---
|
||||
|
||||
Objective-C là ngôn ngữ lập trình chính được sử dụng bởi Apple cho các hệ điều hành OS X, iOS và các framework tương ứng của họ, Cocoa và Cocoa Touch.
|
||||
Nó là một ngôn ngữ lập trình mục đích tổng quát, hướng đối tượng có bổ sung thêm kiểu truyền thông điệp giống Smalltalk vào ngôn ngữ lập trình C.
|
||||
|
||||
```cpp
|
||||
// Chú thích dòng đơn bắt đầu với //
|
||||
|
||||
/*
|
||||
Chú thích đa dòng trông như thế này.
|
||||
*/
|
||||
|
||||
// Nhập các headers của framework Foundation với cú pháp #import
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "MyClass.h"
|
||||
|
||||
// Đầu vào chương trình của bạn là một hàm gọi là
|
||||
// main với một kiểu trả về kiểu integer.
|
||||
int main (int argc, const char * argv[])
|
||||
{
|
||||
// Tạo một autorelease pool để quản lý bộ nhớ vào chương trình
|
||||
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
// Sử dụng hàm NSLog() để in ra các dòng lệnh vào console
|
||||
NSLog(@"Hello World!"); // Print the string "Hello World!"
|
||||
|
||||
///////////////////////////////////////
|
||||
// Kiểu & Biến (Types & Variables)
|
||||
///////////////////////////////////////
|
||||
|
||||
// Khai báo số nguyên
|
||||
int myPrimitive1 = 1;
|
||||
long myPrimitive2 = 234554664565;
|
||||
|
||||
// Khai báo đối tượng
|
||||
// Đặt dấu nháy * vào trước tên biến cho khai báo đối tượng strong
|
||||
MyClass *myObject1 = nil; // Strong
|
||||
id myObject2 = nil; // Weak
|
||||
// %@ là một đối tượng
|
||||
// 'miêu tả' ('desciption') là thông lệ để trình bày giá trị của các Đối tượng
|
||||
NSLog(@"%@ và %@", myObject1, [myObject2 description]); // In ra "(null) và (null)"
|
||||
|
||||
// Chuỗi
|
||||
NSString *worldString = @"World";
|
||||
NSLog(@"Hello %@!", worldString); // In ra "Hello World!"
|
||||
|
||||
// Ký tự literals
|
||||
NSNumber *theLetterZNumber = @'Z';
|
||||
char theLetterZ = [theLetterZNumber charValue];
|
||||
NSLog(@"%c", theLetterZ);
|
||||
|
||||
// Số nguyên literals
|
||||
NSNumber *fortyTwoNumber = @42;
|
||||
int fortyTwo = [fortyTwoNumber intValue];
|
||||
NSLog(@"%i", fortyTwo);
|
||||
|
||||
NSNumber *fortyTwoUnsignedNumber = @42U;
|
||||
unsigned int fortyTwoUnsigned = [fortyTwoUnsignedNumber unsignedIntValue];
|
||||
NSLog(@"%u", fortyTwoUnsigned);
|
||||
|
||||
NSNumber *fortyTwoShortNumber = [NSNumber numberWithShort:42];
|
||||
short fortyTwoShort = [fortyTwoShortNumber shortValue];
|
||||
NSLog(@"%hi", fortyTwoShort);
|
||||
|
||||
NSNumber *fortyTwoLongNumber = @42L;
|
||||
long fortyTwoLong = [fortyTwoLongNumber longValue];
|
||||
NSLog(@"%li", fortyTwoLong);
|
||||
|
||||
// Dấu phẩy động (floating point) literals
|
||||
NSNumber *piFloatNumber = @3.141592654F;
|
||||
float piFloat = [piFloatNumber floatValue];
|
||||
NSLog(@"%f", piFloat);
|
||||
|
||||
NSNumber *piDoubleNumber = @3.1415926535;
|
||||
double piDouble = [piDoubleNumber doubleValue];
|
||||
NSLog(@"%f", piDouble);
|
||||
|
||||
// BOOL literals
|
||||
NSNumber *yesNumber = @YES;
|
||||
NSNumber *noNumber = @NO;
|
||||
|
||||
// Đối tượng Mảng
|
||||
NSArray *anArray = @[@1, @2, @3, @4];
|
||||
NSNumber *thirdNumber = anArray[2];
|
||||
NSLog(@"Third number = %@", thirdNumber); // In ra "Third number = 3"
|
||||
|
||||
// Đối tượng Từ điển
|
||||
NSDictionary *aDictionary = @{ @"key1" : @"value1", @"key2" : @"value2" };
|
||||
NSObject *valueObject = aDictionary[@"A Key"];
|
||||
NSLog(@"Đối tượng = %@", valueObject); // In ra "Object = (null)"
|
||||
|
||||
///////////////////////////////////////
|
||||
// Toán Tử (Operators)
|
||||
///////////////////////////////////////
|
||||
|
||||
// Các toán tử cũng hoạt động giống như ngôn ngữ C
|
||||
// Ví dụ:
|
||||
2 + 5; // => 7
|
||||
4.2f + 5.1f; // => 9.3f
|
||||
3 == 2; // => 0 (NO)
|
||||
3 != 2; // => 1 (YES)
|
||||
1 && 1; // => 1 (Logical and)
|
||||
0 || 1; // => 1 (Logical or)
|
||||
~0x0F; // => 0xF0 (bitwise negation)
|
||||
0x0F & 0xF0; // => 0x00 (bitwise AND)
|
||||
0x01 << 1; // => 0x02 (bitwise dịch trái (bởi 1))
|
||||
|
||||
/////////////////////////////////////////////
|
||||
// Cấu Trúc Điều Khiển (Controls Structures)
|
||||
/////////////////////////////////////////////
|
||||
|
||||
// Câu lệnh If-Else
|
||||
if (NO)
|
||||
{
|
||||
NSLog(@"I am never run");
|
||||
} else if (0)
|
||||
{
|
||||
NSLog(@"I am also never run");
|
||||
} else
|
||||
{
|
||||
NSLog(@"I print");
|
||||
}
|
||||
|
||||
// Câu lệnh Switch
|
||||
switch (2)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
NSLog(@"I am never run");
|
||||
} break;
|
||||
case 1:
|
||||
{
|
||||
NSLog(@"I am also never run");
|
||||
} break;
|
||||
default:
|
||||
{
|
||||
NSLog(@"I print");
|
||||
} break;
|
||||
}
|
||||
|
||||
// Câu lệnh vòng lặp While
|
||||
int ii = 0;
|
||||
while (ii < 4)
|
||||
{
|
||||
NSLog(@"%d,", ii++); // ii++ tăng dần, sau khi sử dụng giá trị của nó.
|
||||
} // => in ra "0,"
|
||||
// "1,"
|
||||
// "2,"
|
||||
// "3,"
|
||||
|
||||
// Câu lệnh vòng lặp For
|
||||
int jj;
|
||||
for (jj=0; jj < 4; jj++)
|
||||
{
|
||||
NSLog(@"%d,", jj);
|
||||
} // => in ra "0,"
|
||||
// "1,"
|
||||
// "2,"
|
||||
// "3,"
|
||||
|
||||
// Câu lệnh Foreach
|
||||
NSArray *values = @[@0, @1, @2, @3];
|
||||
for (NSNumber *value in values)
|
||||
{
|
||||
NSLog(@"%@,", value);
|
||||
} // => in ra "0,"
|
||||
// "1,"
|
||||
// "2,"
|
||||
// "3,"
|
||||
|
||||
// Câu lệnh Try-Catch-Finally
|
||||
@try
|
||||
{
|
||||
// Your statements here
|
||||
@throw [NSException exceptionWithName:@"FileNotFoundException"
|
||||
reason:@"Không Tìm Thấy Tập Tin trên Hệ Thống" userInfo:nil];
|
||||
} @catch (NSException * e)
|
||||
{
|
||||
NSLog(@"Exception: %@", e);
|
||||
} @finally
|
||||
{
|
||||
NSLog(@"Finally");
|
||||
} // => in ra "Exception: Không Tìm Thấy Tập Tin trên Hệ Thống"
|
||||
// "Finally"
|
||||
|
||||
///////////////////////////////////////
|
||||
// Đối Tượng (Objects)
|
||||
///////////////////////////////////////
|
||||
|
||||
// Tạo một thực thể đối tượng bằng cách phân vùng nhớ và khởi tạo đối tượng đó.
|
||||
// Một đối tượng sẽ không thật sự hoạt động cho đến khi cả 2 bước alloc] init] được hoàn thành
|
||||
MyClass *myObject = [[MyClass alloc] init];
|
||||
|
||||
// Mô hình lập trình hướng đối tượng của Objective-C dựa trên việc truyền thông điệp (message)
|
||||
// và các thực thể đối tượng với nhau.
|
||||
// Trong Objective-C một đối tượng không đơn thuần gọi phương thức; nó truyền thông điệp.
|
||||
[myObject instanceMethodWithParameter:@"Steve Jobs"];
|
||||
|
||||
// Dọn dẹp vùng nhớ mà bạn đã dùng ở chương trình
|
||||
[pool drain];
|
||||
|
||||
// Kết thúc chương trình
|
||||
return 0;
|
||||
}
|
||||
|
||||
///////////////////////////////////////
|
||||
// Lớp và Hàm (Classes & Functions)
|
||||
///////////////////////////////////////
|
||||
|
||||
// Khai báo lớp của bạn ở một tập tin header (MyClass.h):
|
||||
// Cú pháp Khai Báo Lớp:
|
||||
// @interface ClassName : ParentClassName <ImplementedProtocols>
|
||||
// {
|
||||
// Khai báo biến thành viên;
|
||||
// }
|
||||
// -/+ (type) Khai báo method;
|
||||
// @end
|
||||
@interface MyClass : NSObject <MyProtocol>
|
||||
{
|
||||
int count;
|
||||
id data;
|
||||
NSString *name;
|
||||
}
|
||||
// Ký hiệu (notation) tiện ích để tự động khởi tạo public getter và setter
|
||||
@property int count;
|
||||
@property (copy) NSString *name; // Sao chép đối tượng trong quá trình gán.
|
||||
@property (readonly) id data; // Chỉ khai báo phương thức getter.
|
||||
|
||||
// Phương thức
|
||||
+/- (return type)methodSignature:(Parameter Type *)parameterName;
|
||||
|
||||
// dấu '+' cho phương thức lớp
|
||||
+ (NSString *)classMethod;
|
||||
|
||||
// dấu '-' cho phương thức thực thể
|
||||
- (NSString *)instanceMethodWithParameter:(NSString *)string;
|
||||
- (NSNumber *)methodAParameterAsString:(NSString*)string andAParameterAsNumber:(NSNumber *)number;
|
||||
|
||||
@end
|
||||
|
||||
// Thực thi các phương thức trong một tập tin thực thi (MyClass.m):
|
||||
|
||||
@implementation MyClass
|
||||
|
||||
// Gọi khi đối tượng được release
|
||||
- (void)dealloc
|
||||
{
|
||||
}
|
||||
|
||||
// Phương thức khởi tạo (Constructors) là một cách để tạo các lớp
|
||||
// Đây là phương thức khởi tạo mặc định được gọi khi đối tượng được khởi tạo
|
||||
- (id)init
|
||||
{
|
||||
if ((self = [super init]))
|
||||
{
|
||||
self.count = 1;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (NSString *)classMethod
|
||||
{
|
||||
return [[self alloc] init];
|
||||
}
|
||||
|
||||
- (NSString *)instanceMethodWithParameter:(NSString *)string
|
||||
{
|
||||
return @"New string";
|
||||
}
|
||||
|
||||
- (NSNumber *)methodAParameterAsString:(NSString*)string andAParameterAsNumber:(NSNumber *)number
|
||||
{
|
||||
return @42;
|
||||
}
|
||||
|
||||
// Các phương thức được khai báo vào MyProtocol
|
||||
- (void)myProtocolMethod
|
||||
{
|
||||
// câu lệnh
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
/*
|
||||
* Một protocol khai báo các phương thức mà có thể thực thi bởi bất kỳ lớp nào.
|
||||
* Các protocol chính chúng không phải là các lớp. Chúng chỉ đơn giản là định ra giao diện (interface)
|
||||
* mà các đối tượng khác có trách nhiệm sẽ thực thi.
|
||||
*/
|
||||
@protocol MyProtocol
|
||||
- (void)myProtocolMethod;
|
||||
@end
|
||||
|
||||
|
||||
|
||||
```
|
||||
## Xem Thêm
|
||||
|
||||
+ [Wikipedia Objective-C](http://en.wikipedia.org/wiki/Objective-C)
|
||||
|
||||
+ Apple Docs':
|
||||
+ [Learning Objective-C](http://developer.apple.com/library/ios/referencelibrary/GettingStarted/Learning_Objective-C_A_Primer/)
|
||||
|
||||
+ [Programming With Objective-C](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/Introduction/Introduction.html)
|
||||
|
||||
+ [Object-Oriented Programming with Objective-C](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/OOP_ObjC/Introduction/Introduction.html#//apple_ref/doc/uid/TP40005149)
|
||||
|
||||
+ [Coding Guidelines for Cocoa](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CodingGuidelines/CodingGuidelines.html)
|
||||
|
||||
+ [iOS For High School Students: Getting Started](http://www.raywenderlich.com/5600/ios-for-high-school-students-getting-started)
|
148
zh-cn/bash-cn.html.markdown
Normal file
148
zh-cn/bash-cn.html.markdown
Normal file
@ -0,0 +1,148 @@
|
||||
---
|
||||
category: tool
|
||||
tool: bash
|
||||
contributors:
|
||||
- ["Max Yankov", "https://github.com/golergka"]
|
||||
- ["Darren Lin", "https://github.com/CogBear"]
|
||||
- ["Alexandre Medeiros", "http://alemedeiros.sdf.org"]
|
||||
translators:
|
||||
- ["Chunyang Xu", "https://github.com/XuChunyang"]
|
||||
filename: LearnBash-cn.sh
|
||||
lang: zh-cn
|
||||
---
|
||||
|
||||
Bash 是一个为 GNU 计划编写的 Unix shell,是 Linux 和 Mac OS X 下的默认 shell。
|
||||
以下大多数例子可以作为脚本的一部分运行也可直接在 shell 下交互执行。
|
||||
|
||||
[更多信息](http://www.gnu.org/software/bash/manual/bashref.html)
|
||||
|
||||
```bash
|
||||
#!/bin/sh
|
||||
# 脚本的第一行叫 shebang,用来告知系统如何执行该脚本:
|
||||
# 参见: http://en.wikipedia.org/wiki/Shebang_(Unix)
|
||||
# 如你所见,注释以 # 开头,shebang 也是注释。
|
||||
|
||||
# 显示 “Hello world!”
|
||||
echo Hello, world!
|
||||
|
||||
# 每一句指令以换行或分号隔开:
|
||||
echo 'This is the first line'; echo 'This is the second line'
|
||||
|
||||
# 声明一个变量:
|
||||
VARIABLE="Some string"
|
||||
|
||||
# 下面是错误的做法:
|
||||
VARIABLE = "Some string"
|
||||
# Bash 会把 VARIABLE 当做一个指令,由于找不到该指令,因此这里会报错。
|
||||
|
||||
|
||||
# 使用变量:
|
||||
echo $VARIABLE
|
||||
echo "$VARIABLE"
|
||||
echo '$VARIABLE'
|
||||
# 当你分配 (assign) 、导出 (export),或者以其他方式使用变量时,变量名前不加 $。
|
||||
# 如果要使用变量的值, 则要加 $。
|
||||
# 注意: ' (单引号) 不会展开变量(即会屏蔽掉变量)。
|
||||
|
||||
|
||||
# 在变量内部进行字符串代换
|
||||
echo ${VARIABLE/Some/A}
|
||||
# 会把 VARIABLE 中首次出现的 "some" 替换成 “A”。
|
||||
|
||||
# 内置变量:
|
||||
# 下面的内置变量很有用
|
||||
echo "Last program return value: $?"
|
||||
echo "Script's PID: $$"
|
||||
echo "Number of arguments: $#"
|
||||
echo "Scripts arguments: $@"
|
||||
echo "Scripts arguments separeted in different variables: $1 $2..."
|
||||
|
||||
# 读取输入:
|
||||
echo "What's your name?"
|
||||
read NAME # 这里不需要声明新变量
|
||||
echo Hello, $NAME!
|
||||
|
||||
# 通常的 if 结构看起来像这样:
|
||||
# 'man test' 可查看更多的信息
|
||||
if [ $NAME -ne $USER ]
|
||||
then
|
||||
echo "Your name is you username"
|
||||
else
|
||||
echo "Your name isn't you username"
|
||||
fi
|
||||
|
||||
# 根据上一个指令执行结果决定是否执行下一个指令
|
||||
echo "Always executed" || echo "Only executed if first command fail"
|
||||
echo "Always executed" && echo "Only executed if first command does NOT fail"
|
||||
|
||||
# 表达式的格式如下:
|
||||
echo $(( 10 + 5 ))
|
||||
|
||||
# 与其他编程语言不同的是,bash 运行时依赖上下文。比如,使用 ls 时,列出当前目录。
|
||||
ls
|
||||
|
||||
# 指令可以带有选项:
|
||||
ls -l # 列出文件和目录的详细信息
|
||||
|
||||
# 前一个指令的输出可以当作后一个指令的输入。grep 用来匹配字符串。
|
||||
# 用下面的指令列出当前目录下所有的 txt 文件:
|
||||
ls -l | grep "\.txt"
|
||||
|
||||
# 重定向可以到输出,输入和错误输出。
|
||||
python2 hello.py < "input.in"
|
||||
python2 hello.py > "output.out"
|
||||
python2 hello.py 2> "error.err"
|
||||
# > 会覆盖已存在的文件, >> 会以累加的方式输出文件中。
|
||||
|
||||
# 一个指令可用 $( ) 嵌套在另一个指令内部:
|
||||
# 以下的指令会打印当前目录下的目录和文件总数
|
||||
echo "There are $(ls | wc -l) items here."
|
||||
|
||||
# Bash 的 case 语句与 Java 和 C++ 中的 switch 语句类似:
|
||||
case "$VARIABLE" in
|
||||
# 列出需要匹配的字符串
|
||||
0) echo "There is a zero.";;
|
||||
1) echo "There is a one.";;
|
||||
*) echo "It is not null.";;
|
||||
esac
|
||||
|
||||
# 循环遍历给定的参数序列:
|
||||
# 变量$VARIABLE 的值会被打印 3 次。
|
||||
# 注意 ` ` 和 $( ) 等价。seq 返回长度为 3 的数组。
|
||||
for VARIABLE in `seq 3`
|
||||
do
|
||||
echo "$VARIABLE"
|
||||
done
|
||||
|
||||
# 你也可以使用函数
|
||||
# 定义函数:
|
||||
function foo ()
|
||||
{
|
||||
echo "Arguments work just like script arguments: $@"
|
||||
echo "And: $1 $2..."
|
||||
echo "This is a function"
|
||||
return 0
|
||||
}
|
||||
|
||||
# 更简单的方法
|
||||
bar ()
|
||||
{
|
||||
echo "Another way to declare functions!"
|
||||
return 0
|
||||
}
|
||||
|
||||
# 调用函数
|
||||
foo "My name is" $NAME
|
||||
|
||||
# 有很多有用的指令需要学习:
|
||||
tail -n 10 file.txt
|
||||
# 打印 file.txt 的最后 10 行
|
||||
head -n 10 file.txt
|
||||
# 打印 file.txt 的前 10 行
|
||||
sort file.txt
|
||||
# 将 file.txt 按行排序
|
||||
uniq -d file.txt
|
||||
# 报告或忽略重复的行,用选项 -d 打印重复的行
|
||||
cut -d ',' -f 1 file.txt
|
||||
# 打印每行中 ',' 之前内容
|
||||
```
|
70
zh-cn/brainfuck-cn.html.markdown
Normal file
70
zh-cn/brainfuck-cn.html.markdown
Normal file
@ -0,0 +1,70 @@
|
||||
---
|
||||
language: brainfuck
|
||||
lang: zh-cn
|
||||
contributors:
|
||||
- ["Prajit Ramachandran", "http://prajitr.github.io/"]
|
||||
- ["Mathias Bynens", "http://mathiasbynens.be/"]
|
||||
translators:
|
||||
- ["lyuehh", "https://github.com/lyuehh"]
|
||||
---
|
||||
|
||||
Brainfuck 是一个极小的只有8个指令的图灵完全的编程语言。
|
||||
|
||||
```
|
||||
除"><+-.,[]"之外的的任何字符都会被忽略 (不包含双引号)。
|
||||
|
||||
Brainfuck 包含一个有30,000个单元为0的数组,和
|
||||
一个数据指针指向当前的单元。
|
||||
|
||||
8个指令如下:
|
||||
+ : 指针指向的单元的值加1
|
||||
- : 指针指向的单元的值减1
|
||||
> : 将指针移动到下一个单元(右边的元素)
|
||||
< : 将指针移动到上一个单元(左边的元素)
|
||||
. : 打印当前单元的内容的ASCII值 (比如 65 = 'A').
|
||||
, : 读取一个字符到当前的单元
|
||||
[ : 如果当前单元的值是0,则向后调转到对应的]处
|
||||
] : 如果当前单元的值不是0,则向前跳转到对应的[处
|
||||
|
||||
[ 和 ] 组成了一个while循环。很明显,它们必须配对。
|
||||
|
||||
让我们看一些基本的brainfuck 程序。
|
||||
|
||||
++++++ [ > ++++++++++ < - ] > +++++ .
|
||||
|
||||
这个程序打印字母'A'。首先,它把 #1 增加到6,使用它来作为循环条件,
|
||||
然后,进入循环,将指针移动到 #2 ,将 #2 的值增加到10,然后
|
||||
移动回 #1,将单元 #1 的值减1,然后继续。循环共进行了6次。
|
||||
|
||||
这时,我们在 #1,它的值为0,#2 的值为60,我们移动到
|
||||
#2,将 #2 的内容加上5,然后将 #2 的内容打印出来,65在
|
||||
ASCII中表示'A', 所以'A'就会被打印出来。
|
||||
|
||||
|
||||
, [ > + < - ] > .
|
||||
|
||||
这个程序从用户的输入中读取一个字符,然后把它复制到 #1。
|
||||
然后我们开始一个循环,移动到 #2,将 #2 的值加1,再移动回 #1,将 #1
|
||||
的值减1,直到 #1的值为0,这样 #2 里就保存了 #1 的旧值,循环结束时我们
|
||||
在 #1,这时我们移动到 #2,然后把字符以ASCII打印出来。
|
||||
|
||||
而且要记住的一点就是,空格在这里只是为了可读性,你可以将他们写成这样:
|
||||
|
||||
,[>+<-]>.
|
||||
|
||||
试着思考一下这段程序是干什么的:
|
||||
|
||||
,>,< [ > [ >+ >+ << -] >> [- << + >>] <<< -] >>
|
||||
|
||||
这段程序从输入接收2个参数,然后将他们相乘。
|
||||
|
||||
先读取2个输入,然后开始外层循环,以 #1 作为终止条件,然后将指针移动到
|
||||
#2,然后开始 #2 的内层循环,将 #3 加1。但是这里有一个小问题,在内层
|
||||
循环结束的时候,#2 的值是0了,那么下次执行外层循环的时候,就有问题了。
|
||||
为了解决这个问题,我们可以增加 #4 的值,然后把 #4 的值复制到 #2,
|
||||
最后结果就保存在 #3 中了。
|
||||
```
|
||||
好了这就是brainfuck了。也没那么难,是吧?为了好玩,你可以写你自己的
|
||||
brainfuck程序,或者用其他语言写一个brainfuck的解释器,解释器非常容易
|
||||
实现,但是如果你是一个自虐狂的话,你可以尝试用brainfuck写一个brainfuk的
|
||||
解释器。
|
@ -1,8 +1,8 @@
|
||||
---
|
||||
名字:Go
|
||||
分类:编程语言
|
||||
文件名:learngo.go
|
||||
贡献者:
|
||||
language: Go
|
||||
lang: zh-cn
|
||||
filename: learngo-cn.go
|
||||
contributors:
|
||||
- ["Sonia Keys", "https://github.com/soniakeys"]
|
||||
- ["pantaovay", "https://github.com/pantaovay"]
|
||||
---
|
||||
@ -13,7 +13,7 @@ Go拥有命令式语言的静态类型,编译很快,执行也很快,同时
|
||||
|
||||
Go语言有非常棒的标准库,还有一个充满热情的社区。
|
||||
|
||||
```Go
|
||||
```go
|
||||
// 单行注释
|
||||
/* 多行
|
||||
注释 */
|
||||
|
152
zh-cn/perl-cn.html.markdown
Normal file
152
zh-cn/perl-cn.html.markdown
Normal file
@ -0,0 +1,152 @@
|
||||
---
|
||||
name: perl
|
||||
category: language
|
||||
language: perl
|
||||
filename: learnperl-cn.pl
|
||||
contributors:
|
||||
- ["Korjavin Ivan", "http://github.com/korjavin"]
|
||||
translators:
|
||||
- ["Yadong Wen", "https://github.com/yadongwen"]
|
||||
lang: zh-cn
|
||||
---
|
||||
|
||||
Perl 5是一个功能强大、特性齐全的编程语言,有25年的历史。
|
||||
|
||||
Perl 5可以在包括便携式设备和大型机的超过100个平台上运行,既适用于快速原型构建,也适用于大型项目开发。
|
||||
|
||||
```perl
|
||||
# 单行注释以#号开头
|
||||
|
||||
|
||||
#### Perl的变量类型
|
||||
|
||||
# 变量以$号开头。
|
||||
# 合法变量名以英文字母或者下划线起始,
|
||||
# 后接任意数目的字母、数字或下划线。
|
||||
|
||||
### Perl有三种主要的变量类型:标量、数组和哈希。
|
||||
|
||||
## 标量
|
||||
# 标量类型代表单个值:
|
||||
my $animal = "camel";
|
||||
my $answer = 42;
|
||||
|
||||
# 标量类型值可以是字符串、整型或浮点类型,Perl会根据需要自动进行类型转换。
|
||||
|
||||
## 数组
|
||||
# 数组类型代表一列值:
|
||||
my @animals = ("camel", "llama", "owl");
|
||||
my @numbers = (23, 42, 69);
|
||||
my @mixed = ("camel", 42, 1.23);
|
||||
|
||||
|
||||
|
||||
## 哈希
|
||||
# 哈希类型代表一个键/值对的集合:
|
||||
|
||||
my %fruit_color = ("apple", "red", "banana", "yellow");
|
||||
|
||||
# 可以使用空格和“=>”操作符更清晰的定义哈希:
|
||||
|
||||
my %fruit_color = (
|
||||
apple => "red",
|
||||
banana => "yellow",
|
||||
);
|
||||
# perldata中有标量、数组和哈希更详细的介绍。 (perldoc perldata).
|
||||
|
||||
# 可以用引用构建更复杂的数据类型,比如嵌套的列表和哈希。
|
||||
|
||||
#### 逻辑和循环结构
|
||||
|
||||
# Perl有大多数常见的逻辑和循环控制结构
|
||||
|
||||
if ( $var ) {
|
||||
...
|
||||
} elsif ( $var eq 'bar' ) {
|
||||
...
|
||||
} else {
|
||||
...
|
||||
}
|
||||
|
||||
unless ( condition ) {
|
||||
...
|
||||
}
|
||||
# 上面这个比"if (!condition)"更可读。
|
||||
|
||||
# 有Perl特色的后置逻辑结构
|
||||
print "Yow!" if $zippy;
|
||||
print "We have no bananas" unless $bananas;
|
||||
|
||||
# while
|
||||
while ( condition ) {
|
||||
...
|
||||
}
|
||||
|
||||
|
||||
# for和foreach
|
||||
for ($i = 0; $i <= $max; $i++) {
|
||||
...
|
||||
}
|
||||
|
||||
foreach (@array) {
|
||||
print "This element is $_\n";
|
||||
}
|
||||
|
||||
|
||||
#### 正则表达式
|
||||
|
||||
# Perl对正则表达式有深入广泛的支持,perlrequick和perlretut等文档有详细介绍。简单来说:
|
||||
|
||||
# 简单匹配
|
||||
if (/foo/) { ... } # 如果 $_ 包含"foo"逻辑为真
|
||||
if ($a =~ /foo/) { ... } # 如果 $a 包含"foo"逻辑为真
|
||||
|
||||
# 简单替换
|
||||
|
||||
$a =~ s/foo/bar/; # 将$a中的foo替换为bar
|
||||
$a =~ s/foo/bar/g; # 将$a中所有的foo替换为bar
|
||||
|
||||
|
||||
#### 文件和输入输出
|
||||
|
||||
# 可以使用“open()”函数打开文件用于输入输出。
|
||||
|
||||
open(my $in, "<", "input.txt") or die "Can't open input.txt: $!";
|
||||
open(my $out, ">", "output.txt") or die "Can't open output.txt: $!";
|
||||
open(my $log, ">>", "my.log") or die "Can't open my.log: $!";
|
||||
|
||||
# 可以用"<>"操作符读取一个打开的文件句柄。 在标量语境下会读取一行,
|
||||
# 在列表环境下会将整个文件读入并将每一行赋给列表的一个元素:
|
||||
|
||||
my $line = <$in>;
|
||||
my @lines = <$in>;
|
||||
|
||||
#### 子程序
|
||||
|
||||
# 写子程序很简单:
|
||||
|
||||
sub logger {
|
||||
my $logmessage = shift;
|
||||
open my $logfile, ">>", "my.log" or die "Could not open my.log: $!";
|
||||
print $logfile $logmessage;
|
||||
}
|
||||
|
||||
# 现在可以像内置函数一样调用子程序:
|
||||
|
||||
logger("We have a logger subroutine!");
|
||||
|
||||
|
||||
```
|
||||
|
||||
#### 使用Perl模块
|
||||
|
||||
Perl模块提供一系列特性来帮助你避免重新发明轮子,CPAN是下载模块的好地方( http://www.cpan.org/ )。Perl发行版本身也包含很多流行的模块。
|
||||
|
||||
perlfaq有很多常见问题和相应回答,也经常有对优秀CPAN模块的推荐介绍。
|
||||
|
||||
#### 深入阅读
|
||||
|
||||
- [perl-tutorial](http://perl-tutorial.org/)
|
||||
- [www.perl.com的learn站点](http://www.perl.org/learn.html)
|
||||
- [perldoc](http://perldoc.perl.org/)
|
||||
- 以及 perl 内置的: `perldoc perlintro`
|
541
zh-cn/r-cn.html.markdown
Normal file
541
zh-cn/r-cn.html.markdown
Normal file
@ -0,0 +1,541 @@
|
||||
---
|
||||
language: R
|
||||
contributors:
|
||||
- ["e99n09", "http://github.com/e99n09"]
|
||||
- ["isomorphismes", "http://twitter.com/isomorphisms"]
|
||||
translators:
|
||||
- ["小柒", "http://weibo.com/u/2328126220"]
|
||||
- ["alswl", "https://github.com/alswl"]
|
||||
filename: learnr.r
|
||||
lang: zh-cn
|
||||
---
|
||||
|
||||
R 是一门统计语言。它有很多数据分析和挖掘程序包。可以用来统计、分析和制图。
|
||||
你也可以在 LaTeX 文档中运行 `R` 命令。
|
||||
|
||||
```python
|
||||
# 评论以 # 开始
|
||||
|
||||
# R 语言原生不支持 多行注释
|
||||
# 但是你可以像这样来多行注释
|
||||
|
||||
# 在窗口里按回车键可以执行一条命令
|
||||
|
||||
|
||||
###################################################################
|
||||
# 不用懂编程就可以开始动手了
|
||||
###################################################################
|
||||
|
||||
data() # 浏览内建的数据集
|
||||
data(rivers) # 北美主要河流的长度(数据集)
|
||||
ls() # 在工作空间中查看「河流」是否出现
|
||||
head(rivers) # 撇一眼数据集
|
||||
# 735 320 325 392 524 450
|
||||
length(rivers) # 我们测量了多少条河流?
|
||||
# 141
|
||||
summary(rivers)
|
||||
# Min. 1st Qu. Median Mean 3rd Qu. Max.
|
||||
# 135.0 310.0 425.0 591.2 680.0 3710.0
|
||||
stem(rivers) # 茎叶图(一种类似于直方图的展现形式)
|
||||
#
|
||||
# The decimal point is 2 digit(s) to the right of the |
|
||||
#
|
||||
# 0 | 4
|
||||
# 2 | 011223334555566667778888899900001111223333344455555666688888999
|
||||
# 4 | 111222333445566779001233344567
|
||||
# 6 | 000112233578012234468
|
||||
# 8 | 045790018
|
||||
# 10 | 04507
|
||||
# 12 | 1471
|
||||
# 14 | 56
|
||||
# 16 | 7
|
||||
# 18 | 9
|
||||
# 20 |
|
||||
# 22 | 25
|
||||
# 24 | 3
|
||||
# 26 |
|
||||
# 28 |
|
||||
# 30 |
|
||||
# 32 |
|
||||
# 34 |
|
||||
# 36 | 1
|
||||
|
||||
|
||||
stem(log(rivers)) # 查看数据集的方式既不是标准形式,也不是取log后的结果! 看起来,是钟形曲线形式的基本数据集
|
||||
|
||||
# The decimal point is 1 digit(s) to the left of the |
|
||||
#
|
||||
# 48 | 1
|
||||
# 50 |
|
||||
# 52 | 15578
|
||||
# 54 | 44571222466689
|
||||
# 56 | 023334677000124455789
|
||||
# 58 | 00122366666999933445777
|
||||
# 60 | 122445567800133459
|
||||
# 62 | 112666799035
|
||||
# 64 | 00011334581257889
|
||||
# 66 | 003683579
|
||||
# 68 | 0019156
|
||||
# 70 | 079357
|
||||
# 72 | 89
|
||||
# 74 | 84
|
||||
# 76 | 56
|
||||
# 78 | 4
|
||||
# 80 |
|
||||
# 82 | 2
|
||||
|
||||
|
||||
hist(rivers, col="#333333", border="white", breaks=25) # 试试用这些参数画画 (译者注:给 river 做统计频数直方图,包含了这些参数:数据源,颜色,边框,空格)
|
||||
hist(log(rivers), col="#333333", border="white", breaks=25) #你还可以做更多式样的绘图
|
||||
|
||||
# 还有其他一些简单的数据集可以被用来加载。R 语言包括了大量这种 data()
|
||||
data(discoveries)
|
||||
plot(discoveries, col="#333333", lwd=3, xlab="Year", main="Number of important discoveries per year")
|
||||
# 译者注:参数为(数据源,颜色,线条宽度,X 轴名称,标题)
|
||||
plot(discoveries, col="#333333", lwd=3, type = "h", xlab="Year", main="Number of important discoveries per year")
|
||||
|
||||
|
||||
# 除了按照默认的年份排序,我们还可以排序来发现特征
|
||||
sort(discoveries)
|
||||
# [1] 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2
|
||||
# [26] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3
|
||||
# [51] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4
|
||||
# [76] 4 4 4 4 5 5 5 5 5 5 5 6 6 6 6 6 6 7 7 7 7 8 9 10 12
|
||||
|
||||
stem(discoveries, scale=2) # 译者注:茎叶图(数据,放大系数)
|
||||
#
|
||||
# The decimal point is at the |
|
||||
#
|
||||
# 0 | 000000000
|
||||
# 1 | 000000000000
|
||||
# 2 | 00000000000000000000000000
|
||||
# 3 | 00000000000000000000
|
||||
# 4 | 000000000000
|
||||
# 5 | 0000000
|
||||
# 6 | 000000
|
||||
# 7 | 0000
|
||||
# 8 | 0
|
||||
# 9 | 0
|
||||
# 10 | 0
|
||||
# 11 |
|
||||
# 12 | 0
|
||||
|
||||
max(discoveries)
|
||||
# 12
|
||||
|
||||
summary(discoveries)
|
||||
# Min. 1st Qu. Median Mean 3rd Qu. Max.
|
||||
# 0.0 2.0 3.0 3.1 4.0 12.0
|
||||
|
||||
|
||||
|
||||
|
||||
#基本的统计学操作也不需要任何编程知识
|
||||
|
||||
#随机生成数据
|
||||
round(runif(7, min=.5, max=6.5))
|
||||
# 译者注:runif 产生随机数,round 四舍五入
|
||||
# 1 4 6 1 4 6 4
|
||||
|
||||
# 你输出的结果会和我们给出的不同,除非我们设置了相同的随机种子 random.seed(31337)
|
||||
|
||||
|
||||
#从标准高斯函数中随机生成 9 次
|
||||
rnorm(9)
|
||||
# [1] 0.07528471 1.03499859 1.34809556 -0.82356087 0.61638975 -1.88757271
|
||||
# [7] -0.59975593 0.57629164 1.08455362
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#########################
|
||||
# 基础编程
|
||||
#########################
|
||||
|
||||
# 数值
|
||||
|
||||
#“数值”指的是双精度的浮点数
|
||||
5 # 5
|
||||
class(5) # "numeric"
|
||||
5e4 # 50000 # 用科学技术法方便的处理极大值、极小值或者可变的量级
|
||||
6.02e23 # 阿伏伽德罗常数#
|
||||
1.6e-35 # 布朗克长度
|
||||
|
||||
# 长整数并用 L 结尾
|
||||
5L # 5
|
||||
#输出5L
|
||||
class(5L) # "integer"
|
||||
|
||||
# 可以自己试一试?用 class() 函数获取更多信息
|
||||
# 事实上,你可以找一些文件查阅 `xyz` 以及xyz的差别
|
||||
# `xyz` 用来查看源码实现,?xyz 用来看帮助
|
||||
|
||||
# 算法
|
||||
10 + 66 # 76
|
||||
53.2 - 4 # 49.2
|
||||
2 * 2.0 # 4
|
||||
3L / 4 # 0.75
|
||||
3 %% 2 # 1
|
||||
|
||||
# 特殊数值类型
|
||||
class(NaN) # "numeric"
|
||||
class(Inf) # "numeric"
|
||||
class(-Inf) # "numeric" # 在以下场景中会用到 integrate( dnorm(x), 3, Inf ) -- 消除 Z 轴数据
|
||||
|
||||
# 但要注意,NaN 并不是唯一的特殊数值类型……
|
||||
class(NA) # 看上面
|
||||
class(NULL) # NULL
|
||||
|
||||
|
||||
# 简单列表
|
||||
c(6, 8, 7, 5, 3, 0, 9) # 6 8 7 5 3 0 9
|
||||
c('alef', 'bet', 'gimmel', 'dalet', 'he')
|
||||
c('Z', 'o', 'r', 'o') == "Zoro" # FALSE FALSE FALSE FALSE
|
||||
|
||||
# 一些优雅的内置功能
|
||||
5:15 # 5 6 7 8 9 10 11 12 13 14 15
|
||||
|
||||
seq(from=0, to=31337, by=1337)
|
||||
# [1] 0 1337 2674 4011 5348 6685 8022 9359 10696 12033 13370 14707
|
||||
# [13] 16044 17381 18718 20055 21392 22729 24066 25403 26740 28077 29414 30751
|
||||
|
||||
letters
|
||||
# [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s"
|
||||
# [20] "t" "u" "v" "w" "x" "y" "z"
|
||||
|
||||
month.abb # "Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov" "Dec"
|
||||
|
||||
|
||||
# Access the n'th element of a list with list.name[n] or sometimes list.name[[n]]
|
||||
# 使用 list.name[n] 来访问第 n 个列表元素,有时候需要使用 list.name[[n]]
|
||||
letters[18] # "r"
|
||||
LETTERS[13] # "M"
|
||||
month.name[9] # "September"
|
||||
c(6, 8, 7, 5, 3, 0, 9)[3] # 7
|
||||
|
||||
|
||||
|
||||
# 字符串
|
||||
|
||||
# 字符串和字符在 R 语言中没有区别
|
||||
"Horatio" # "Horatio"
|
||||
class("Horatio") # "character"
|
||||
substr("Fortuna multis dat nimis, nulli satis.", 9, 15) # "multis "
|
||||
gsub('u', 'ø', "Fortuna multis dat nimis, nulli satis.") # "Fortøna møltis dat nimis, nølli satis."
|
||||
|
||||
|
||||
|
||||
# 逻辑值
|
||||
|
||||
# 布尔值
|
||||
class(TRUE) # "logical"
|
||||
class(FALSE) # "logical"
|
||||
# 和我们预想的一样
|
||||
TRUE == TRUE # TRUE
|
||||
TRUE == FALSE # FALSE
|
||||
FALSE != FALSE # FALSE
|
||||
FALSE != TRUE # TRUE
|
||||
# 缺失数据(NA)也是逻辑值
|
||||
class(NA) # "logical"
|
||||
#定义NA为逻辑型
|
||||
|
||||
|
||||
|
||||
# 因子
|
||||
# 因子是为数据分类排序设计的(像是排序小朋友们的年级或性别)
|
||||
levels(factor(c("female", "male", "male", "female", "NA", "female"))) # "female" "male" "NA"
|
||||
|
||||
factor(c("female", "female", "male", "NA", "female"))
|
||||
# female female male NA female
|
||||
# Levels: female male NA
|
||||
|
||||
data(infert) # 自然以及引产导致的不育症
|
||||
levels(infert$education) # "0-5yrs" "6-11yrs" "12+ yrs"
|
||||
|
||||
|
||||
|
||||
# 变量
|
||||
|
||||
# 有许多种方式用来赋值
|
||||
x = 5 # 这样可以
|
||||
y <- "1" # 更推荐这样
|
||||
TRUE -> z # 这样可行,但是很怪
|
||||
|
||||
#我们还可以使用强制转型
|
||||
as.numeric(y) # 1
|
||||
as.character(x) # "5"
|
||||
|
||||
# 循环
|
||||
|
||||
# for 循环语句
|
||||
for (i in 1:4) {
|
||||
print(i)
|
||||
}
|
||||
|
||||
# while 循环
|
||||
a <- 10
|
||||
while (a > 4) {
|
||||
cat(a, "...", sep = "")
|
||||
a <- a - 1
|
||||
}
|
||||
|
||||
# 记住,在 R 语言中 for / while 循环都很慢
|
||||
# 建议使用 apply()(我们一会介绍)来错做一串数据(比如一列或者一行数据)
|
||||
|
||||
# IF/ELSE
|
||||
|
||||
# 再来看这些优雅的标准
|
||||
if (4 > 3) {
|
||||
print("Huzzah! It worked!")
|
||||
} else {
|
||||
print("Noooo! This is blatantly illogical!")
|
||||
}
|
||||
|
||||
# =>
|
||||
# [1] "Huzzah! It worked!"
|
||||
|
||||
# 函数
|
||||
|
||||
# 定义如下
|
||||
jiggle <- function(x) {
|
||||
x + rnorm(x, sd=.1) #add in a bit of (controlled) noise
|
||||
return(x)
|
||||
}
|
||||
|
||||
# 和其他 R 语言函数一样调用
|
||||
jiggle(5) # 5±ε. 使用 set.seed(2716057) 后, jiggle(5)==5.005043
|
||||
|
||||
#########################
|
||||
# 数据容器:vectors, matrices, data frames, and arrays
|
||||
#########################
|
||||
|
||||
# 单维度
|
||||
# 你可以将目前我们学习到的任何类型矢量化,只要它们拥有相同的类型
|
||||
vec <- c(8, 9, 10, 11)
|
||||
vec # 8 9 10 11
|
||||
# 矢量的类型是这一组数据元素的类型
|
||||
class(vec) # "numeric"
|
||||
# If you vectorize items of different classes, weird coercions happen
|
||||
#如果你强制的将不同类型数值矢量化,会出现特殊值
|
||||
c(TRUE, 4) # 1 4
|
||||
c("dog", TRUE, 4) # "dog" "TRUE" "4"
|
||||
|
||||
#我们这样来取内部数据,(R 的下标索引顺序 1 开始)
|
||||
vec[1] # 8
|
||||
# 我们可以根据条件查找特定数据
|
||||
which(vec %% 2 == 0) # 1 3
|
||||
# 抓取矢量中第一个和最后一个字符
|
||||
head(vec, 1) # 8
|
||||
tail(vec, 1) # 11
|
||||
#如果下标溢出或不存会得到 NA
|
||||
vec[6] # NA
|
||||
# 你可以使用 length() 获取矢量的长度
|
||||
length(vec) # 4
|
||||
|
||||
# 你可以直接操作矢量或者矢量的子集
|
||||
vec * 4 # 16 20 24 28
|
||||
vec[2:3] * 5 # 25 30
|
||||
# 这里有许多内置的函数,来表现向量
|
||||
mean(vec) # 9.5
|
||||
var(vec) # 1.666667
|
||||
sd(vec) # 1.290994
|
||||
max(vec) # 11
|
||||
min(vec) # 8
|
||||
sum(vec) # 38
|
||||
|
||||
# 二维(相同元素类型)
|
||||
|
||||
#你可以为同样类型的变量建立矩阵
|
||||
mat <- matrix(nrow = 3, ncol = 2, c(1,2,3,4,5,6))
|
||||
mat
|
||||
# =>
|
||||
# [,1] [,2]
|
||||
# [1,] 1 4
|
||||
# [2,] 2 5
|
||||
# [3,] 3 6
|
||||
# 和 vector 不一样的是,一个矩阵的类型真的是 「matrix」,而不是内部元素的类型
|
||||
class(mat) # => "matrix"
|
||||
# 访问第一行的字符
|
||||
mat[1,] # 1 4
|
||||
# 操作第一行数据
|
||||
3 * mat[,1] # 3 6 9
|
||||
# 访问一个特定数据
|
||||
mat[3,2] # 6
|
||||
# 转置整个矩阵(译者注:变成 2 行 3 列)
|
||||
t(mat)
|
||||
# =>
|
||||
# [,1] [,2] [,3]
|
||||
# [1,] 1 2 3
|
||||
# [2,] 4 5 6
|
||||
|
||||
# 使用 cbind() 函数把两个矩阵按列合并,形成新的矩阵
|
||||
mat2 <- cbind(1:4, c("dog", "cat", "bird", "dog"))
|
||||
mat2
|
||||
# =>
|
||||
# [,1] [,2]
|
||||
# [1,] "1" "dog"
|
||||
# [2,] "2" "cat"
|
||||
# [3,] "3" "bird"
|
||||
# [4,] "4" "dog"
|
||||
class(mat2) # matrix
|
||||
# Again, note what happened!
|
||||
# 注意
|
||||
# 因为矩阵内部元素必须包含同样的类型
|
||||
# 所以现在每一个元素都转化成字符串
|
||||
c(class(mat2[,1]), class(mat2[,2]))
|
||||
|
||||
# 按行合并两个向量,建立新的矩阵
|
||||
mat3 <- rbind(c(1,2,4,5), c(6,7,0,4))
|
||||
mat3
|
||||
# =>
|
||||
# [,1] [,2] [,3] [,4]
|
||||
# [1,] 1 2 4 5
|
||||
# [2,] 6 7 0 4
|
||||
# 哈哈,数据类型都一样的,没有发生强制转换,生活真美好
|
||||
|
||||
# 二维(不同的元素类型)
|
||||
|
||||
# 利用 data frame 可以将不同类型数据放在一起
|
||||
dat <- data.frame(c(5,2,1,4), c("dog", "cat", "bird", "dog"))
|
||||
names(dat) <- c("number", "species") # 给数据列命名
|
||||
class(dat) # "data.frame"
|
||||
dat
|
||||
# =>
|
||||
# number species
|
||||
# 1 5 dog
|
||||
# 2 2 cat
|
||||
# 3 1 bird
|
||||
# 4 4 dog
|
||||
class(dat$number) # "numeric"
|
||||
class(dat[,2]) # "factor"
|
||||
# data.frame() 会将字符向量转换为 factor 向量
|
||||
|
||||
# 有很多精妙的方法来获取 data frame 的子数据集
|
||||
dat$number # 5 2 1 4
|
||||
dat[,1] # 5 2 1 4
|
||||
dat[,"number"] # 5 2 1 4
|
||||
|
||||
# 多维(相同元素类型)
|
||||
|
||||
# 使用 arry 创造一个 n 维的表格
|
||||
# You can make a two-dimensional table (sort of like a matrix)
|
||||
# 你可以建立一个 2 维表格(有点像矩阵)
|
||||
array(c(c(1,2,4,5),c(8,9,3,6)), dim=c(2,4))
|
||||
# =>
|
||||
# [,1] [,2] [,3] [,4]
|
||||
# [1,] 1 4 8 3
|
||||
# [2,] 2 5 9 6
|
||||
#你也可以利用数组建立一个三维的矩阵
|
||||
array(c(c(c(2,300,4),c(8,9,0)),c(c(5,60,0),c(66,7,847))), dim=c(3,2,2))
|
||||
# =>
|
||||
# , , 1
|
||||
#
|
||||
# [,1] [,2]
|
||||
# [1,] 2 8
|
||||
# [2,] 300 9
|
||||
# [3,] 4 0
|
||||
#
|
||||
# , , 2
|
||||
#
|
||||
# [,1] [,2]
|
||||
# [1,] 5 66
|
||||
# [2,] 60 7
|
||||
# [3,] 0 847
|
||||
|
||||
#列表(多维的,不同类型的)
|
||||
|
||||
# R语言有列表的形式
|
||||
list1 <- list(time = 1:40)
|
||||
list1$price = c(rnorm(40,.5*list1$time,4)) # 随机
|
||||
list1
|
||||
|
||||
# You can get items in the list like so
|
||||
# 你可以这样获得列表的元素
|
||||
list1$time
|
||||
# You can subset list items like vectors
|
||||
# 你也可以和矢量一样获取他们的子集
|
||||
list1$price[4]
|
||||
|
||||
#########################
|
||||
# apply()函数家族
|
||||
#########################
|
||||
|
||||
# 还记得 mat 么?
|
||||
mat
|
||||
# =>
|
||||
# [,1] [,2]
|
||||
# [1,] 1 4
|
||||
# [2,] 2 5
|
||||
# [3,] 3 6
|
||||
# Use apply(X, MARGIN, FUN) to apply function FUN to a matrix X
|
||||
# 使用(X, MARGIN, FUN)将函数 FUN 应用到矩阵 X 的行 (MAR = 1) 或者 列 (MAR = 2)
|
||||
# That is, R does FUN to each row (or column) of X, much faster than a
|
||||
# R 在 X 的每一行/列使用 FUN,比循环要快很多
|
||||
apply(mat, MAR = 2, myFunc)
|
||||
# =>
|
||||
# [,1] [,2]
|
||||
# [1,] 3 15
|
||||
# [2,] 7 19
|
||||
# [3,] 11 23
|
||||
# 还有其他家族函数 ?lapply, ?sapply
|
||||
|
||||
# 不要被吓到,虽然许多人在此都被搞混
|
||||
# plyr 程序包的作用是用来改进 apply() 函数家族
|
||||
|
||||
install.packages("plyr")
|
||||
require(plyr)
|
||||
?plyr
|
||||
|
||||
#########################
|
||||
# 载入数据
|
||||
#########################
|
||||
|
||||
# "pets.csv" 是网上的一个文本
|
||||
pets <- read.csv("http://learnxinyminutes.com/docs/pets.csv")
|
||||
pets
|
||||
head(pets, 2) # 前两行
|
||||
tail(pets, 1) # 最后一行
|
||||
|
||||
# 以 .csv 格式来保存数据集或者矩阵
|
||||
write.csv(pets, "pets2.csv") # 保存到新的文件 pets2.csv
|
||||
# set working directory with setwd(), look it up with getwd()
|
||||
# 使用 setwd() 改变工作目录,使用 getwd() 查看当前工作目录
|
||||
|
||||
# 尝试使用 ?read.csv 和 ?write.csv 来查看更多信息
|
||||
|
||||
#########################
|
||||
# 画图
|
||||
#########################
|
||||
|
||||
# 散点图
|
||||
plot(list1$time, list1$price, main = "fake data") # 译者注:横轴 list1$time,纵轴 wlist1$price,标题 fake data
|
||||
# 回归图
|
||||
linearModel <- lm(price ~ time, data = list1) # 译者注:线性模型,数据集为list1,以价格对时间做相关分析模型
|
||||
linearModel # 拟合结果
|
||||
# 将拟合结果展示在图上,颜色设为红色
|
||||
abline(linearModel, col = "red")
|
||||
# 也可以获取各种各样漂亮的分析图
|
||||
plot(linearModel)
|
||||
|
||||
# 直方图
|
||||
hist(rpois(n = 10000, lambda = 5), col = "thistle") # 译者注:统计频数直方图
|
||||
|
||||
# 柱状图
|
||||
barplot(c(1,4,5,1,2), names.arg = c("red","blue","purple","green","yellow"))
|
||||
|
||||
# 可以尝试着使用 ggplot2 程序包来美化图片
|
||||
install.packages("ggplot2")
|
||||
require(ggplot2)
|
||||
?ggplot2
|
||||
|
||||
```
|
||||
|
||||
## 获得 R
|
||||
|
||||
* 从 [http://www.r-project.org/](http://www.r-project.org/) 获得安装包和图形化界面
|
||||
* [RStudio](http://www.rstudio.com/ide/) 是另一个图形化界面
|
Loading…
Reference in New Issue
Block a user