Function and flow control

flow control

if:

if x>10{    fmt.Println("x is greater than 10")}else{    fmt.Println("x is less than 10")}

The condition judegement allow one variable's declaration which only function in this logic judgement part

if x:= computedValue(); x>10{    fmt.Println("x is greater than 10")}else if x<3{    fmt.Println("x is less than 3")}else{    fmt.Println("x is greater than 3 and less than 10")}fmt.Println(x) //Here will raise some mistakes since x is not available here

For:

package mainimport "fmt"func main(){    sum := 0    for index := 0;index < 10;index++{        sum += index    }    fmt.Println("sum is equal to", sum)}

expression1 and expression2 could be omitted:

sum := 1for ;sum<1000;{    sum += sum}

break will shut down the loop, continue will break out this loop

for index := 10;index>0; index--{    if index == 5{        break //continue    }    fmt.Println(index)}//break: 10 9 8 7 6//continue: 10 9 8 7 6 4 3 2 1

for can coordinate with range for slice and map :

for key,value := range mapName{    fmt.Println("map's key is:",key)}

You can drop the unuesd values by introducing _:

for _,v := range mapName{    fmt.Println("map's value is:", v)}

Switch

switch interger{    case 4:        fmt.Println("The integer was <= 4")        fallthrough    case 5:        fmt.Println("The integer was <= 5")        fallthrough    case 6:        fmt.Println("The integer was <= 6")        fallthrough    default:        fmt.Println("default case")}

All case defautly possess the break, if we use fallthrough, then when the first matched case was found, the following cases will still be judged.

Function

func funcName(input1 type1, input2 type2, input3 type3)(output1 type1, output2 type2){    return value1, value2}
  • output1 output2 could be omitted,
package mainimport "fmt"func SumAndProduct(A int, B int)(int, int){    return A+B, A*B}func main(){    x := 3    y := 4    xPLUSy, xTIMESy := SumAndProduct(x,y)}

Changing parameters

func myfunc(arg ...int){}

arg is a slice accepting undetermined parameters whose type is int

Pointer

When we deliverying parameters from one function to another, we delivery the copy rather than the quotation, so we cannot change the value of the parameters by calling a function, if we intend to do so, pass the pointer.

package mainimport "fmt"//简单的一个函数,实现了参数+1的操作func add1(a *int) int { // 请注意,    *a = *a+1 // 修改了a的值    return *a // 返回新值}func main() {    x := 3    fmt.Println("x = ", x)  // 应该输出 "x = 3"    x1 := add1(&x)  // 调用 add1(&x) 传x的地址    fmt.Println("x+1 = ", x1) // 应该输出 "x+1 = 4"    fmt.Println("x = ", x)    // 应该输出 "x = 4"}

Here we pass the *int a, so the returned *a can change the x to x1.

The advantages of passing the pointer:

  • multiple functions can manipulate one object.

  • passing pointers is efficient and space-saving(8 bytes), when you would pass the struct or a big object, passing the pointer is a great method.

  • channel,slice,map 's realizing mechanisms are like pointers

defer

defer realize the stack, in functions, defer will be called before return.

func ReadWrite() bool {    file.Open("file")    defer file.Close()    if failureX {        return false    }    if failureY {        return false    }    return true}

Here is another usage, print the output reversely:

for i := 0; i < 5; i++ {    defer fmt.Printf("%d ", i)}

Define function as the value or type

Pass this function as the value:

package mainimport "fmt"type testInt func(int) bool // 声明了一个函数类型func isOdd(integer int) bool {    if integer%2 == 0 {        return false    }    return true}func isEven(integer int) bool {    if integer%2 == 0 {        return true    }    return false}// 声明的函数类型在这个地方当做了一个参数func filter(slice []int, f testInt) []int {    var result []int    for _, value := range slice {        if f(value) {            result = append(result, value)        }    }    return result}func main(){    slice := []int {1, 2, 3, 4, 5, 7}    fmt.Println("slice = ", slice)    odd := filter(slice, isOdd)    // 函数当做值来传递了    fmt.Println("Odd elements of slice are: ", odd)    even := filter(slice, isEven)  // 函数当做值来传递了    fmt.Println("Even elements of slice are: ", even)}

Taking f's place to be testInt()

Panic and recover:

Go cannot thrown exceptions as Java or C++, that is why panic and recover exist. But use them cautiously.

var user = os.Getenv("USER")func init(){    if user == ""{        panic("no value for $USER")    }}

This defer function can judge whether there is a panic function when executing the function

func throwsPanic(f func())(b bool){    defer func(){        if x:=recover();x!=nil{            b = true        }    }()    f()    return}
  • Conming accross the panic function, the function will immediately break off and jump to return, however the defer function will still be executed, so, if we put the recover function into the defer, we can detect whether we come accross the panic and take some measures.

main** and **init

These two reserved functions are forbidden to possess any input or output.main is the entry of the package main, init is the entry of all packages.

[图片上传失败...(image-154a5-1540311933507)]

import

When we inport something, the function load packages from the path abtained from environment variable GOROOT.

We can also import our own packages by absolute paths:

import "shorturl/model" //load $GOPATH/shorturl/model

Other methods to import packages:

import {    . "fmt"}

or

import {    f "fmt"}

then we can call functions of "fmt" by :

import {    Println("hello world")    //the first one    f.Println("hello world")    //the second one}
import {    _ "github.com/ziutek/mysql/godrv"}

No function will be included, but the init() will still be executed

你可能感兴趣的:(Function and flow control)