1. 程式人生 > 其它 >go語言io reader_Go語言學習入門篇用Go解決現代程式設計難題

go語言io reader_Go語言學習入門篇用Go解決現代程式設計難題

技術標籤:go語言io reader

Go語言開發團隊花了很長時間來解決當今軟體開發人員面對的問題。開發人員在為專案選擇語言時,不得不在快速開發和效能之間做出選擇。C和C++這類語言提供了很快的執行速度,而Ruby和Python這類的語言則擅長快速開發。Go語言在這兩者之間架起了橋樑,不僅提供了高效能的語言,同時也讓開發更快速。作為一門語言,Go不僅定義了能做什麼,還定義了不能做什麼。Go語言簡潔到只有幾個關鍵字。Go語言的編譯器非常快,所以,Go開發者能顯著減少專案構建時間。另外Go語言內建併發機制,所以不用使用特定的執行緒庫。Go語言簡單且高效。Go語言還自帶垃圾回收器,不需要使用者管理記憶體。

420111439cff2afbeefe46e7fb541898.png

總結一句話:Go語言兼顧開發速度與執行速度的語言。這個可能也是重新發明的輪子的原因吧!

關鍵特性如下:

1、開發速度

Go語言使用了更加智慧的編譯器,並簡化了解決依賴的演算法,最終提供了趕快的編譯速度。在現代硬體上,編譯整個Go語言的原始碼樹只需要20秒。 2、併發Go語言對併發的支援是這門語言最重要的特性之一。goroutine很像執行緒,但是它的開銷遠小於執行緒,使用它需要的程式碼更少。通道(channel)是內建的資料結構,可以讓使用者在不同的goroutine之間同步傳送具有型別的訊息。這個特性細節如下:

2.1、goroutine

