Format and remove en/02.3.md spaces

This commit is contained in:
vCaesar
2017-06-30 23:55:28 +08:00
parent 7c350f5876
commit 2859b37818
2 changed files with 181 additions and 180 deletions

View File

@@ -124,9 +124,9 @@ We just talked about how Go uses the UTF-8 character set. Strings are represente
var frenchHello string // basic form to define string
var emptyString string = "" // define a string with empty string
func test() {
no, yes, maybe := "no", "yes", "maybe" // brief statement
japaneseHello := "Ohaiou"
frenchHello = "Bonjour" // basic form of assign values
no, yes, maybe := "no", "yes", "maybe" // brief statement
japaneseHello := "Ohaiou"
frenchHello = "Bonjour" // basic form of assign values
}
```
It's impossible to change string values by index. You will get errors when you compile the following code.
@@ -168,7 +168,7 @@ Go has one `error` type for purpose of dealing with error messages. There is als
```Go
err := errors.New("emit macho dwarf: elf header corrupted")
if err != nil {
fmt.Print(err)
fmt.Print(err)
}
```
### Underlying data structure
@@ -201,20 +201,20 @@ var prefix string
Group form.
```Go
import(
"fmt"
"os"
"fmt"
"os"
)
const(
i = 100
pi = 3.1415
prefix = "Go_"
i = 100
pi = 3.1415
prefix = "Go_"
)
var(
i int
pi float32
prefix string
i int
pi float32
prefix string
)
```
Unless you assign the value of constant is `iota`, the first value of constant in the group `const()` will be `0`. If following constants don't assign values explicitly, their values will be the same as the last one. If the value of last constant is `iota`, the values of following constants which are not assigned are `iota` also.
@@ -224,11 +224,11 @@ Unless you assign the value of constant is `iota`, the first value of constant i
Go has one keyword called `iota`, this keyword is to make `enum`, it begins with `0`, increased by `1`.
```Go
const(
x = iota // x == 0
y = iota // y == 1
z = iota // z == 2
w // If there is no expression after the constants name, it uses the last expression,
//so it's saying w = iota implicitly. Therefore w == 3, and y and z both can omit "= iota" as well.
x = iota // x == 0
y = iota // y == 1
z = iota // z == 2
w // If there is no expression after the constants name, it uses the last expression,
//so it's saying w = iota implicitly. Therefore w == 3, and y and z both can omit "= iota" as well.
)
const v = iota // once iota meets keyword `const`, it resets to `0`, so v = 0.
@@ -363,8 +363,8 @@ For instance, in the case of `aSlice` and `bSlice` above, if you change the valu
- The length of `slice`.
- Capacity, the length from start index to end index of `slice`.
```Go
Array_a := [10]byte{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'}
Slice_a := Array_a[2:5]
Array_a := [10]byte{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'}
Slice_a := Array_a[2:5]
```
The underlying data structure of the code above as follows.
@@ -419,9 +419,9 @@ rating := map[string]float32 {"C":5, "Go":4.5, "Python":4.5, "C++":2 }
//exist'ok' returns false. It returns true otherwise.
csharpRating, ok := rating["C#"]
if ok {
fmt.Println("C# is in the map and its rating is ", csharpRating)
fmt.Println("C# is in the map and its rating is ", csharpRating)
} else {
fmt.Println("We have no rating associated with C# in the map")
fmt.Println("We have no rating associated with C# in the map")
}
delete(rating, "C") // delete element with key "c"

View File

