golang小程式實驗(二)

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
1. golang程式已耗用時間顯示
package mainimport ("fmt""time""math/rand")func main(){rand.Seed(time.Now().Unix())var name stringfor i:=0; i<3; i++{name=fmt.Sprintf("go_%02d", i)go runroutine(name, time.Duration(rand.Intn(5))*time.Second)}var input string//for waiting goroutine, unless it exit.fmt.Scanln(&input)fmt.Println("Done")}func runroutine(name string, t time.Duration){t0:=time.Now()fmt.Println(name, " start at ", t0)time.Sleep(t)t1:=time.Now()fmt.Println(name, " end at ", t1)fmt.Println(name, " lasted ", t1.Sub(t0))fmt.Println()}

運行結果:

go_00  start at  2013-12-05 17:22:34.5337149 +0800 +0800go_01  start at  2013-12-05 17:22:34.5367151 +0800 +0800go_02  start at  2013-12-05 17:22:34.5367151 +0800 +0800go_02  end at  2013-12-05 17:22:36.5548305 +0800 +0800go_02  lasted  2.0181154sgo_00  end at  2013-12-05 17:22:37.5558878 +0800 +0800go_00  lasted  3.0221729sgo_01  end at  2013-12-05 17:22:38.5549449 +0800 +0800go_01  lasted  4.0182298sjDone
2. 利用mutex控制goroutine的執行
package mainimport "fmt"import "time"import "math/rand"import "sync"import "runtime"//var total_tickets int32 = 10var mutex = &sync.Mutex{} //可簡寫成:var mutex sync.Mutexfunc sell_tickets(i int, t time.Duration) {var total_tickets int32 = 10for {mutex.Lock()if total_tickets > 0 {time.Sleep(t)total_tickets--fmt.Println("id:", i, "  ticket:", total_tickets)}mutex.Unlock()}}func main() {runtime.GOMAXPROCS(4)        //我的電腦是4核處理器,所以我設定了4rand.Seed(time.Now().Unix()) //產生隨機種子for i := 0; i < 5; i++ { //並發5個goroutine來賣票go sell_tickets(i, time.Duration(rand.Intn(5))*time.Millisecond)}//等待線程執行完var input stringfmt.Scanln(&input)//fmt.Println(total_tickets, "done") //退出時列印還有多少票}
3. 利用select監聽channel
package main import "time" import "fmt" func main() {     //建立兩個channel - c1 c2     c1 := make(chan string)     c2 := make(chan string)     //建立兩個goruntine來分別向這兩個channel發送資料     go func() {         time.Sleep(time.Second * 1)         c1 <- "Hello"     }()     go func() {         time.Sleep(time.Second * 1)         c2 <- "World"     }()     //使用select來偵聽兩個channel     for {         select {         case msg1 := <-c1:             fmt.Println("received", msg1)         case msg2 := <-c2:             fmt.Println("received", msg2)         case <-time.After(time.Second * 30):            fmt.Println("Time Out")             break         }     } }

 上面代碼執行time.After時總是報錯:invalid identifier。不知道為什麼。如果改成default,加入sleep和break,由於break寫在最後,導致sleep後繼續監聽而使break永遠也得不到執行。

package mainimport "time"import "fmt"func main() {//建立兩個channel - c1 c2c1 := make(chan string)c2 := make(chan string)//建立兩個goruntine來分別向這兩個channel發送資料go func() {time.Sleep(time.Second * 1)c1 <- "Hello"}()go func() {time.Sleep(time.Second * 1)c2 <- "World"}()//使用select來偵聽兩個channelfor {select {case msg1 := <-c1:fmt.Println("received", msg1)case msg2 := <-c2:fmt.Println("received", msg2)default: //default會導致無阻塞fmt.Println("nothing received!")time.Sleep(time.Second)
                       //break永遠也不會執行break}}}

 關閉channel,總是在發送端關閉:

package mainimport "fmt"import "time"import "math/rand"func main() {channel := make(chan string)rand.Seed(time.Now().Unix())//向channel發送隨機個數的messagego func () {cnt := rand.Intn(10)fmt.Println("message cnt :", cnt)for i:=0; i<cnt; i++{channel <- fmt.Sprintf("message-%2d", i)}close(channel) //關閉Channel}()var more bool = truevar msg stringfor more {select{//channel會返回兩個值,一個是內容,一個是boolcase msg, more = <- channel:if more {fmt.Println(msg)}else{fmt.Println("channel closed!")}}}}
4. golang的定時器

Go語言中可以使用time.NewTimer或time.NewTicker來設定一個定時器,這個定時器會綁定在你的當前channel中,通過channel的阻塞通知機器來通知你的程式。

package mainimport "time"import "fmt"func main() {ticker := time.NewTicker(time.Second)go func() {for t := range ticker.C {fmt.Println(t)}}()//設定一個timer,10鈔後停掉tickertimer := time.NewTimer(10 * time.Second)<-timer.Cticker.Stop()fmt.Println("timer expired!")}
5. 利用os/exec中的Cmd執行命令
package mainimport ("bytes""fmt""log""os/exec""strings")func main() {cmd := exec.Command("tr", "a-z", "A-Z")cmd.Stdin = strings.NewReader("some input")var out bytes.Buffercmd.Stdout = &outerr := cmd.Run()if err != nil {log.Fatal(err)}fmt.Printf("in all caps: %q\n", out.String())}
6. golang命令列參數解析
package mainimport ("bytes""fmt""log""os/exec""strings")func main() {cmd := exec.Command("tr", "a-z", "A-Z")cmd.Stdin = strings.NewReader("some input")var out bytes.Buffercmd.Stdout = &outerr := cmd.Run()if err != nil {log.Fatal(err)}fmt.Printf("in all caps: %q\n", out.String())}

這樣執行:

#如果沒有指定參數名,則使用預設值$ go run flagtest.gohost: coolshell.cnport: 80debug: false#指定了參數名後的情況$ go run flagtest.go -host=localhost -port=22 -dhost: localhostport: 22debug: true#用法出錯了(如:使用了不支援的參數,參數沒有=)$ go build flagtest.go$ ./flagtest -debug -host localhost -port=22flag provided but not defined: -debugUsage of flagtest:-d=false: enable/disable debug mode-host="coolshell.cn": a host name-port=80: a port numberexit status 2
7. 使用append要注意的問題

1. 先看段簡單的代碼。
a := []int{1, 2, 3, 4, 5}
b = append(a[1:3], 8, 9)
這時fmt.Println(a)的結果是什嗎?
答案是: a = [1, 2, 3, 8, 9]

原因解答:a[1:3]返回的是一個new slice: b。不過這個b沿用了 a原有的空間。

2. 再看個新的
a := []int{1, 2, 3, 4, 5}
b = append(a[1:3], 8, 9, 10)
這時fmt.Println(a)的結果是什嗎?
答案是: a = [1, 2, 3, 4, 5]

原因解答: 因為這次append的資料超過了a的空間大小。所以系統重新開闢了一段空間給b。所以a的資料就不會修改了。

3. 在來一個
a := make([]int, 0, 6)
a = append(a, 1, 2, 3, 4, 5)
b = append(a[1:3], 8, 9, 10)
這時fmt.Println(a)的結果是什嗎?
答案是:(你大概應該猜到了) 是 a = [1, 2, 3, 8, 9]
原因嗎: 看看上一條解答,就明白了。也就是slice以cap空間為標準,沒有超過cap的空間,不會觸發空間的重新分配。

4. 補充一個
a := make([]int, 0, 6)
b := a[:3] // 這個語句合法嗎?
答案是合法的,雖然len(a) == 0, 不過slice取的是cap(a)。 只不過是b = [0, 0, 0]


相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.