让前端飞

【golang】2.0 逻辑控制、函数

2022-05-04  本文已影响0人  bobokaka

if

image.png

新建branch.go


image.png
package main

import (
    "fmt"
    "io/ioutil"
)

func main() {
    const filename = "abc.txt"
    contents, err := ioutil.ReadFile(filename)
    if err != nil {
        fmt.Println(err)
    } else {
        fmt.Printf("%s\n", contents)
    }
}

nil:相当于null


image.png

创建abc.txt

abcde
12345
hhhhh
again

再次执行:


image.png

也可以改写成:

package main

import (
    "fmt"
    "io/ioutil"
)

func main() {
    const filename = "abc.txt"
    //contents, err := ioutil.ReadFile(filename)
    //if err != nil {
    //  fmt.Println(err)
    //} else {
    //  fmt.Printf("%s\n", contents)
    //}
    //如上可以改写成:
    if contents, err := ioutil.ReadFile(filename); err != nil {
        fmt.Println(err)
    } else {
        fmt.Printf("%s\n", contents)
    }
}

如上的条件语句的作用域(contents, err)会局限于if内部使用。

switch

switch后面可以没有表达式。

image.png
package main

import (
    "fmt"
    "io/ioutil"
)

func ifDemo() {
    const filename = "abc.txt"
    //contents, err := ioutil.ReadFile(filename)
    //if err != nil {
    //  fmt.Println(err)
    //} else {
    //  fmt.Printf("%s\n", contents)
    //}
    //如上可以改写成:
    if contents, err := ioutil.ReadFile(filename); err != nil {
        fmt.Println(err)
    } else {
        fmt.Printf("%s\n", contents)
    }
}

func grade(score int) string {
    g := ""
    switch {
    case score < 0 || score > 100:
        panic(fmt.Sprintf("Wrong score: %d", score)) //panic:会中断执行并报错
    case score < 60:
        g = "F"
    case score < 70:
        g = "C"
    case score < 80:
        g = "B"
    case score < 90:
        g = "A"
    case score < 95:
        g = "S"
    case score <= 100:
        g = "S+"
    }
    return g

}

func main() {
    //ifDemo()
    fmt.Println(
        grade(0), grade(55), grade(65), grade(79), grade(87), grade(91), grade(95), grade(98),
    )
}
image.png

改成如下输出:

fmt.Println(
        grade(0), grade(55), grade(65), grade(79), grade(87), grade(91), grade(95), grade(98), grade(102), grade(-3))

image.png

for

image.png
package main

import (
    "bufio"
    "fmt"
    "os"
    "strconv"
)

/**
十进制转2进制
*/
func convertToBin(n int) string {
    result := ""
    for ; n > 0; n /= 2 {
        lsb := n % 2
        //strconv.Itoa():转string
        result = strconv.Itoa(lsb) + result
    }

    return result
}

func printFile(filename string) {
    file, err := os.Open(filename)
    // 报错
    if err != nil {
        panic(err)
    }
    scanner := bufio.NewScanner(file)

    // 只有结束条件,相当于while,go语言没有while,通过for实现
    for scanner.Scan() {
        fmt.Println(scanner.Text())
    }
}

func forever() {
    // 死循环
    for {
        fmt.Println("abc")
    }

}

func main() {
    fmt.Println(convertToBin(5), //101
        convertToBin(13), //1101
        convertToBin(72387885),
        convertToBin(0),
    )

    printFile("abc.txt")
    //forever()
}
image.png

函数

package main

import "fmt"

func eval(a, b int, op string) int {
    switch op {
    case "+":
        return a + b
    case "-":
        return a - b
    case "*":
        return a * b
    case "/":
        return a / b
    default:
        panic("unsupported operation:" + op)
    }
}

//商和余数
//func div(a, b int) (int, int) {
//  return a / b, a % b
//}
// 另一种写法,函数体太长不建议此写法
func div(a, b int) (q, r int) {
    //return a / b, a % b
    q = a / b
    r = a % b
    return
}

func main() {
    fmt.Println(eval(3, 4, "*"))
    q, r := div(13, 3)
    fmt.Println(q, "...", r)
}
image.png

修改一下。_表示变量不想用,go语言要求声明的变量必须使用,否则编译不通过:

package main

import "fmt"

