【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.pngpackage 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.pngpackage 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