Go 学习笔记 - Go 基础语法(2)
go 基础语法 (程序结构控制)
条件语句
- if
- if的条件里是不需要括号的
- if 的条件里可以赋值
- if 条件里赋值的变量作用于就在这个 if 语句里面
func readsfile() { const filename = "abc.txt" // 注意创建文件 // 写法1 比较多 // go 语言的函数是可以返回两个值的 countents, err := ioutil.ReadFile(filename) if err != nil { fmt.Print(err) } else { fmt.Printf("%s\n", countents) } // 写法2 if可以跟多个语句 if countents, err := ioutil.ReadFile(filename); err != nil { fmt.Print(err) } else { fmt.Printf("%s\n", countents) } }
- switch
- switch 会自动 break, 除非使用 fallthrough
- switch 后可以没有表达式
- panic 会自动报错
func grade(score int) string { g := "" switch { case score < 0 || score > 100: panic(fmt.Sprintf( "Wrong scor: %d", score)) case score < 60: g = "F" case score < 80: g = "C" case score < 90: g = "B" case score <= 100: g = "A" // default: // panic(fmt.Sprintf("Wrong scor: %d", score)) } return g } // 函数入口 func main() { fmt.Println( grade(0), grade(20), grade(50), grade(69), grade(98), grade(100), // grade(101), // grade 报错不会返回前面的已经运算的结果,是直接跳出err ) }
循环
for
for 的条件里不需要括号
for 的条件里面可以省略初始条件,结束条件,递增表达式
省略初始条件相当于while, go 语言中没有 while
省略所有条件就是死循环
func converToBin(n int) string { // 省略初始条件 result := "" for ; n > 0; n /= 2 { lsb := n % 2 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 scanner.Scan() { fmt.Println(scanner.Text()) } } func forever(){ // 省略所有条件就是死循环 // 死循环设计的这么好写是因为 go 中死循环使用的频率很高 for { fmt.Println("hello") } } // 函数入口 func main() { fmt.Println( converToBin(5), converToBin(13), converToBin(23333), converToBin(0), ) printFile("abc.txt") forever() }
函数
函数格式
func eval(a, b int, op string) int
函数名在前 类型在后函数可以返回多个值
函数返回多个值可以起名(起名适用于非常简单的函数),对于调用者而言没有区别
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 "/": return a / b, nil default: // 函数的多返回值不要乱用,一般是一个返回值,加一个 err // panic("unsupported operation:" + op) // panic 直接报错中断程序,不建议使用 return 0, fmt.Errorf("unsupported operation: %s", op) } } // 取余 func div(a, b int) (q, r int) { // q,r 方便他人理解,返回值可以取个名字 return a / b, a % b // 但是如果函数体过长,使用这这方法来 return 看起来会很累 // q = a / b // r = a % b // return } // 函数入口 func main() { fmt.Println(eval(3, 4, "*")) if result, err := eval(2, 3, "x"); err != nil { fmt.Printf("Error:", err) } else { fmt.Println(result) } // fmt.Println(div(13, 4)) q, r := div(13, 4) s, _ := div(13, 4) // go 语言定义的变量一定要使用到,两个返回的变量就可以使用 _ 跳过不需要的返回值 fmt.Println(q, r, s) }
函数式编程:函数的条件,参数包括函数内都可以嵌套函数
// 简化上面的方法,不需要那么复杂的switch func apply(op func(int, int) int, a, b int) int { return op(a, b) } // 定义一个函数不需要再去转换浮点 func pow(a, b int) int { return int(math.Pow(float64(a), float64(b))) } // 函数入口 func main() { fmt.Println(apply(pow, 2, 4)) // 如果觉得定义一个包比较麻烦,也可以直接写一个匿名函 fmt.Println(apply( func(a, b int) int { return int(math.Pow(float64(a), float64(b))) }, 2, 4)) }
go 语言函数没有默认参数,可选参数,参数重载.
只有一个可变参数列表// ...int 代表随意传多少个int都可以 func sum(numbers ...int) int { s := 0 for i := range numbers { s += numbers[i] } return s } // 函数入口 func main() { fmt.Println(sum(1, 2, 3, 4, 5)) // 15 }
指针
- go 的指针不能运算
go 只有值传递一种方式
(值传递:拷贝,原函数中的值不会变. 引用传递:会改变原函数中的值)(值传递)
(通过指针+值传递实现引用传递的效果)
(object 的传递)
例子
func swap(a, b *int) { *a, *b = *b, *a } // 函数入口 func main() { a, b := 3, 4 swap(&a, &b) fmt.Println(a, b) }
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: