summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--c.html.markdown250
-rw-r--r--go.html.markdown354
-rw-r--r--ko-kr/java-kr.html.markdown10
-rw-r--r--pt-br/elisp-pt.html.markdown16
-rw-r--r--pt-br/ruby-pt.html.markdown8
-rw-r--r--ru-ru/clojure-ru.html.markdown2
-rw-r--r--ru-ru/php-ru.html.markdown18
-rw-r--r--ru-ru/python-ru.html.markdown8
-rw-r--r--zh-cn/go-zh.html.markdown183
9 files changed, 425 insertions, 424 deletions
diff --git a/c.html.markdown b/c.html.markdown
index 00b13cb0..24a96463 100644
--- a/c.html.markdown
+++ b/c.html.markdown
@@ -1,11 +1,9 @@
---
-- name: c
-- category: language
-- language: c
-- filename: learnc.c
-- contributors:
- - [Adam Bard](http://adambard.com/)
- - [Árpád Goretity](http://twitter.com/H2CO3_iOS)
+language: c
+filename: learnc.c
+contributors:
+ - ["Adam Bard", "http://adambard.com/"]
+ - ["Árpád Goretity", "http://twitter.com/H2CO3_iOS"]
---
@@ -27,17 +25,10 @@ Multi-line comments look like this. They work in C89 as well.
#include <stdio.h>
#include <string.h>
-// file names between <angle brackets> are headers from the C standard library.
-// They are searched for by the preprocessor in the system include paths
-// (usually /usr/lib on Unices, can be controlled with the -I<dir> option if you are using GCC or clang.)
+// (File names between <angle brackets> are headers from the C standard library.)
// For your own headers, use double quotes instead of angle brackets:
#include "my_header.h"
-// The C preprocessor introduces an almost fully-featured macro language. It's useful, but
-// it can be confusing (and what's even worse, it can be misused). Read the
-// Wikipedia article on the C preprocessor for further information:
-// http://en.wikipedia.org/wiki/C_preprocessor
-
// Declare function signatures in advance in a .h file, or at the top of
// your .c file.
void function_1();
@@ -50,132 +41,117 @@ int main() {
// %d is an integer, \n is a newline
printf("%d\n", 0); // => Prints 0
// All statements must end with a semicolon
-
+
///////////////////////////////////////
// Types
///////////////////////////////////////
-
- // You have to declare variables before using them. A variable declaration
- // requires you to specify its type; a variable's type determines its size
- // in bytes.
-
+
// ints are usually 4 bytes
int x_int = 0;
-
+
// shorts are usually 2 bytes
short x_short = 0;
-
+
// chars are guaranteed to be 1 byte
char x_char = 0;
char y_char = 'y'; // Char literals are quoted with ''
-
+
// longs are often 4 to 8 bytes; long longs are guaranteed to be at least
// 64 bits
long x_long = 0;
long long x_long_long = 0;
-
+
// floats are usually 32-bit floating point numbers
float x_float = 0.0;
-
+
// doubles are usually 64-bit floating-point numbers
double x_double = 0.0;
-
- // Integral types may be unsigned. This means they can't be negative, but
- // the maximum value of an unsigned variable is greater than the maximum
- // signed value of the same size.
- unsigned char ux_char;
+
+ // Integral types may be unsigned.
unsigned short ux_short;
unsigned int ux_int;
unsigned long long ux_long_long;
-
- // Other than char, which is always 1 byte (but not necessarily 8 bits!),
- // these types vary in size depending on your machine and compiler.
- // sizeof(T) gives you the size of a variable with type T in
- // bytes so you can express the size of these types in a portable way.
- // sizeof(obj) yields the size of an actual expression (variable, literal, etc.).
- // For example,
+
+ // sizeof(T) gives you the size of a variable with type T in bytes
+ // sizeof(obj) yields the size of the expression (variable, literal, etc.).
printf("%zu\n", sizeof(int)); // => 4 (on most machines with 4-byte words)
-
-
- // It's worth noting that if the argument of the `sizeof` operator is not a type but an expression,
- // then its argument is not evaluated except VLAs (see below). Also, `sizeof()` is an operator, not a function,
- // furthermore, the value it yields is a compile-time constant (except when used on VLAs, again.)
+
+
+ // If the argument of the `sizeof` operator an expression, then its argument
+ // is not evaluated (except VLAs (see below)).
+ // The value it yields in this case is a compile-time constant.
int a = 1;
size_t size = sizeof(a++); // a++ is not evaluated
printf("sizeof(a++) = %zu where a = %d\n", size, a);
- // the above code prints "sizeof(a++) = 4 where a = 1" (on a usual 32-bit architecture)
-
+ // prints "sizeof(a++) = 4 where a = 1" (on a 32-bit architecture)
+
// Arrays must be initialized with a concrete size.
char my_char_array[20]; // This array occupies 1 * 20 = 20 bytes
int my_int_array[20]; // This array occupies 4 * 20 = 80 bytes
// (assuming 4-byte words)
-
-
+
+
// You can initialize an array to 0 thusly:
char my_array[20] = {0};
-
+
// Indexing an array is like other languages -- or,
// rather, other languages are like C
my_array[0]; // => 0
-
+
// Arrays are mutable; it's just memory!
my_array[1] = 2;
printf("%d\n", my_array[1]); // => 2
-
- // In C99 (and as an optional feature in C11), variable-length arrays (VLAs) can be declared as well.
- // The size of such an array need not be a compile time constant:
+
+ // In C99 (and as an optional feature in C11), variable-length arrays (VLAs)
+ // can be declared as well. The size of such an array need not be a compile
+ // time constant:
printf("Enter the array size: "); // ask the user for an array size
char buf[0x100];
fgets(buf, sizeof buf, stdin);
- size_t size = strtoul(buf, NULL, 10); // strtoul parses a string to an unsigned integer
+
+ // strtoul parses a string to an unsigned integer
+ size_t size = strtoul(buf, NULL, 10);
int var_length_array[size]; // declare the VLA
printf("sizeof array = %zu\n", sizeof var_length_array);
-
+
// A possible outcome of this program may be:
- Enter the array size: 10
- sizeof array = 40
-
+ // > Enter the array size: 10
+ // > sizeof array = 40
+
// Strings are just arrays of chars terminated by a NUL (0x00) byte,
// represented in strings as the special character '\0'.
// (We don't have to include the NUL byte in string literals; the compiler
// inserts it at the end of the array for us.)
char a_string[20] = "This is a string";
printf("%s\n", a_string); // %s formats a string
-
- /*
- You may have noticed that a_string is only 16 chars long.
- Char #17 is the NUL byte.
- Chars #18, 19 and 20 are 0 as well - if an initializer list (in this case, the string literal)
- has less elements than the array it is initializing, then excess array elements are implicitly
- initialized to zero. This is why int ar[10] = { 0 } works as expected intuitively.
- */
-
+
printf("%d\n", a_string[16]); // => 0
-
- // So string literals are strings enclosed within double quotes, but if we have characters
- // between single quotes, that's a character literal.
+ // i.e., byte #17 is 0 (as are 18, 19, and 20)
+
+ // If we have characters between single quotes, that's a character literal.
// It's of type `int`, and *not* `char` (for historical reasons).
int cha = 'a'; // fine
- char chb = 'a'; // fine too (implicit conversion from int to char - truncation)
-
+ char chb = 'a'; // fine too (implicit conversion from int to char)
+
///////////////////////////////////////
// Operators
///////////////////////////////////////
-
+
int i1 = 1, i2 = 2; // Shorthand for multiple declaration
float f1 = 1.0, f2 = 2.0;
-
+
// Arithmetic is straightforward
i1 + i2; // => 3
i2 - i1; // => 1
i2 * i1; // => 2
i1 / i2; // => 0 (0.5, but truncated towards 0)
-
- f1 / f2; // => 0.5, plus or minus epsilon - floating-point numbers and calculations are not exact
-
+
+ f1 / f2; // => 0.5, plus or minus epsilon
+ // Floating-point numbers and calculations are not exact
+
// Modulo is there as well
11 % 3; // => 2
-
+
// Comparison operators are probably familiar, but
// there is no boolean type in c. We use ints instead.
// (Or _Bool or bool in C99.)
@@ -187,14 +163,14 @@ int main() {
3 < 2; // => 0
2 <= 2; // => 1
2 >= 2; // => 1
-
+
// C is not Python - comparisons don't chain.
int a = 1;
// WRONG:
int between_0_and_2 = 0 < a < 2;
// Correct:
int between_0_and_2 = 0 < a && a < 2;
-
+
// Logic works on ints
!3; // => 0 (Logical not)
!0; // => 1
@@ -202,7 +178,7 @@ int main() {
0 && 1; // => 0
0 || 1; // => 1 (Logical or)
0 || 0; // => 0
-
+
// Bitwise operators!
~0x0F; // => 0xF0 (bitwise negation, "1's complement")
0x0F & 0xF0; // => 0x00 (bitwise AND)
@@ -210,17 +186,17 @@ int main() {
0x04 ^ 0x0F; // => 0x0B (bitwise XOR)
0x01 << 1; // => 0x02 (bitwise left shift (by 1))
0x02 >> 1; // => 0x01 (bitwise right shift (by 1))
-
- // Be careful when shifting signed integers - the following are all undefined behavior:
+
+ // Be careful when shifting signed integers - the following are undefined:
// - shifting into the sign bit of a signed integer (int a = 1 << 32)
// - left-shifting a negative number (int a = -1 << 2)
- // - shifting by an offset which is more than or equal to the width of the type of the LHS:
+ // - shifting by an offset which is >= the width of the type of the LHS:
// int a = 1 << 32; // UB if int is 32 bits wide
-
+
///////////////////////////////////////
// Control Structures
///////////////////////////////////////
-
+
if (0) {
printf("I am never run\n");
} else if (0) {
@@ -228,36 +204,38 @@ int main() {
} else {
printf("I print\n");
}
-
+
// While loops exist
int ii = 0;
while (ii < 10) {
- printf("%d, ", ii++); // ii++ increments ii in-place, after yielding its value ("postincrement").
+ printf("%d, ", ii++); // ii++ increments ii in-place
+ // after yielding its value ("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 increments kk in-place, and yields the already incremented value ("preincrement")
+ } while (++kk < 10); // ++kk increments kk in-place, and yields
+ // the already incremented value ("preincrement")
// => prints "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "
-
+
printf("\n");
-
+
// For loops too
int jj;
for (jj=0; jj < 10; jj++) {
printf("%d, ", jj);
} // => prints "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "
-
+
printf("\n");
-
+
// branching with multiple choices: switch()
switch (some_integral_expression) {
case 0: // labels need to be integral *constant* epxressions
do_stuff();
- break; // if you don't break, control flow falls over labels - you usually don't want that.
+ break; // if you don't break, control flow falls over labels
case 1:
do_something_else();
break;
@@ -267,73 +245,74 @@ int main() {
exit(-1);
break;
}
-
+
///////////////////////////////////////
// Typecasting
///////////////////////////////////////
-
+
// Every value in C has a type, but you can cast one value into another type
// if you want (with some constraints).
-
+
int x_hex = 0x01; // You can assign vars with hex literals
-
+
// Casting between types will attempt to preserve their numeric values
printf("%d\n", x_hex); // => Prints 1
printf("%d\n", (short) x_hex); // => Prints 1
printf("%d\n", (char) x_hex); // => Prints 1
-
+
// Types will overflow without warning
printf("%d\n", (unsigned char) 257); // => 1 (Max char = 255 if char is 8 bits long)
- // printf("%d\n", (unsigned char) 257); would be undefined behavior - `char' is usually signed
- // on most modern systems, and signed integer overflow invokes UB.
- // Also, for determining the maximal value of a `char`, a `signed char` and an `unisigned char`,
+
+ // For determining the max value of a `char`, a `signed char` and an `unisigned char`,
// respectively, use the CHAR_MAX, SCHAR_MAX and UCHAR_MAX macros from <limits.h>
-
+
// Integral types can be cast to floating-point types, and vice-versa.
printf("%f\n", (float)100); // %f formats a float
printf("%lf\n", (double)100); // %lf formats a double
printf("%d\n", (char)100.0);
-
+
///////////////////////////////////////
// Pointers
///////////////////////////////////////
-
+
// A pointer is a variable declared to store a memory address. Its declaration will
// also tell you the type of data it points to. You can retrieve the memory address
// of your variables, then mess with them.
-
+
int x = 0;
printf("%p\n", (void *)&x); // Use & to retrieve the address of a variable
// (%p formats an object pointer of type void *)
// => Prints some address in memory;
-
-
+
+
// Pointers start with * in their declaration
int *px, not_a_pointer; // px is a pointer to an int
px = &x; // Stores the address of x in px
printf("%p\n", (void *)px); // => Prints some address in memory
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,
// put * in front to de-reference it.
- // Note: yes, it may be confusing that '*' is used for _both_ declaring a pointer and dereferencing it.
- printf("%d\n", *px); // => Prints 0, the value of x, which is what px is pointing to the address of
-
+ // Note: yes, it may be confusing that '*' is used for _both_ declaring a
+ // pointer and dereferencing it.
+ printf("%d\n", *px); // => Prints 0, the value of x
+
// You can also change the value the pointer is pointing to.
// We'll have to wrap the de-reference in parenthesis because
// ++ has a higher precedence than *.
(*px)++; // Increment the value px is pointing to by 1
printf("%d\n", *px); // => Prints 1
printf("%d\n", x); // => Prints 1
-
- int x_array[20]; // Arrays are a good way to allocate a contiguous block of memory
+
+ // Arrays are a good way to allocate a contiguous block of memory
+ int x_array[20];
int xx;
for (xx = 0; xx < 20; xx++) {
x_array[xx] = 20 - xx;
} // Initialize x_array to 20, 19, 18,... 2, 1
-
+
// Declare a pointer of type int and initialize it to point to x_array
int* x_ptr = x_array;
// x_ptr now points to the first element in the array (the integer 20).
@@ -342,50 +321,52 @@ int main() {
// it decays into (implicitly converted to) a pointer.
// Exceptions: when the array is the argument of the `&` (address-od) operator:
int arr[10];
- int (*ptr_to_arr)[10] = &arr; // &arr is NOT of type `int *`! It's of type "pointer to array" (of ten `int`s).
+ int (*ptr_to_arr)[10] = &arr; // &arr is NOT of type `int *`!
+ // It's of type "pointer to array" (of ten `int`s).
// or when the array is a string literal used for initializing a char array:
char arr[] = "foobarbazquirk";
// or when it's the argument of the `sizeof` or `alignof` operator:
int arr[10];
int *ptr = arr; // equivalent with int *ptr = &arr[0];
printf("%zu %zu\n", sizeof arr, sizeof ptr); // probably prints "40, 4" or "40, 8"
-
+
// Pointers are incremented and decremented based on their type
// (this is called pointer arithmetic)
printf("%d\n", *(x_ptr + 1)); // => Prints 19
printf("%d\n", x_array[1]); // => Prints 19
-
+
// You can also dynamically allocate contiguous blocks of memory with the
// standard library function malloc, which takes one argument of type size_t
// representing the number of bytes to allocate (usually from the heap, although this
// may not be true on e. g. embedded systems - the C standard says nothing about it).
int *my_ptr = malloc(sizeof(*my_ptr) * 20);
for (xx = 0; xx < 20; xx++) {
- *(my_ptr + xx) = 20 - xx; // my_ptr[xx] = 20-xx would also work here, and it's also more readable
+ *(my_ptr + xx) = 20 - xx; // my_ptr[xx] = 20-xx
} // Initialize memory to 20, 19, 18, 17... 2, 1 (as ints)
-
+
// Dereferencing memory that you haven't allocated gives
// "unpredictable results" - the program is said to invoke "undefined behavior"
printf("%d\n", *(my_ptr + 21)); // => Prints who-knows-what? It may even crash.
-
+
// When you're done with a malloc'd block of memory, you need to free it,
// or else no one else can use it until your program terminates
// (this is called a "memory leak"):
free(my_ptr);
-
+
// Strings are arrays of char, but they are usually represented as a
// pointer-to-char (which is a pointer to the first element of the array).
// It's good practice to use `const char *' when referring to a string literal,
// since string literals shall not be modified (i. e. "foo"[0] = 'a' is ILLEGAL.)
const char *my_str = "This is my very own string literal";
printf("%c\n", *my_str); // => 'T'
-
- // This is not the case if the string is an array (potentially initialized with a string literal)
+
+ // This is not the case if the string is an array
+ // (potentially initialized with a string literal)
// that resides in writable memory, as in:
char foo[] = "foo";
foo[0] = 'a'; // this is legal, foo now contains "aoo"
-
+
function_1();
} // end main function
@@ -435,17 +416,17 @@ printf("%s\n", c); // => ".tset a si sihT"
typedef int my_type;
my_type my_type_var = 0;
-// Structs are just collections of data, the members are allocated sequentially, in the order they are written:
+// Structs are just collections of data, the members are allocated sequentially,
+// in the order they are written:
struct rectangle {
int width;
int height;
};
-// it's generally not true that sizeof(struct rectangle) == sizeof(int) + sizeof(int) due to
-// potential padding between the structure members (this is for alignment reasons. Probably won't
-// happen if all members are of the same type, but watch out!
-// See http://stackoverflow.com/questions/119123/why-isnt-sizeof-for-a-struct-equal-to-the-sum-of-sizeof-of-each-member
-// for further information.
+// It's not generally true that
+// sizeof(struct rectangle) == sizeof(int) + sizeof(int)
+// due to potential padding between the structure members (this is for alignment
+// reasons). [1]
void function_1()
{
@@ -473,7 +454,8 @@ int area(rect r)
return r.width * r.height;
}
-// if you have large structs, you can pass them "by pointer" to avoid copying the whole struct:
+// if you have large structs, you can pass them "by pointer" to avoid copying
+// the whole struct:
int area(const rect *r)
{
return r->width * r->height;
@@ -527,3 +509,5 @@ Readable code is better than clever code and fast code. For a good, sane coding
[Linux kernel coding stlye](https://www.kernel.org/doc/Documentation/CodingStyle).
Other than that, Google is your friend.
+
+[1] http://stackoverflow.com/questions/119123/why-isnt-sizeof-for-a-struct-equal-to-the-sum-of-sizeof-of-each-member
diff --git a/go.html.markdown b/go.html.markdown
index e7b35926..4db76a49 100644
--- a/go.html.markdown
+++ b/go.html.markdown
@@ -18,7 +18,7 @@ help with large-scale programming.
Go comes with a great standard library and an enthusiastic community.
-```Go
+```go
// Single line comment
/* Multi-
line comment */
@@ -29,260 +29,260 @@ package main
// Import declaration declares library packages referenced in this file.
import (
- "fmt" // A package in the Go standard library
- "net/http" // Yes, a web server!
- "strconv" // String conversions
+ "fmt" // A package in the Go standard library
+ "net/http" // Yes, a web server!
+ "strconv" // String conversions
)
// A function definition. Main is special. It is the entry point for the
// executable program. Love it or hate it, Go uses brace brackets.
func main() {
- // Println outputs a line to stdout.
- // Qualify it with the package name, fmt.
- fmt.Println("Hello world!")
+ // Println outputs a line to stdout.
+ // Qualify it with the package name, fmt.
+ fmt.Println("Hello world!")
- // Call another function within this package.
- beyondHello()
+ // Call another function within this package.
+ beyondHello()
}
// Functions have parameters in parentheses.
// If there are no parameters, empty parens are still required.
func beyondHello() {
- var x int // Variable declaration. Variables must be declared before use.
- x = 3 // Variable assignment.
- // "Short" declarations use := to infer the type, declare, and assign.
- y := 4
- sum, prod := learnMultiple(x, y) // function returns two values
- fmt.Println("sum:", sum, "prod:", prod) // simple output
- learnTypes() // < y minutes, learn more!
+ var x int // Variable declaration. Variables must be declared before use.
+ x = 3 // Variable assignment.
+ // "Short" declarations use := to infer the type, declare, and assign.
+ y := 4
+ sum, prod := learnMultiple(x, y) // function returns two values
+ fmt.Println("sum:", sum, "prod:", prod) // simple output
+ learnTypes() // < y minutes, learn more!
}
// Functions can have parameters and (multiple!) return values.
func learnMultiple(x, y int) (sum, prod int) {
- return x + y, x * y // return two values
+ return x + y, x * y // return two values
}
// Some built-in types and literals.
func learnTypes() {
- // Short declaration usually gives you what you want.
- s := "Learn Go!" // string type
+ // Short declaration usually gives you what you want.
+ s := "Learn Go!" // string type
- s2 := `A "raw" string literal
+ s2 := `A "raw" string literal
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
+ // non-ASCII literal. Go source is UTF-8.
+ g := 'Σ' // rune type, an alias for uint32, holds a UTF-8 code point
- f := 3.14195 // float64, an IEEE-754 64-bit floating point number
- c := 3 + 4i // complex128, represented internally with two float64s
+ f := 3.14195 // float64, an IEEE-754 64-bit floating point number
+ c := 3 + 4i // complex128, represented internally with two float64s
- // Var syntax with an initializers.
- var u uint = 7 // unsigned, but implementation dependent size as with int
- var pi float32 = 22. / 7
+ // Var syntax with an initializers.
+ var u uint = 7 // unsigned, but implementation dependent size as with int
+ var pi float32 = 22. / 7
- // Conversion syntax with a short declaration.
- n := byte('\n') // byte is an alias for uint8
+ // Conversion syntax with a short declaration.
+ n := byte('\n') // byte is an alias for uint8
- // Arrays have size fixed at compile time.
- var a4 [4]int // an array of 4 ints, initialized to all 0
- a3 := [...]int{3, 1, 5} // an array of 3 ints, initialized as shown
+ // Arrays have size fixed at compile time.
+ var a4 [4]int // an array of 4 ints, initialized to all 0
+ a3 := [...]int{3, 1, 5} // an array of 3 ints, initialized as shown
- // Slices have dynamic size. Arrays and slices each have advantages
- // but use cases for slices are much more common.
- s3 := []int{4, 5, 9} // compare to a3. no ellipsis here
- s4 := make([]int, 4) // allocates slice of 4 ints, initialized to all 0
- var d2 [][]float64 // declaration only, nothing allocated here
- bs := []byte("a slice") // type conversion syntax
+ // Slices have dynamic size. Arrays and slices each have advantages
+ // but use cases for slices are much more common.
+ s3 := []int{4, 5, 9} // compare to a3. no ellipsis here
+ s4 := make([]int, 4) // allocates slice of 4 ints, initialized to all 0
+ var d2 [][]float64 // declaration only, nothing allocated here
+ bs := []byte("a slice") // type conversion syntax
- p, q := learnMemory() // declares p, q to be type pointer to int.
- fmt.Println(*p, *q) // * follows a pointer. This prints two ints.
+ p, q := learnMemory() // declares p, q to be type pointer to int.
+ fmt.Println(*p, *q) // * follows a pointer. This prints two ints.
- // Maps are a dynamically growable associative array type, like the
- // hash or dictionary types of some other languages.
- m := map[string]int{"three": 3, "four": 4}
- m["one"] = 1
+ // Maps are a dynamically growable associative array type, like the
+ // hash or dictionary types of some other languages.
+ m := map[string]int{"three": 3, "four": 4}
+ m["one"] = 1
- // Unused variables are an error in Go.
- // The underbar lets you "use" a variable but discard its value.
- _, _, _, _, _, _, _, _, _ = s2, g, f, u, pi, n, a3, s4, bs
- // Output of course counts as using a variable.
- fmt.Println(s, c, a4, s3, d2, m)
+ // Unused variables are an error in Go.
+ // The underbar lets you "use" a variable but discard its value.
+ _, _, _, _, _, _, _, _, _ = s2, g, f, u, pi, n, a3, s4, bs
+ // Output of course counts as using a variable.
+ fmt.Println(s, c, a4, s3, d2, m)
- learnFlowControl() // back in the flow
+ learnFlowControl() // back in the flow
}
// Go is fully garbage collected. It has pointers but no pointer arithmetic.
// You can make a mistake with a nil pointer, but not by incrementing a pointer.
func learnMemory() (p, q *int) {
- // Named return values p and q have type pointer to int.
- p = new(int) // built-in function new allocates memory.
- // The allocated int is initialized to 0, p is no longer nil.
- s := make([]int, 20) // allocate 20 ints as a single block of memory
- s[3] = 7 // assign one of them
- r := -2 // declare another local variable
- return &s[3], &r // & takes the address of an object.
+ // Named return values p and q have type pointer to int.
+ p = new(int) // built-in function new allocates memory.
+ // The allocated int is initialized to 0, p is no longer nil.
+ s := make([]int, 20) // allocate 20 ints as a single block of memory
+ s[3] = 7 // assign one of them
+ r := -2 // declare another local variable
+ return &s[3], &r // & takes the address of an object.
}
func expensiveComputation() int {
- return 1e6
+ return 1e6
}
func learnFlowControl() {
- // If statements require brace brackets, and do not require parens.
- if true {
- fmt.Println("told ya")
- }
- // Formatting is standardized by the command line command "go fmt."
- if false {
- // pout
- } else {
- // gloat
- }
- // Use switch in preference to chained if statements.
- x := 1
- switch x {
- case 0:
- case 1:
- // cases don't "fall through"
- case 2:
- // unreached
- }
- // Like if, for doesn't use parens either.
- for x := 0; x < 3; x++ { // ++ is a statement
- fmt.Println("iteration", x)
- }
- // x == 1 here.
-
- // For is the only loop statement in Go, but it has alternate forms.
- for { // infinite loop
- break // just kidding
- continue // unreached
- }
- // As with for, := in an if statement means to declare and assign y first,
- // then test y > x.
- if y := expensiveComputation(); y > x {
- x = y
- }
- // Function literals are closures.
- xBig := func() bool {
- return x > 100 // references x declared above switch statement.
- }
- fmt.Println("xBig:", xBig()) // true (we last assigned 1e6 to x)
- x /= 1e5 // this makes it == 10
- fmt.Println("xBig:", xBig()) // false now
-
- // When you need it, you'll love it.
- goto love
+ // If statements require brace brackets, and do not require parens.
+ if true {
+ fmt.Println("told ya")
+ }
+ // Formatting is standardized by the command line command "go fmt."
+ if false {
+ // pout
+ } else {
+ // gloat
+ }
+ // Use switch in preference to chained if statements.
+ x := 1
+ switch x {
+ case 0:
+ case 1:
+ // cases don't "fall through"
+ case 2:
+ // unreached
+ }
+ // Like if, for doesn't use parens either.
+ for x := 0; x < 3; x++ { // ++ is a statement
+ fmt.Println("iteration", x)
+ }
+ // x == 1 here.
+
+ // For is the only loop statement in Go, but it has alternate forms.
+ for { // infinite loop
+ break // just kidding
+ continue // unreached
+ }
+ // As with for, := in an if statement means to declare and assign y first,
+ // then test y > x.
+ if y := expensiveComputation(); y > x {
+ x = y
+ }
+ // Function literals are closures.
+ xBig := func() bool {
+ return x > 100 // references x declared above switch statement.
+ }
+ fmt.Println("xBig:", xBig()) // true (we last assigned 1e6 to x)
+ x /= 1e5 // this makes it == 10
+ fmt.Println("xBig:", xBig()) // false now
+
+ // When you need it, you'll love it.
+ goto love
love:
- learnInterfaces() // Good stuff coming up!
+ learnInterfaces() // Good stuff coming up!
}
// Define Stringer as an interface type with one method, String.
type Stringer interface {
- String() string
+ String() string
}
// Define pair as a struct with two fields, ints named x and y.
type pair struct {
- x, y int
+ x, y int
}
// Define a method on type pair. Pair now implements Stringer.
func (p pair) String() string { // p is called the "receiver"
- // Sprintf is another public function in package fmt.
- // Dot syntax references fields of p.
- return fmt.Sprintf("(%d, %d)", p.x, p.y)
+ // Sprintf is another public function in package fmt.
+ // Dot syntax references fields of p.
+ return fmt.Sprintf("(%d, %d)", p.x, p.y)
}
func learnInterfaces() {
- // Brace syntax is a "struct literal." It evaluates to an initialized
- // struct. The := syntax declares and initializes p to this struct.
- p := pair{3, 4}
- fmt.Println(p.String()) // call String method of p, of type pair.
- var i Stringer // declare i of interface type Stringer.
- i = p // valid because pair implements Stringer
- // Call String method of i, of type Stringer. Output same as above.
- fmt.Println(i.String())
-
- // Functions in the fmt package call the String method to ask an object
- // for a printable representation of itself.
- fmt.Println(p) // output same as above. Println calls String method.
- fmt.Println(i) // output same as above
-
- learnErrorHandling()
+ // Brace syntax is a "struct literal." It evaluates to an initialized
+ // struct. The := syntax declares and initializes p to this struct.
+ p := pair{3, 4}
+ fmt.Println(p.String()) // call String method of p, of type pair.
+ var i Stringer // declare i of interface type Stringer.
+ i = p // valid because pair implements Stringer
+ // Call String method of i, of type Stringer. Output same as above.
+ fmt.Println(i.String())
+
+ // Functions in the fmt package call the String method to ask an object
+ // for a printable representation of itself.
+ fmt.Println(p) // output same as above. Println calls String method.
+ fmt.Println(i) // output same as above
+
+ learnErrorHandling()
}
func learnErrorHandling() {
- // ", ok" idiom used to tell if something worked or not.
- m := map[int]string{3: "three", 4: "four"}
- if x, ok := m[1]; !ok { // ok will be false because 1 is not in the map.
- fmt.Println("no one there")
- } else {
- fmt.Print(x) // x would be the value, if it were in the map.
- }
- // An error value communicates not just "ok" but more about the problem.
- if _, err := strconv.Atoi("non-int"); err != nil { // _ discards value
- // prints "strconv.ParseInt: parsing "non-int": invalid syntax"
- fmt.Println(err)
- }
- // We'll revisit interfaces a little later. Meanwhile,
- learnConcurrency()
+ // ", ok" idiom used to tell if something worked or not.
+ m := map[int]string{3: "three", 4: "four"}
+ if x, ok := m[1]; !ok { // ok will be false because 1 is not in the map.
+ fmt.Println("no one there")
+ } else {
+ fmt.Print(x) // x would be the value, if it were in the map.
+ }
+ // An error value communicates not just "ok" but more about the problem.
+ if _, err := strconv.Atoi("non-int"); err != nil { // _ discards value
+ // prints "strconv.ParseInt: parsing "non-int": invalid syntax"
+ fmt.Println(err)
+ }
+ // We'll revisit interfaces a little later. Meanwhile,
+ learnConcurrency()
}
// c is a channel, a concurrency-safe communication object.
func inc(i int, c chan int) {
- c <- i + 1 // <- is the "send" operator when a channel appears on the left.
+ c <- i + 1 // <- is the "send" operator when a channel appears on the left.
}
// We'll use inc to increment some numbers concurrently.
func learnConcurrency() {
- // Same make function used earlier to make a slice. Make allocates and
- // initializes slices, maps, and channels.
- c := make(chan int)
- // Start three concurrent goroutines. Numbers will be incremented
- // concurrently, perhaps in parallel if the machine is capable and
- // properly configured. All three send to the same channel.
- go inc(0, c) // go is a statement that starts a new goroutine.
- go inc(10, c)
- go inc(-805, c)
- // Read three results from the channel and print them out.
- // There is no telling in what order the results will arrive!
- 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.
- 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
- // a channel operation. It selects a case at random out of the cases
- // that are ready to communicate.
- select {
- case i := <-c: // the value received can be assigned to a variable
- fmt.Println("it's a", i)
- case <-cs: // or the value received can be discarded
- fmt.Println("it's a string")
- case <-cc: // empty channel, not ready for communication.
- fmt.Println("didn't happen.")
- }
- // At this point a value was taken from either c or cs. One of the two
- // goroutines started above has completed, the other will remain blocked.
-
- learnWebProgramming() // Go does it. You want to do it too.
+ // Same make function used earlier to make a slice. Make allocates and
+ // initializes slices, maps, and channels.
+ c := make(chan int)
+ // Start three concurrent goroutines. Numbers will be incremented
+ // concurrently, perhaps in parallel if the machine is capable and
+ // properly configured. All three send to the same channel.
+ go inc(0, c) // go is a statement that starts a new goroutine.
+ go inc(10, c)
+ go inc(-805, c)
+ // Read three results from the channel and print them out.
+ // There is no telling in what order the results will arrive!
+ 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.
+ 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
+ // a channel operation. It selects a case at random out of the cases
+ // that are ready to communicate.
+ select {
+ case i := <-c: // the value received can be assigned to a variable
+ fmt.Println("it's a", i)
+ case <-cs: // or the value received can be discarded
+ fmt.Println("it's a string")
+ case <-cc: // empty channel, not ready for communication.
+ fmt.Println("didn't happen.")
+ }
+ // At this point a value was taken from either c or cs. One of the two
+ // goroutines started above has completed, the other will remain blocked.
+
+ learnWebProgramming() // Go does it. You want to do it too.
}
// A single function from package http starts a web server.
func learnWebProgramming() {
- // ListenAndServe first parameter is TCP address to listen at.
- // Second parameter is an interface, specifically http.Handler.
- err := http.ListenAndServe(":8080", pair{})
- fmt.Println(err) // don't ignore errors
+ // ListenAndServe first parameter is TCP address to listen at.
+ // Second parameter is an interface, specifically http.Handler.
+ err := http.ListenAndServe(":8080", pair{})
+ fmt.Println(err) // don't ignore errors
}
// Make pair an http.Handler by implementing its only method, ServeHTTP.
func (p pair) ServeHTTP(w http.ResponseWriter, r *http.Request) {
- // Serve data with a method of http.ResponseWriter
- w.Write([]byte("You learned Go in Y minutes!"))
+ // Serve data with a method of http.ResponseWriter
+ w.Write([]byte("You learned Go in Y minutes!"))
}
```
diff --git a/ko-kr/java-kr.html.markdown b/ko-kr/java-kr.html.markdown
index dcca9b2e..371b4665 100644
--- a/ko-kr/java-kr.html.markdown
+++ b/ko-kr/java-kr.html.markdown
@@ -1,5 +1,6 @@
---
language: java
+filename: java-kr.java
category: language
contributors:
- ["Jake Prather", "http://github.com/JakeHP"]
@@ -26,7 +27,8 @@ import java.util.ArrayList;
// java.security 패키지 안에 있는 모든 클래스를 임포트합니다.
import java.security.*;
-// 각 .java 파일에는 공용(public) 클래스가 들어 있으며, 클래스의 이름은 파일명과 동일합니다.
+// 각 .java 파일에는 공용(public) 클래스가 들어 있으며, 클래스의 이름은
+// 파일명과 동일합니다.
public class LearnJava {
// 프로그램에는 반드시 진입점 역할을 하는 main 메서드가 하나 있어야 합니다.
@@ -253,8 +255,8 @@ public class LearnJava {
// String
// 형변환
- // 자바 객채 또한 형변환할 수 있으며, 이와 관련해서 알아야 할 세부사항이 많을뿐더러
- // 다소 중급 수준에 해당하는 개념들도 다뤄야 합니다.
+ // 자바 객채 또한 형변환할 수 있으며, 이와 관련해서 알아야 할 세부사항이
+ // 많을뿐더러 다소 중급 수준에 해당하는 개념들도 다뤄야 합니다.
// 이와 관련된 사항은 아래 링크를 참고하세요.
// http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html
@@ -403,4 +405,4 @@ class PennyFarthing extends Bicycle {
* [제네릭(Generics)](http://docs.oracle.com/javase/tutorial/java/generics/index.html)
-* [자바 코딩 관례(Java Code Conventions)](http://www.oracle.com/technetwork/java/codeconv-138413.html) \ No newline at end of file
+* [자바 코딩 관례(Java Code Conventions)](http://www.oracle.com/technetwork/java/codeconv-138413.html)
diff --git a/pt-br/elisp-pt.html.markdown b/pt-br/elisp-pt.html.markdown
index 9031cad9..fc2d1e40 100644
--- a/pt-br/elisp-pt.html.markdown
+++ b/pt-br/elisp-pt.html.markdown
@@ -4,7 +4,7 @@ contributors:
- ["Bastien Guerry", "http://bzg.fr"]
translators:
- ["Lucas Tadeu Teixeira", "http://ltt.me"]
-lang: pt-br
+lang: pt-br
filename: learn-emacs-lisp-pt.el
---
@@ -30,9 +30,9 @@ filename: learn-emacs-lisp-pt.el
;; Realizar este tutorial não danificará seu computador, a menos
;; que você fique tão irritado a ponto de jogá-lo no chão. Neste caso,
;; me abstenho de qualquer responsabilidade. Divirta-se!
-
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;
+;;
;; Abra o Emacs.
;;
;; Aperte a tecla `q' para ocultar a mensagem de boas vindas.
@@ -45,11 +45,11 @@ filename: learn-emacs-lisp-pt.el
;; O buffer de rascunho (i.e., "scratch") é o buffer padrão quando
;; o Emacs é aberto. Você nunca está editando arquivos: você está
;; editando buffers que você pode salvar em um arquivo.
-;;
+;;
;; "Lisp interaction" refere-se a um conjunto de comandos disponíveis aqui.
-;;
-;; O Emacs possui um conjunto de comandos embutidos (disponíveis em
-;; qualquer buffer) e vários subconjuntos de comandos disponíveis
+;;
+;; O Emacs possui um conjunto de comandos embutidos (disponíveis em
+;; qualquer buffer) e vários subconjuntos de comandos disponíveis
;; quando você ativa um modo específico. Aqui nós utilizamos
;; `lisp-interaction-mode', que possui comandos para interpretar e navegar
;; em código Elisp.
@@ -137,7 +137,7 @@ filename: learn-emacs-lisp-pt.el
;; => [a tela exibirá duas janelas e o cursor estará no buffer *test*]
;; Posicione o mouse sobre a janela superior e clique com o botão
-;; esquerdo para voltar. Ou você pode utilizar `C-xo' (i.e. segure
+;; esquerdo para voltar. Ou você pode utilizar `C-xo' (i.e. segure
;; ctrl-x e aperte o) para voltar para a outra janela, de forma interativa.
;; Você pode combinar várias "sexps" com `progn':
diff --git a/pt-br/ruby-pt.html.markdown b/pt-br/ruby-pt.html.markdown
index 8e8ce6a8..484bb0dd 100644
--- a/pt-br/ruby-pt.html.markdown
+++ b/pt-br/ruby-pt.html.markdown
@@ -1,5 +1,6 @@
---
language: ruby
+lang: br-pt
filename: learnruby.rb
contributors:
- ["Bruno Henrique - Garu", "http://garulab.com"]
@@ -98,9 +99,10 @@ caminho_para_a_raiz_do_projeto = '/bom/nome/'
caminho = '/nome/ruim/'
# Símbolos (são objetos)
-# Símbolos são imutáveis, são constantes reutilizáveis representadadas internamente por um
-# valor inteiro. Eles são frequentemente usados no lugar de strings para transmitir com eficiência os valores
-# específicos e significativos
+# Símbolos são imutáveis, são constantes reutilizáveis representadadas
+# internamente por um valor inteiro. Eles são frequentemente usados no
+# lugar de strings para transmitir com eficiência os valores específicos
+# e significativos
:pendente.class #=> Symbol
diff --git a/ru-ru/clojure-ru.html.markdown b/ru-ru/clojure-ru.html.markdown
index 48c16192..e1d68e5a 100644
--- a/ru-ru/clojure-ru.html.markdown
+++ b/ru-ru/clojure-ru.html.markdown
@@ -4,7 +4,7 @@ filename: learnclojure-ru.clj
contributors:
- ["Adam Bard", "http://adambard.com/"]
- ["Alexey Pirogov", "http://twitter.com/alex_pir"]
-
+lang: ru-ru
---
Clojure, это представитель семейства Lisp-подобных языков, разработанный
diff --git a/ru-ru/php-ru.html.markdown b/ru-ru/php-ru.html.markdown
index 6c5720e3..9133ecca 100644
--- a/ru-ru/php-ru.html.markdown
+++ b/ru-ru/php-ru.html.markdown
@@ -88,7 +88,8 @@ $unescaped = 'This just contains a slash and a t: \t';
// Заключайте переменные в фигурные скобки если это необходимо
$money = "I have $${number} in the bank.";
-// Начиная с PHP 5.3, синтаксис nowdocs может использоваться для неинтерполированного многострочного текста
+// Начиная с PHP 5.3, синтаксис nowdocs может использоваться для
+// неинтерполированного многострочного текста
$nowdoc = <<<'END'
Multi line
string
@@ -210,11 +211,13 @@ echo $integer + $integer; // => 2
$string = '1';
echo $string + $string; // => 2 (строка превращается в число)
-// Выводится 0 по той причине, что оператор + не может привести строку 'one' к числовому типу
+// Выводится 0 по той причине, что оператор + не может привести строку 'one' к
+// числовому типу
$string = 'one';
echo $string + $string; // => 0
-// Приведение типов (type casting) может быть использовано для преобразование переменной в другой тип
+// Приведение типов (type casting) может быть использовано для преобразование
+// переменной в другой тип
$boolean = (boolean) 1; // => true
$zero = 0;
@@ -429,10 +432,11 @@ return 'Anything you like.';
// Эти функции могут также возвращать значения.
$value = include 'my-include.php';
-// Имена файлов содержат их путь в файловой системе, или если передано просто имя файла,
-// PHP обращается к директиве include_path. Если файл не найден в include_path, предпринимается
-// попытка поиска в папке, где выполняется скрипт или в текущей рабочей директории.
-// Если не в одном из этих мест файл не найден - выдается ошибка
+// Имена файлов содержат их путь в файловой системе, или если передано просто
+// имя файла, PHP обращается к директиве include_path. Если файл не найден в
+// include_path, предпринимается попытка поиска в папке, где выполняется скрипт
+// или в текущей рабочей директории. Если не в одном из этих мест файл не
+// найден - выдается ошибка
/* */
/********************************
diff --git a/ru-ru/python-ru.html.markdown b/ru-ru/python-ru.html.markdown
index 58b0adcc..9163c8aa 100644
--- a/ru-ru/python-ru.html.markdown
+++ b/ru-ru/python-ru.html.markdown
@@ -1,5 +1,6 @@
---
language: python
+lang: ru-ru
contributors:
- ["Yury Timofeev", "http://twitter.com/gagar1n"]
filename: learnpython-ru.py
@@ -219,7 +220,8 @@ filled_dict["four"] # KeyError
# Чтобы избежать этого, используйте метод get
filled_dict.get("one") #=> 1
filled_dict.get("four") #=> None
-# Метод get также принимает аргумент default, значение которого будет возвращено при отсутствии указанного ключа
+# Метод get также принимает аргумент default, значение которого будет
+# возвращено при отсутствии указанного ключа
filled_dict.get("one", 4) #=> 1
filled_dict.get("four", 4) #=> 4
@@ -314,7 +316,9 @@ try:
# Для выбора ошибки используется raise
raise IndexError("Это IndexError")
except IndexError as e:
- pass # pass это просто отсутствие оператора. Обычно здесь происходит восстановление от ошибки.
+ # pass это просто отсутствие оператора. Обычно здесь происходит
+ # восстановление от ошибки.
+ pass
####################################################
diff --git a/zh-cn/go-zh.html.markdown b/zh-cn/go-zh.html.markdown
index 25fd1f03..8f7cb2af 100644
--- a/zh-cn/go-zh.html.markdown
+++ b/zh-cn/go-zh.html.markdown
@@ -29,7 +29,8 @@ import (
"strconv" // 字符串转换
)
-//函数声明:Main是程序执行的入口。不管你喜欢还是不喜欢,反正G就用了花括号来包住函数体。
+// 函数声明:Main是程序执行的入口。
+// 不管你喜欢还是不喜欢,反正G就用了花括号来包住函数体。
func main() {
// 往标准输出打印一行。
// 用包名fmt限制打印函数。
@@ -65,10 +66,10 @@ func learnTypes() {
can include line breaks.` // 同样是String类型
// 非ascii字符。Go使用UTF-8编码。
- g := 'Σ' // rune类型,uint32的别名,使用UTF-8编码
+ g := 'Σ' // rune类型,uint32的别名,使用UTF-8编码
- f := 3.14195 // float64类型,IEEE-754 64位浮点数
- c := 3 + 4i // complex128类型,内部使用两个float64表示
+ f := 3.14195 // float64类型,IEEE-754 64位浮点数
+ c := 3 + 4i // complex128类型,内部使用两个float64表示
// Var变量可以直接初始化。
var u uint = 7 // unsigned 无符号变量,但是实现依赖int型变量的长度
@@ -99,9 +100,9 @@ can include line breaks.` // 同样是String类型
// 下划线 _ 可以使你“使用”一个变量,但是丢弃它的值。
_,_,_,_,_,_,_,_,_ = s2, g, f, u, pi, n, a3, s4, bs
// 输出变量
- fmt.Println(s, c, a4, s3, d2, m)
+ fmt.Println(s, c, a4, s3, d2, m)
- learnFlowControl() // 回到流程控制
+ learnFlowControl() // 回到流程控制
}
// Go全面支持垃圾回收。Go有指针,但是不支持指针运算。
@@ -117,155 +118,159 @@ func learnMemory() (p, q *int) {
}
func expensiveComputation() int {
- return 1e6
+ return 1e6
}
func learnFlowControl() {
// If需要花括号,括号就免了
- if true {
- fmt.Println("told ya")
- }
- // 用go fmt 命令可以帮你格式化代码,所以不用怕被人吐槽代码风格了,也不用容忍被人的代码风格。
- if false {
- // pout
- } else {
- // gloat
- }
+ if true {
+ fmt.Println("told ya")
+ }
+ // 用go fmt 命令可以帮你格式化代码,所以不用怕被人吐槽代码风格了,
+ // 也不用容忍被人的代码风格。
+ if false {
+ // pout
+ } else {
+ // gloat
+ }
// 如果太多嵌套的if语句,推荐使用switch
- x := 1
- switch x {
- case 0:
- case 1:
+ x := 1
+ switch x {
+ case 0:
+ case 1:
// 隐式调用break语句,匹配上一个即停止
- case 2:
+ case 2:
// 不会运行
- }
+ }
// 和if一样,for也不用括号
- for x := 0; x < 3; x++ { // ++ 自增
- fmt.Println("iteration", x)
- }
+ for x := 0; x < 3; x++ { // ++ 自增
+ fmt.Println("iteration", x)
+ }
// x在这里还是1。为什么?
// for 是go里唯一的循环关键字,不过它有很多变种
- for { // 无限循环
- break // 骗你的
- continue // 不会运行的
- }
+ for { // 无限循环
+ break // 骗你的
+ continue // 不会运行的
+ }
// 和for一样,if中的:=先给y赋值,然后再和x作比较。
- if y := expensiveComputation(); y > x {
- x = y
- }
+ if y := expensiveComputation(); y > x {
+ x = y
+ }
// 闭包函数
- xBig := func() bool {
- return x > 100 // x是上面声明的变量引用
- }
- fmt.Println("xBig:", xBig()) // true (上面把y赋给x了)
- x /= 1e5 // x变成10
- fmt.Println("xBig:", xBig()) // 现在是false
+ xBig := func() bool {
+ return x > 100 // x是上面声明的变量引用
+ }
+ fmt.Println("xBig:", xBig()) // true (上面把y赋给x了)
+ x /= 1e5 // x变成10
+ fmt.Println("xBig:", xBig()) // 现在是false
// 当你需要goto的时候,你会爱死它的!
- goto love
+ goto love
love:
- learnInterfaces() // 好东西来了!
+ learnInterfaces() // 好东西来了!
}
// 定义Stringer为一个接口类型,有一个方法String
type Stringer interface {
- String() string
+ String() string
}
// 定义pair为一个结构体,有x和y两个int型变量。
type pair struct {
- x, y int
+ x, y int
}
// 定义pair类型的方法,实现Stringer接口。
func (p pair) String() string { // p被叫做“接收器”
// Sprintf是fmt包中的另一个公有函数。
// 用 . 调用p中的元素。
- return fmt.Sprintf("(%d, %d)", p.x, p.y)
+ return fmt.Sprintf("(%d, %d)", p.x, p.y)
}
func learnInterfaces() {
// 花括号用来定义结构体变量,:=在这里将一个结构体变量赋值给p。
- p := pair{3, 4}
- fmt.Println(p.String()) // 调用pair类型p的String方法
- var i Stringer // 声明i为Stringer接口类型
- i = p // 有效!因为p实现了Stringer接口(类似java中的塑型)
+ p := pair{3, 4}
+ fmt.Println(p.String()) // 调用pair类型p的String方法
+ var i Stringer // 声明i为Stringer接口类型
+ i = p // 有效!因为p实现了Stringer接口(类似java中的塑型)
// 调用i的String方法,输出和上面一样
- fmt.Println(i.String())
+ fmt.Println(i.String())
- // fmt包中的Println函数向对象要它们的string输出,实现了String方法就可以这样使用了。(类似java中的序列化)
- fmt.Println(p) // 输出和上面一样,自动调用String函数。
- fmt.Println(i) // 输出和上面一样。
+ // fmt包中的Println函数向对象要它们的string输出,实现了String方法就可以这样使用了。
+ // (类似java中的序列化)
+ fmt.Println(p) // 输出和上面一样,自动调用String函数。
+ fmt.Println(i) // 输出和上面一样。
- learnErrorHandling()
+ learnErrorHandling()
}
func learnErrorHandling() {
- // ", ok"用来判断有没有正常工作
- m := map[int]string{3: "three", 4: "four"}
- if x, ok := m[1]; !ok { // ok 为false,因为m中没有1
- fmt.Println("no one there")
- } else {
- fmt.Print(x) // 如果x在map中的话,x就是那个值喽。
- }
+ // ", ok"用来判断有没有正常工作
+ m := map[int]string{3: "three", 4: "four"}
+ if x, ok := m[1]; !ok { // ok 为false,因为m中没有1
+ fmt.Println("no one there")
+ } else {
+ fmt.Print(x) // 如果x在map中的话,x就是那个值喽。
+ }
// 错误可不只是ok,它还可以给出关于问题的更多细节。
- if _, err := strconv.Atoi("non-int"); err != nil { // _ discards value
- // 输出"strconv.ParseInt: parsing "non-int": invalid syntax"
- fmt.Println(err)
- }
+ if _, err := strconv.Atoi("non-int"); err != nil { // _ discards value
+ // 输出"strconv.ParseInt: parsing "non-int": invalid syntax"
+ fmt.Println(err)
+ }
// 待会再说接口吧。同时,
- learnConcurrency()
+ learnConcurrency()
}
// c是channel类型,一个并发安全的通信对象。
func inc(i int, c chan int) {
- c <- i + 1 // <-把右边的发送到左边的channel。
+ c <- i + 1 // <-把右边的发送到左边的channel。
}
// 我们将用inc函数来并发地增加一些数字。
func learnConcurrency() {
// 用make来声明一个slice,make会分配和初始化slice,map和channel。
- c := make(chan int)
- // 用go关键字开始三个并发的goroutine,如果机器支持的话,还可能是并行执行。三个都被发送到同一个channel。
- go inc(0, c) // go is a statement that starts a new goroutine.
- go inc(10, c)
- go inc(-805, c)
+ c := make(chan int)
+ // 用go关键字开始三个并发的goroutine,如果机器支持的话,还可能是并行执行。
+ // 三个都被发送到同一个channel。
+ go inc(0, c) // go is a statement that starts a new goroutine.
+ go inc(10, c)
+ go inc(-805, c)
// 从channel中独处结果并打印。
// 打印出什么东西是不可预知的。
- fmt.Println(<-c, <-c, <-c) // channel在右边的时候,<-是接收操作。
-
- cs := make(chan string) // 操作string的channel
- cc := make(chan chan string) // 操作channel的channel
- go func() { c <- 84 }() // 开始一个goroutine来发送一个新的数字
- go func() { cs <- "wordy" }() // 发送给cs
- // Select类似于switch,但是每个case包括一个channel操作。它随机选择一个准备好通讯的case。
- select {
- case i := <-c: // 从channel接收的值可以赋给其他变量
- fmt.Println("it's a", i)
- case <-cs: // 或者直接丢弃
- fmt.Println("it's a string")
- case <-cc: // 空的,还没作好通讯的准备
- fmt.Println("didn't happen.")
- }
+ fmt.Println(<-c, <-c, <-c) // channel在右边的时候,<-是接收操作。
+
+ cs := make(chan string) // 操作string的channel
+ cc := make(chan chan string) // 操作channel的channel
+ go func() { c <- 84 }() // 开始一个goroutine来发送一个新的数字
+ go func() { cs <- "wordy" }() // 发送给cs
+ // Select类似于switch,但是每个case包括一个channel操作。
+ // 它随机选择一个准备好通讯的case。
+ select {
+ case i := <-c: // 从channel接收的值可以赋给其他变量
+ fmt.Println("it's a", i)
+ case <-cs: // 或者直接丢弃
+ fmt.Println("it's a string")
+ case <-cc: // 空的,还没作好通讯的准备
+ fmt.Println("didn't happen.")
+ }
// 上面c或者cs的值被取到,其中一个goroutine结束,另外一个保持阻塞。
- learnWebProgramming() // Go很适合web编程,我知道你也想学!
+ learnWebProgramming() // Go很适合web编程,我知道你也想学!
}
// http包中的一个简单的函数就可以开启web服务器。
func learnWebProgramming() {
// ListenAndServe第一个参数指定了监听端口,第二个参数是一个接口,特定是http.Handler。
- err := http.ListenAndServe(":8080", pair{})
- fmt.Println(err) // 不要无视错误。
+ err := http.ListenAndServe(":8080", pair{})
+ fmt.Println(err) // 不要无视错误。
}
// 使pair实现http.Handler接口的ServeHTTP方法。
func (p pair) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// 使用http.ResponseWriter返回数据
- w.Write([]byte("You learned Go in Y minutes!"))
+ w.Write([]byte("You learned Go in Y minutes!"))
}
```