Go語言學習Part2:流程控制語句:for、if、else、switch 和 defer

for循環

  • 初始化語句+條件語句+後置語句
    • 初始化語句一般爲短變量聲明
    • 條件語句在迭代前求值,false迭代就會中止
    • 後置語句在每次迭代結尾執行
//case 1
package main

import "fmt"

func main() {
    sum := 0
    for i:=0; i<3; i++ {
        sum += i
        fmt.Println(sum)
    }
}
  • 條件語句一般如果想要循環結束應該有,初始化語句和後置語句可有可無
    • 只有條件語句就可以(看起來像不像C裏面的while)
    • 條件語句兩側加分號也可以
    • 省略條件語句,會變成無限循環
//case 2
package main

import "fmt"

func main() {
    sum := 0
    i := 1
    for sum<3 {
        sum += i
        fmt.Println(sum)
    }
}
//case 3
package main

import "fmt"

func main() {
    sum := 0
    i := 1
    for ;sum<3; {
        sum += i
        fmt.Println(sum)
    }
}
//case 4
package main

import "fmt"

func main() {

    for {
        fmt.Printf("hello")
    }
}

if語句

//case 5
//實現一個開根號的函數

package main

import (
    "fmt"
    "math"
)

func sqrtFloat(x float64) string {
    if x < 0 {
        return sqrtFloat(-x)+"i"
    } 
    return fmt.Sprint(math.Sqrt(x))
}

func main() {
	fmt.Println(sqrtFloat(-9), sqrtFloat(80))
    fmt.Println(sqrtFloat(5))
}
  • if語句可以在表達式執行之前執行一個簡單的語句
//case 6
// 寫代碼也考驗記憶裏hh,各種規則都要記住
// math.Pow()的參數是float64
package main    
import "fmt"
import "math"

func test(x, y, limit float64) float64{
    if v := math.Pow(x, y); v < limit {
        return v
    } else {
		 return limit
	}
       
}

func main() {
    fmt.Println(test(2,3, 6))
    fmt.Println(test(2,3, 10))
}

  • if 簡短語句聲明的變量,else仍舊有效;出了if、else塊變量就無效了
//case 7
// 寫代碼也考驗記憶裏hh,各種規則都要記住
// math.Pow()的參數是float64
package main    
import "fmt"
import "math"

func test(x, y, limit float64) float64{
    if v := math.Pow(x, y); v < limit {
        return v
    } else {
        fmt.Println("test else",v)
		 return limit
	}
       
}

func main() {
    fmt.Println(test(2,3, 6))
    fmt.Println(test(2,3, 10))
}

switch

  • go的進入一個case,會自動退出;如果你想要強制執行下面的case:使用fallthrough
    • Go裏面switch默認相當於每個case最後帶有break,匹配成功後不會自動向下執行其他case,而是跳出整個switch, 但是可以使用fallthrough強制執行後面的所有case代碼,包括default。見case8
    • 最後一個分支,不能使用fallthrough
  • case 不用是int,任何類型都可以
  • 寫起來比if else 簡單很多,見case9
//case 8
package main

import (
	"fmt"
	"runtime"
)

func main() {
	fmt.Print("Go runs on ")
	switch os := runtime.GOOS; os {
	case "darwin":
		fmt.Println("OS X.")
	case "linux":
		fmt.Println("Linux.")
	default:
		// freebsd, openbsd,
		// plan9, windows...
		fmt.Printf("%s.\n", os)
	}
	
	s := "abcd"  // 匹配b,輸出了234
	switch  s[1] {
	case 'a':
		fmt.Println("1")
		fallthrough
	case 'b':
		fmt.Println("2")
		fallthrough
	case 'e':
		fmt.Println("3")
		fallthrough
	default:
		// freebsd, openbsd,
		// plan9, windows...
		fmt.Printf("4")

	}
}

// case 9
package main

import (
	"fmt"
	"time"
)