@@ -12,45 +12,45 @@ The greatest invention in programming is flow control. Because of them, you are
`if` doesn't need parentheses in Go.
```Go
if x > 10 {
fmt.Println("x is greater than 10")
} else {
fmt.Println("x is less than or equal to 10")
}
if x > 10 {
fmt.Println("x is greater than 10")
} else {
fmt.Println("x is less than or equal to 10")
}
```
The most useful thing concerning `if` in Go is that it can have one initialization statement before the conditional statement. The scope of the variables defined in this initialization statement are only available inside the block of the defining `if`.
```Go
// initialize x, then check if x greater than
if x := computedValue(); x > 10 {
fmt.Println("x is greater than 10")
} else {
fmt.Println("x is less than 10")
}
// initialize x, then check if x greater than
if x := computedValue(); x > 10 {
fmt.Println("x is greater than 10")
} else {
fmt.Println("x is less than 10")
}
// the following code will not compile
fmt.Println(x)
// the following code will not compile
fmt.Println(x)
```
Use if-else for multiple conditions.
```Go
if integer == 3 {
fmt.Println("The integer is equal to 3")
} else if integer < 3 {
fmt.Println("The integer is less than 3")
} else {
fmt.Println("The integer is greater than 3")
}
if integer == 3 {
fmt.Println("The integer is equal to 3")
} else if integer < 3 {
fmt.Println("The integer is less than 3")
} else {
fmt.Println("The integer is greater than 3")
}
```
### goto
Go has a `goto` keyword, but be careful when you use it. `goto` reroutes the control flow to a previously defined `label` within the body of same code block.
```Go
func myFunc() {
i := 0
Here: // label ends with ":"
fmt.Println(i)
i++
goto Here // jump to label "Here"
}
func myFunc() {
i := 0
Here: // label ends with ":"
fmt.Println(i)
i++
goto Here // jump to label "Here"
}
```
The label name is case sensitive.
@@ -58,134 +58,135 @@ The label name is case sensitive.
`for` is the most powerful control logic in Go. It can read data in loops and iterative operations, just like `while`.
```Go
for expression1; expression2; expression3 {
//...
}
for expression1; expression2; expression3 {
//...
}
```
`expression1`, `expression2` and `expression3` are all expressions, where `expression1` and `expression3` are variable definitions or return values from functions, and `expression2` is a conditional statement. `expression1` will be executed once before looping, and `expression3` will be executed after each loop.
Examples are more useful than words.
```Go
package main
import "fmt"
package main
func main(){
sum := 0;
for index:=0; index < 10 ; index++ {
sum += index
}
fmt.Println("sum is equal to ", sum)
}
// Printsum is equal to 45
import "fmt"
func main(){
sum := 0;
for index:=0; index < 10 ; index++ {
sum += index
}
fmt.Println("sum is equal to ", sum)
}
// Printsum is equal to 45
```
Sometimes we need multiple assignments, but Go doesn't have the `,` operator, so we use parallel assignment like `i, j = i + 1, j - 1`.
We can omit `expression1` and `expression3` if they are not necessary.
```Go
sum := 1
for ; sum < 1000; {
sum += sum
}
sum := 1
for ; sum < 1000; {
sum += sum
}
```
Omit `;` as well. Feel familiar? Yes, it's identical to `while`.
```Go
sum := 1
for sum < 1000 {
sum += sum
}
sum := 1
for sum < 1000 {
sum += sum
}
```
There are two important operations in loops which are `break` and `continue`. `break` jumps out of the loop, and `continue` skips the current loop and starts the next one. If you have nested loops, use `break` along with labels.
```Go
for index := 10; index>0; index-- {
if index == 5{
break // or continue
}
fmt.Println(index)
}
// break prints 10、9、8、7、6
// continue prints 10、9、8、7、6、4、3、2、1
for index := 10; index>0; index-- {
if index == 5{
break // or continue
}
fmt.Println(index)
}
// break prints 10、9、8、7、6
// continue prints 10、9、8、7、6、4、3、2、1
```
`for` can read data from `array`, `slice`, `map` and `string` when it is used together with `range`.
```Go
for k,v:=range map {
fmt.Println("map's key:",k)
fmt.Println("map's val:",v)
}
for k,v:=range map {
fmt.Println("map's key:",k)
fmt.Println("map's val:",v)
}
```
Because Go supports multi-value returns and gives compile errors when you don't use values that were defined, you may want to use `_` to discard certain return values.
for _, v := range map{
fmt.Println("map's val:", v)
}
```Go
for _, v := range map{
fmt.Println("map's val:", v)
}
```
### switch
Sometimes you may find that you are using too many `if-else` statements to implement some logic, which may make it difficult to read and maintain in the future. This is the perfect time to use the `switch` statement to solve this problem.
```Go
switch sExpr {
case expr1:
some instructions
case expr2:
some other instructions
case expr3:
some other instructions
default:
other code
}
switch sExpr {
case expr1:
some instructions
case expr2:
some other instructions
case expr3:
some other instructions
default:
other code
}
```
The type of `sExpr`, `expr1`, `expr2`, and `expr3` must be the same. `switch` is very flexible. Conditions don't have to be constants and it executes from top to bottom until it matches conditions. If there is no statement after the keyword `switch`, then it matches `true`.
```Go
i := 10
switch i {
case 1:
fmt.Println("i is equal to 1")
case 2, 3, 4:
fmt.Println("i is equal to 2, 3 or 4")
case 10:
fmt.Println("i is equal to 10")
default:
fmt.Println("All I know is that i is an integer")
}
i := 10
switch i {
case 1:
fmt.Println("i is equal to 1")
case 2, 3, 4:
fmt.Println("i is equal to 2, 3 or 4")
case 10:
fmt.Println("i is equal to 10")
default:
fmt.Println("All I know is that i is an integer")
}
```
In the fifth line, we put many values in one `case`, and we don't need to add the `break` keyword at the end of `case`'s body. It will jump out of the switch body once it matched any case. If you want to continue to matching more cases, you need to use the`fallthrough` statement.
```Go
integer := 6
switch integer {
case 4:
fmt.Println("integer <= 4")
fallthrough
case 5:
fmt.Println("integer <= 5")
fallthrough
case 6:
fmt.Println("integer <= 6")
fallthrough
case 7:
fmt.Println("integer <= 7")
fallthrough
case 8:
fmt.Println("integer <= 8")
fallthrough
default:
fmt.Println("default case")
}
integer := 6
switch integer {
case 4:
fmt.Println("integer <= 4")
fallthrough
case 5:
fmt.Println("integer <= 5")
fallthrough
case 6:
fmt.Println("integer <= 6")
fallthrough
case 7:
fmt.Println("integer <= 7")
fallthrough
case 8:
fmt.Println("integer <= 8")
fallthrough
default:
fmt.Println("default case")
}
```
This program prints the following information.
```Go
integer <= 6
integer <= 7
integer <= 8
default case
integer <= 6
integer <= 7
integer <= 8
default case
```
## Functions
Use the `func` keyword to define a function.
```Go
func funcName(input1 type1, input2 type2) (output1 type1, output2 type2) {
// function body
// multi-value return
return value1, value2
}
func funcName(input1 type1, input2 type2) (output1 type1, output2 type2) {
// function body
// multi-value return
return value1, value2
}
```
We can extrapolate the following information from the example above.
@@ -209,9 +210,9 @@ func max(a, b int) int {
return a
}
return b
}
}
func main() {
func main() {
x := 3
y := 4
z := 5
@@ -254,23 +255,23 @@ func main() {
```
The above example returns two values without names -you have the option of naming them also. If we named the return values, we would just need to use `return` to return the values since they are initialized in the function automatically. Notice that if your functions are going to be used outside of the package, which means your function names start with a capital letter, you'd better write complete statements for `return`; it makes your code more readable.
```Go
func SumAndProduct(A, B int) (add int, multiplied int) {
add = A+B
multiplied = A*B
return
}
func SumAndProduct(A, B int) (add int, multiplied int) {
add = A+B
multiplied = A*B
return
}
```
### Variadic functions
Go supports functions with a variable number of arguments. These functions are called "variadic", which means the function allows an uncertain numbers of arguments.
```Go
func myfunc(arg ...int) {}
func myfunc(arg ...int) {}
```
`arg …int` tells Go that this is a function that has variable arguments. Notice that these arguments are type `int`. In the body of function, the `arg` becomes a `slice` of `int`.
```Go
for _, n := range arg {
fmt.Printf("And the number is: %d\n", n)
}
for _, n := range arg {
fmt.Printf("And the number is: %d\n", n)
}
```
### Pass by value and pointers
@@ -372,15 +373,15 @@ func ReadWrite() bool {
```
If there are more than one `defer`s, they will execute by reverse order. The following example will print `4 3 2 1 0`.
```Go
for i := 0; i < 5; i++ {
defer fmt.Printf("%d ", i)
}
for i := 0; i < 5; i++ {
defer fmt.Printf("%d ", i)
}
```
### Functions as values and types
Functions are also variables in Go, we can use `type` to define them. Functions that have the same signature can be seen as the same type.
```Go
type typeName func(input1 inputType1 , input2 inputType2 [, ...]) (result1 resultType1 [, ...])
type typeName func(input1 inputType1 , input2 inputType2 [, ...]) (result1 resultType1 [, ...])
```
What's the advantage of this feature? The answer is that it allows us to pass functions as values.
```Go
@@ -438,25 +439,25 @@ Go doesn't have `try-catch` structure like Java does. Instead of throwing except
The following example shows how to use `panic`.
```Go
var user = os.Getenv("USER")
var user = os.Getenv("USER")
func init() {
if user == "" {
panic("no value for $USER")
}
}
func init() {
if user == "" {
panic("no value for $USER")
}
}
```
The following example shows how to check `panic`.
```Go
func throwsPanic(f func()) (b bool) {
defer func() {
if x := recover(); x != nil {
b = true
}
}()
f() // if f causes panic, it will recover
return
}
func throwsPanic(f func()) (b bool) {
defer func() {
if x := recover(); x != nil {
b = true
}
}()
f() // if f causes panic, it will recover
return
}
```
### `main` function and `init` function
@@ -474,13 +475,13 @@ Figure 2.6 Flow of programs initialization in Go
We use `import` very often in Go programs as follows.
```Go
import(
"fmt"
)
import(
"fmt"
)
```
Then we use functions in that package as follows.
```Go
fmt.Println("hello world")
fmt.Println("hello world")
```
`fmt` is from Go standard library, it is located within $GOROOT/pkg. Go supports third-party packages in two ways.
@@ -494,26 +495,26 @@ There are some special operators when we import packages, and beginners are alwa
1. Dot operator.
Sometime we see people use following way to import packages.
```Go
import(
. "fmt"
)
import(
. "fmt"
)
```
The dot operator means you can omit the package name when you call functions inside of that package. Now `fmt.Printf("Hello world")` becomes to `Printf("Hello world")`.
2. Alias operation.
It changes the name of the package that we imported when we call functions that belong to that package.
```Go
import(
f "fmt"
)
import(
f "fmt"
)
```
Now `fmt.Printf("Hello world")` becomes to `f.Printf("Hello world")`.
3. `_` operator.
This is the operator that is difficult to understand without someone explaining it to you.
```Go
import (
"database/sql"
_ "github.com/ziutek/mymysql/godrv"
)
import (
"database/sql"
_ "github.com/ziutek/mymysql/godrv"
)
```
The `_` operator actually means we just want to import that package and execute its `init` function, and we are not sure if we want to use the functions belonging to that package.