Go方法與併發

2021-07-31 08:22:18 字數 3805 閱讀 3128

go中沒有類,但是可以為結構體定義方法,方法就是一類帶有特殊的接受者引數的函式。

方法接受者位於func關鍵字和方法名之間。

可以為非結構體型別宣告方法,但不能為其它包內定義的型別的接收者宣告方法,且不能為內建型別宣告方法。

// 函式

package main

import

"fmt"

func add(x int, y int) int

func main()

// 方法

package main

import

"fmt"

type rect struct

func (r *rect) area() int

func (r rect) perim() int

func main()

fmt.println("area: ", r.area())

fmt.println("perim:", r.perim())

rp := &r

fmt.println("area: ", rp.area())

fmt.println("perim:", rp.perim())

}// output

area: 50

perim:30

area: 50

perim:30

package main

import

"fmt"

// 函式 adder 返回乙個閉包。每個閉包被繫結到自己的 sum 變數上

func adder() func(int) int

}func main()

}

介面型別是由一組方法簽名的集合。

介面型別的值可以儲存任何實現了介面方法的變數。

型別通過實現了乙個介面的所有方法來實現這個介面,而不需要專門的顯示宣告也就是」implements」關鍵字來宣告。

package main

import

"fmt"

import

"math"

type geometry inte***ce

type rect struct

type circle struct

func (r rect) area() float64

func (r rect) perim() float64

func (c circle) area() float64

func (c circle) perim() float64

func measure(g geometry)

func main()

c := circle

measure(r)

measure(c)

}// output

1214

78.53981633974483

31.41592653589793

go程式設計提供了乙個非常簡單的錯誤處理框架,以及內建的錯誤介面型別,如下宣告:

type error inte***ce 

go函式通常返回錯誤作為最後乙個返回值。 可使用errors.new來構造乙個基本的錯誤訊息

package main

import

"errors"

import

"fmt"

import

"math"

func sqrt(value float64)(float64, error)

return math.sqrt(value), nil

}func main() else

result, err = sqrt(9)

if err != nil else

}

goroutine 是由 go 執行時環境管理的輕量級執行緒。

使用 go f(x, y, z) 開啟乙個新的 goroutine 執行。

package main

import

"fmt"

func f(from string)

}func main() ("going")

fmt.println("done")

}// output

$ go run goroutines.go

direct :0

direct :1

direct :2

goroutine :0

going

goroutine :1

goroutine :2

done

channel 是有型別的管道,可以用 channel 操作符 <- 對其傳送或者接收值。

ch <- v // 將 v 送入 channel ch。

v := <-ch // 從 ch 接收,並且賦值給 v。

預設情況下,在另一端準備好之前,傳送和接收都會阻塞。這使得 goroutine 可以在沒有明確的鎖或競態變數的情況下進行同步。

package main

import

"fmt"

func main() ()

msg := <-messages

fmt.println(msg)

}

channel 可以是帶緩衝的。為 make 提供第二個引數作為緩衝長度來初始化乙個緩衝 channel:

ch := make(chan int, 100)

向緩衝 channel 傳送資料的時候,只有在緩衝區滿的時候才會阻塞。當緩衝區清空的時候接受阻塞。

package main

import

"fmt"

func main()

傳送者可以 close 乙個 channel 來表示再沒有值會被傳送了。接收者可以通過賦值語句的第二引數來測試 channel 是否被關閉:當沒有值可以接收並且 channel 已經被關閉,那麼

v, ok := <-ch

ok 會被設定為 false。

注意: 只有傳送者才能關閉 channel,而不是接收者。向乙個已經關閉的 channel 傳送資料會引起 panic。

package main

import

"fmt"

func main() else

}}()

for j :=1; j <=3; j++

close(jobs)

fmt.println("sent all jobs")

<-done

}

go語言的選擇(select)可等待多個通道操作。將goroutine和channel與select結合是go語言的乙個強大功能。

select 會阻塞,直到條件分支中的某個可以繼續執行,這時就會執行那個條件分支。如果有多個都準備好的時候,會隨機選乙個。

package main

import

"time"

import

"fmt"

func main() ()

gofunc() ()

gofunc() ()

for i :=0; i <3; i++

}t2 := time.now().unixnano()

dt := (t2 - t1) /1e6

fmt.println(dt)

}

Go語言併發

協程 本質上是一種使用者態執行緒,不需要作業系統來進行搶占式排程,且在真正的實現重寄存於執行緒中,因此,系統開銷極小,可以有效提高執行緒的任務併發性,從而避免多執行緒的缺點。使用協程的優點是程式設計簡單,結構清晰 缺點是需要語言的支援。協程最大優勢 輕量級 可以輕鬆建立上百萬個而不會導致系統資源衰竭...

Go 高階併發

譯文出處 譯者 咔嘰咔嘰 校對者 fivezh 如果你曾經使用過 go 一段時間,那麼你可能了解一些 go 中的併發原語 這些語言特性和包組合在一起,為構建高併發的應用程式提供了豐富的工具集。你可能還沒有發現在擴充套件庫 golang.org x sync 中,提供了一系列更高階別的併發原語。我們將...

go總結 併發

主要學習了菜鳥程式設計 go 併發 總結 go func 可以起乙個執行緒,輕量級的執行緒,執行緒之間採用chan進行傳值。package main import fmt func sum s int c chan int c sum 把 sum 傳送到通道 c func main 緩衝區大小為2 ...