func main() {
	// Go 練習場中的時間總是從 2009-11-10 23:00:00 UTC 語言發佈的日子
	// https://tour.go-zh.org/
	t := time.Now()
	switch {
	case t.Hour() < 12:
		fmt.Println("Good morning!")
	case t.Hour() < 17:
		fmt.Println("Good afternoon.")
	default:
		fmt.Println("Good evening.")
	}
}

練習題目你敢信,考驗我記憶的時候到了哈哈哈哈哈

  • 一次成功hh,開平方這個找到了數學思維
  • 牛頓迭代法求平方根,參考這篇,寫的非常之好:https://blog.csdn.net/chenrenxiang/article/details/78286599
    • 主要的思路:平方根的結果是曲線和切線在y軸上的點重合,有一個不斷逼近的迭代過程
    • case10:迭代法的變種
    • case11:迭代法的原型: x(n+1) = (x(n)*2+a)/2x(n) , a是平方數
// case 10
package main

import (
	"fmt"
)

func Sqrt(x float64) float64 {
	z := 1.0
	for i:=0; i< 100; i++ {
		z -= (z*z -x)/(2*z)
		fmt.Println(z)
	}
	return z
}

func main() {
	fmt.Println(Sqrt(100))
}

//case 11
package main

import (
	"fmt"
)

func Sqrt(x float64) float64 {
	xcur := 1.0;
	for i:=0; i< 100; i++ {
		xcur = (xcur*xcur +x)/(2*xcur)
		fmt.Println(xcur)
	}
	return xcur
}

func main() {
	fmt.Println(Sqrt(100))
}

runtime知多少

  • runtime 調度器是個非常有用的東西,關於 runtime 包幾個方法:
    • 以下來源該鏈接:https://www.jianshu.com/p/e45cea3e1723
    • Gosched:讓當前線程讓出 cpu 以讓其它線程運行,它不會掛起當前線程,因此當前線程未來會繼續執行
    • NumCPU:返回當前系統的 CPU 核數量
    • GOMAXPROCS:設置最大的可同時使用的 CPU 核數, 寫在init函數裏面
    • Goexit:退出當前 goroutine(但是defer語句會照常執行)
    • NumGoroutine:返回正在執行和排隊的任務總數
    • GOOS:目標操作系統
  • 以下例子裏面有defer,會將函數推遲到外層函數返回後執行,見case 14
    • 推遲的函數會被押入棧中,這也太妙了吧hh,見case 15
//case 12
package main

import (
    "fmt"
    "runtime"
)

func init() {
    runtime.GOMAXPROCS(4)  //使用多核
}

func main() {
	fmt.Println(runtime.NumCPU())
    exit := make(chan int)
    go func() {
        defer close(exit)
        go func() {
            fmt.Println("b")
        }()
    }()

    for i := 0; i < 5; i++ {
        fmt.Println("a:", i)

        if i == 1 {
            runtime.Gosched()  //切換任務
        }
        if i == 3 {
            runtime.Gosched()  //切換任務
        }
    }
    <-exit
}
//case 14
package main

import "fmt"

func main() {
	defer fmt.Println("world")

	fmt.Println("hello")
}

//case 15
package main

import "fmt"

func main() {
	fmt.Println("counting")

	for i := 10; i >= 0; i-- {
		defer fmt.Println(i)
	}

	fmt.Println("done")
}


函數知多少

  • fmt.Printf()
    • 根據 format 參數生成格式化的字符串並寫入標準輸出
  • fmt.Sprintf()
    • 根據 format 參數生成格式化的字符串並返回該字符串
  • fmt.Fprintf()
    • 根據format 參數生成格式化的字符串並寫入 io.Writer
  • time.Now().Weekday()
    • time.Saturday
//case 13
package main

import (
	"fmt"
	"time"
)

func main() {
	fmt.Println("When's Tuesday?")
	today := time.Now().Weekday()
	fmt.Println(time.Now())
	fmt.Println(today)
	switch time.Tuesday {
	case today + 0:
		fmt.Println("Today is Tuesday.")
	case today + 1:
		fmt.Println("Tomorrow.")
	case today + 2:
		fmt.Println("In two days.")
	default:
		fmt.Println("Too far away.")
	}
}

一點點好東西

  • https://golang.org/ref/spec
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章