Go語言中會使用同一個執行緒來執行多個goroutine,使用net/http庫直接使用了內建的goroutine。如果使用C或者Java,不得不寫大量的額外程式碼來使用執行緒。
func log( msg string){//這裡是記錄一些日誌的程式碼}//其他程式碼裡發生錯誤,呼叫日誌函式golog("發生了錯誤")

2.2、通道

通道是一種資料結構,可以通過goroutine之間進行安全的資料通訊。通道可以幫助使用者避免在其他語言裡常見的共享記憶體的問題。在其他語言中,如果使用全域性變數或者共享記憶體,必須使用複雜的鎖機制來防止對同一個變數的不同步修改。為了解決這個問題,通道提供了一種新的模式,從而保證併發修改時的資料安全。通道這個模式保證同一時刻只會有一個goroutine修改資料。通道用於在幾個執行的goroutine中間傳送資料。 3、Go語言的資料型別

Go語言提供了靈活的、無繼承的型別系統,無需降低效能就能最大程度上覆用程式碼。這個系統依然支援面向物件開發,而且避免了傳統面向物件的效能問題。Go語言使用組合(Composition)設計模式,只需要將一個型別嵌入到另外一個型別,就能複用所有的功能。另外Go語言還具有獨特的介面實現機制。

3.1、型別簡單Go語言通過結構體或者基於已有型別宣告自定義型別。 結構體型別結構體型別通常包含一組帶型別的欄位,每個欄位型別既可以是內建型別,也可以是其他自定義的型別。Go語言的自定義型別看起來很像C語言的結構體,用起來也很相似。不過Go語言的型別可以什麼操作型別資料的方法。
type User struct {    id int    name string    email string}//宣告結構體型別變數並初始化零值(結構體中的每個欄位都會用零值初始化)var u1 User//賦值u1.id = 1u1.name = "zhangsan1"u1.email="[email protected]"
還可以用如下方式在變數宣告時進行初始化賦值:
//這種形式對宣告順序沒有要求u2 := User{    id:2,    name:"zhangsan2",    email:"[email protected]",}//這種形式要和結構體宣告中的欄位順序一致u3 := User{id:3, name:"zhangsan3", email:"[email protected]"}

基於已有型別

另一種宣告使用者自定義型別的方法是基於一個已有的型別,使用這種宣告型別的方法,從內建型別中創建出更多型別,賦予更高階的功能。

type Interger int
Go認為這兩種型別是不同的型別,不同型別不能相互賦值,也不會對不同型別的值做隱式轉換。3.2、Go介面 在Go語言中,的介面有下面幾 個特點:
  • 可以包含0個或多個方法

  • 只定義方法宣告,不包含實現

  • 實現介面不需要顯式的宣告,只需實現相應方法即可

介面定義

type Namer interface {    method1(param_list) return_list    method2(param_list) return_list    ...}

這裡的 Namer 就是介面的名字,只要符合識別符號的規則即可。不過,通常約定的介面的名字最好以 er, r, able 結尾(視情況而定),這樣一眼就知道它是介面。

介面實現

在 Go語言 中實現介面很簡單,不需要顯式的宣告實現了某個介面,想要實現某個介面,只需要實現介面中的所有方法即可。

package mainimport "fmt"import "math"type Shaper interface {    Area() float32    Circumference() float32}type Rect struct {    Width float32    Height float32}type Circle struct {    Radius float32}func (r Rect) Area() int {    return r.Width * r.Height}func (r Rect) Circumference() int {    return 2 * (r.Width + r.Height)}func (c Circle) Area() int {    return math.Pi * c.Radius * c.Radius}func (c Circle) Circumference() int {    return math.Pi * 2 * c.Radius}func main() {    r := Rect{10, 20}    fmt.Printf("Rect w: %f, d: %f, Area: %f, Circumference: %f", r.Width, r.Height, r.Area(), r.Circumference())    c := Circle{5}    fmt.Printf("Circle r: %f, Area: %f, Circumference: %f", c.Radius, c.Area(), c.Circumference())    }

上面我們定義了一個 Shaper 的介面,其中包含兩個方法 Area 和 Circumference,分別用來計算面積和周長。然後我們定義了兩個結構體 Rect, Circle 並分別實現了這兩個方法。但是上面的程式似乎並沒有體現出介面和兩個實現型別的關係,下面我們將他們關聯起來使用:

func showInfo(s Shaper) {    fmt.Printf("Area: %f, Circumference: %f", s.Area(), s.Circumference())}
注意,這裡方法的引數是一個介面型別的,因此我們可以將實現介面的型別的例項傳遞進去,像下面這樣:
r := Rect{10, 20}showInfo(r)c := Circle{5}showInfo(c)

獲取實現介面的實際型別

在上面的 showInfo 中我們傳入了介面型別的物件,如果將實現了介面的型別傳遞進去,那麼會將實際型別的其他特性掩蓋住,因此通常我們會想要獲取其真正的型別, 可以使用下面的方法:

func showInfo(s Shaper) {    switch s.(type) {    case Rect:        fmt.Println("This is Rect")    case Circle:        fmt.Println("This is Circle")            }    fmt.Printf("Area: %f, Circumference: %f\n", s.Area(), s.Circumference())}

標準庫中的常用介面

io.Reader 和 io.Writer

這兩個介面定義了實現io功能的基本操作,因此某種型別只要實現了這兩個介面就可以進行io操作。

例如,Reader 介面的定義為:

type Reader interface {    Read(p []byte) (n int, err error)}

類似的實現了 Reader 介面的物件有: os.Stdout, os.Stderr, os.File 等等。可以使用 Read方法向其中寫入資料。

4、記憶體管理

Go語言的垃圾回收會有一些額外的開銷,但是程式設計時,能顯著降低開發難度。Go語言把無趣的記憶體管理交給專業的編譯器去做,而讓程式設計師專注於業務開發。

5、Go版本HelloWorld

讓我們看看用Go語言如何編寫經典的HelloWorld!

packagemain//Go語言組織成包 import"fmt"//引入外部庫funcmain(){//main函式是程式執行入口fmt.Println("HelloWorld!")}
6、小結
  • Go語言是現代的、快速的、帶有強大的標準庫

  • Go語言內建對併發的支援

  • Go語言使用介面作為程式碼複用的基礎模組