條件語句
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 只有值傳遞一種方式
(值傳遞)
(值傳遞:拷貝,原函式中的值不會變. 引用傳遞:會改變原函式中的值)
(通過指標+值傳遞實現引用傳遞的效果) ![Go 學習筆記 - Go 基礎語法(2)](https://cdn.learnku.com/uploads/images/202107/06/41040/hZqQ18KzT1.png!large) (object 的傳遞)例子
func swap(a, b *int) { *a, *b = *b, *a } // 函式入口 func main() { a, b := 3, 4 swap(&a, &b) fmt.Println(a, b) }
本作品採用《CC 協議》,轉載必須註明作者和本文連結