代码改变世界

Golang流程语句

2013-04-04 23:15  Yang-Onion  阅读(843)  评论(0编辑  收藏  举报
package main

import (
    "fmt"
)

func main() {

    //if
    /*
        x := 5
        if x > 10 {
            fmt.Println("X is larger than 10")
        } else {
            fmt.Println("X is smaller than 10")
        }

        //也可写成
        //if y := GetSomeNumber(); y < 10 {

        //}
    */

    //goto 用goto跳转到必须在当前函数内定义的标签(以冒号结束作为标签,且大小写敏感)
    /*
            i := 0
        Here:
            fmt.Println(i)
            i++
            goto Here
    */

    //for  和其他语言的for一样,但他可以当作while来使用,也可配合range 读取slice,map数据
    /*
            //for=while
            sum := 0
            for sum < 100 {
                sum++
            }

            //for range map(slice)
            for k,v=range map{
                fmt.Println("map's key :",k)
                fmt.Println("map's value:",v)
            }

            //如果没有fmt.Println("map's key :",k)这句,使用k申明了而没使用,会造成编译出错
            //所以,要做修改将k改成_,来丢弃不需要的返回值
            for k,v=range map{
                fmt.Println("map's key :",k)
                fmt.Println("map's value:",v)
            }
            //修改成
            for _,v=range map{
                fmt.Println("map's value:",v)
            }
    */

    //switch,如果swith 没有表达式,它会匹配true;每个case后面不用加break;
    //它默认加了break,如果要实现没有break的情况,要在除default外的所有case后面加fallthrough
    /*
        i := 5
        switch i {

        case 1:
            fmt.Println("i is equal to 1")
        case 2:
            fmt.Println("i is equal to 2")
        case 3, 4, 5, 6:
            fmt.Println("i is equal to 3,4,5 or 6")
            fallthrough //添加后,相当于去掉默认的break
        default:
            fmt.Println("others")

        }
    */

    //函数
    /*
            func funcName(input1 type1,input2 type2)(output1 type1,output2 type2)
            {
                      //返回多个值
                      return value1,value2        
            }

            //上面返回值声明了两个变量output1和output2,
            //如果你不想声明也可以,直接就两个类型
            func funcName(input1 type1,input2 type2)(type1,type2)
            {
                      //返回多个值
                      return value1,value2        
            }

            //如果只有一个返回值且不声明返回值变量,那么你可以省略 包括返回值 的括号
            func funcName(input1 type1,input2 type2) type1
            {
                      //返回1个值,可省略返回值的名称和括号
                      return value1+value2        
            }

            //如果没有返回值,那么就直接省略最后的返回信息
            func funcName(input1 type1,input2 type2) 
            {
                      //没有返回值,可省略返回信息
                      sum:= value1+value2        
            }

            //如果参数类型相同,则可以省略第一个参数的类型
            //说明input1和input2都是参数都是int类型的
            func funcName(input1 ,input2 int) 
            {
                      //有返回值,return必须写在最外层
                      return  value1+value2        
            }
            //变参,参数类型为int,个数不限
            func funcName(arg ...int) {

            }

            //示例
            var var1 int32 = 2
            var var2 int32 = 5
            var3, var4 := PlusAndTimes(var1, var2)
            fmt.Printf("%d,%d", var3, var4)
    */

    //传值与传指针

    //传指针使得多个函数能操作同一个对象。
    //传指针比较轻量级 (8bytes),只是传内存地址,
    //我们可以用指针传递体积大的结构体。
    //如果用参数值传递的话, 在每次copy上面就会花费相对较多的系统开销(内存和时间)。
    //所以当你要传递大的结构体的时候,用指针是一个明智的选择。
    //Go语言中string,slice,map这三种类型的实现机制类似指针,
    //所以可以直接传递,而不用取地址后传递指针。
    //(注:若函数需改变slice的长度,则仍需要取地址传递指针)

    //传值,传指针示例
    /*
        x := 3
        fmt.Println("x = ", x)    // 应该输出 "x = 3"
        x1 := addByValue(x)       //调用add1(x)
        fmt.Println("x+1 = ", x1) // 应该输出"x+1 = 4"
        fmt.Println("x = ", x)    // 应该输出"x = 3"

        fmt.Println("------------")
        //传指针
        fmt.Println("x = ", x)    // 应该输出 "x = 3"
        x2 := addByPoint(&x)      //调用add1(x)
        fmt.Println("x+1 = ", x2) // 应该输出"x+1 = 4"
        fmt.Println("x = ", x)    // 应该输出"x = 4"
    */

    //defer
    //Go语言中有种不错的设计,即延迟(defer)语句,你可以在函数中添加多个defer语句。
    //当函数执行到最后时,这些defer语句会按照【逆序】执行,最后该函数返回
    //见示例

    //函数作为值、类型
    //Go中函数也是一种变量,我们可以通过type来定义它,
    //它的类型就是所有拥有相同的参数,相同的返回值的一种类型
    //类似于c#中的委托

    //示例
    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)

    //Panic和Recover
    //Panic:当函数F调用panic,函数F的执行被中断,
    //但是F中的延迟函数会正常执行,然后F返回到调用它的地方。
    //Recover:仅在延迟函数中有效。
    //在正常的执行过程中,调用recover会返回nil,并且没有其它任何效果。

    //main函数和init函数
    //每个package中的init函数都是可选的,
    //但package main就必须包含一个main函数。

    //执行顺序
    //初始化和执行main包-->导入其他包(如果main包导入了其他包)-->初始化其他包的常量、变量
    //-->执行其他包的init()-->初始化main包的变量、常量-->执行main包的init()-->执行main()
}

func PlusAndTimes(var1, var2 int32) (plusVar, timesVar int32) {
    plusVar = var1 + var2
    timesVar = var1 * var2
    return
}

//简单的一个函数,实现了参数+1的操作
func addByValue(a int) int {
    a = a + 1 // 我们改变了a的值
    return a  //返回一个新值
}

//简单的一个函数,实现了参数+1的操作
func addByPoint(a *int) int {
    *a = *a + 1
    return *a
}

//defer Demo
/*
func testNoDefer() bool {
    file.open("file")
    if failureX {
        file.close()
        return false
    }
    if failureY {
        file.close()
        return false
    }
    file.close()
    return true
}

func testDefer() bool{
    file.opern()
    defer file.close()
    if failureX {
        return false
    }
    if failureY {
        return false
    }
    return true
}
*/

//声明一个函数类型(类型于c#中的委托),isOdd和isEven的参数和返回值必须和testInt一样

type testInt func(intVar int) bool

func isOdd(integer int) bool {
    if integer%2 == 0 {
        return true
    }
    return false
}

func isEven(integer int) bool {
    if integer%2 == 0 {
        return false
    }
    return true
}

func filter(slice []int, f testInt) []int {
    var result []int
    for _, value := range slice {
        if f(value) {
            result = append(result, value)
        }
    }
    return result
}

 

home page tracking
NutriSystem Diet