func eval(a, b int, op string) int {
    switch op {
    case "+":
        return a + b
    case "-":
        return a - b
    case "*":
        return a * b
    case "/":
        q, _ := div(a, b)
        return q
    default:
        panic("unsupported operation:" + op)
    }
}

//商和余数
//func div(a, b int) (int, int) {
//  return a / b, a % b
//}
// 另一种写法,函数体太长不建议此写法
func div(a, b int) (q, r int) {
    //return a / b, a % b
    q = a / b
    r = a % b
    return
}

func main() {
    fmt.Println(eval(3, 4, "/"))
    q, r := div(13, 3)
    fmt.Println(q, "...", r)
}

image.png

go语言报错会中断运行,如果不想中断,可以如下写法:

package main

import "fmt"

func eval(a, b int, op string) (int, error) {
    switch op {
    case "+":
        return a + b, nil
    case "-":
        return a - b, nil
    case "*":
        return a * b, nil
    case "/":
        q, _ := div(a, b)
        return q, nil
    default:
        //panic("unsupported operation:" + op)
        return 0, fmt.Errorf("unsupported operation: %s", op)
    }
}

//商和余数
//func div(a, b int) (int, int) {
//  return a / b, a % b
//}
// 另一种写法,函数体太长不建议此写法
func div(a, b int) (q, r int) {
    //return a / b, a % b
    q = a / b
    r = a % b
    return
}

func main() {
    fmt.Println(eval(3, 4, "x"))
    q, r := div(13, 3)
    fmt.Println(q, "...", r)
}
image.png

更优化如下:

......
func main() {
    //fmt.Println(eval(3, 4, "x"))
    if result, err := eval(3, 4, "x"); err != nil {
        fmt.Println("error:", err)
    } else {
        fmt.Println(result)
    }

    q, r := div(13, 3)
    fmt.Println(q, "...", r)
}
image.png
image.png

go语言是函数式编程,可以函数的参数、函数的返回值,函数体内,都可以有函数,

package main

import (
    "fmt"
    "math"
    "reflect"
    "runtime"
)

func eval(a, b int, op string) (int, error) {
    switch op {
    case "+":
        return a + b, nil
    case "-":
        return a - b, nil
    case "*":
        return a * b, nil
    case "/":
        q, _ := div(a, b)
        return q, nil
    default:
        //panic("unsupported operation:" + op)
        return 0, fmt.Errorf("unsupported operation: %s", op)
    }
}
func applyEval(op func(int, int) int, a, b int) int {
    //reflect:可以进行反射
    p := reflect.ValueOf(op).Pointer() //获得指针
    opName := runtime.FuncForPC(p).Name()
    fmt.Printf("Calling function %s with args"+"(%d,%d)\n", opName, a, b)
    return op(a, b)
}

func pow(a, b int) int {
    return int(math.Pow(float64(a), float64(b)))
}

//商和余数
//func div(a, b int) (int, int) {
//  return a / b, a % b
//}
// 另一种写法,函数体太长不建议此写法
func div(a, b int) (q, r int) {
    //return a / b, a % b
    q = a / b
    r = a % b
    return
}

func main() {
    //fmt.Println(eval(3, 4, "x"))
    //if result, err := eval(3, 4, "x"); err != nil {
    //  fmt.Println("error:", err)
    //} else {
    //  fmt.Println(result)
    //}
    //
    //q, r := div(13, 3)
    //fmt.Println(q, "...", r)

    fmt.Println(applyEval(pow, 3, 4))
    //匿名函数
    fmt.Println(applyEval(func(a, b int) int {
        return int(math.Pow(float64(a), float64(b)))
    }, 3, 4))
}

image.png

go语言还支持可变参数列表。

......
func sum(numbers ...int) int {
    s := 0
    for i := range numbers {
        s += numbers[i]
    }
    return s
}

func main() {
    //fmt.Println(eval(3, 4, "x"))
    //if result, err := eval(3, 4, "x"); err != nil {
    //  fmt.Println("error:", err)
    //} else {
    //  fmt.Println(result)
    //}
    //
    //q, r := div(13, 3)
    //fmt.Println(q, "...", r)

    //fmt.Println(applyEval(pow, 3, 4))
    ////匿名函数
    //fmt.Println(applyEval(func(a, b int) int {
    //  return int(math.Pow(float64(a), float64(b)))
    //}, 3, 4))

    fmt.Println(sum(1, 2, 3, 4, 5, 6))
}
image.png
上一篇下一篇

猜你喜欢

热点阅读