9 筆記go語言 方法和介面

2021-08-08 20:47:46 字數 3939 閱讀 8536

9.筆記go語言——方法和介面

go 沒有類。然而,仍然可以在結構體型別上定義方法。

方法接收者 出現在 func 關鍵字和方法名之間的引數中。

package main

import (

"fmt"

"math" )

type vertex struct

func (v *vertex) abs() float64

func main()

fmt.println(v.abs()) }

執行:你可以對包中的 任意 型別定義任意方法,而不僅僅是針對結構體。

但是,不能對來自其他包的型別或基礎型別定義方法。

package main

import (

"fmt"

"math" )

type myfloat float64

func (f myfloat) abs() float64

returnfloat64(f) }

func main()

執行結果:

1.4142135623730951

方法可以與命名型別或命名型別的指標關聯。

剛剛看到的兩個 abs 方法。乙個是在 *vertex 指標型別上,而另乙個在 myfloat 值型別上。有兩個原因需要使用指標接收者。首先避免在每個方法呼叫中拷貝值(如果值型別是大的結構體的話會更有效率)。其次,方法可以修改接收者指向的值。

嘗試修改 abs 的定義,同時 scale 方法使用 vertex 代替 *vertex 作為接收者。

當 v 是 vertex 的時候 scale 方法沒有任何作用。`scale` 修改 `v`。當 v 是乙個值(非指標),方法看到的是 vertex 的副本,並且無法修改原始值。

abs 的工作方式是一樣的。只不過,僅僅讀取`v`。所以讀取的是原始值(通過指標)還是那個值的副本並沒有關係。

package main

import (

"fmt"

"math" )

type vertex struct

func (v *vertex) scale(f float64)

func (v *vertex) abs() float64

func main()

v.scale(5)

fmt.println(v,v.abs()) }

執行:& 25

介面型別是由一組方法定義的集合。

介面型別的值可以存放實現這些方法的任何值。

注意: 列子**的 22 行存在乙個錯誤。由於 abs 只定義在 *vertex(指標型別) 上,所以 vertex(值型別) 不滿足 `abser`。

package main

import (

"fmt"

"math" )

type abser inte***ce

func main()

a =f  // a myfloat

實現了abser

a =&v // a *vertex

實現了abser

// 下面一行,

v 是乙個

vertex

(而不是

*vertex)

// 所以沒有實現

abser。

a = v

fmt.println(a.abs()) }

type myfloat float64

func (f myfloat) abs() float64

returnfloat64(f) }

type vertex struct

func (v *vertex) abs() float64

#command-line-arguments

.\hello.go:22:cannot use v (type vertex) as type abser in assignment:

vertexdoes not implement abser (abs method has pointer receiver)

exitstatus 2

型別通過實現那些方法來實現介面。沒有顯式宣告的必要;所以也就沒有關鍵字「implements「。

隱式介面解藕了實現介面的包和定義介面的包:互不依賴。

因此,也就無需在每乙個實現上增加新的介面名稱,這樣同時也鼓勵了明確的介面定義。

包 io 定義了 reader 和 `writer`;其實不一定要這麼做。

package main

import (

"fmt"

"os" )

type reader inte***ce

type writer inte***ce

type readwriter inte***ce

func main()

執行:hello,writer

stringers

乙個普遍存在的介面是 fmt 包中定義的 stringer。

type stringer struct

func (p person) string() string

func main()

z :=person

fmt.println(a,z) }

執行:arthurdent (42 years) zaphod beeblebrox (9001 years)

go 程式使用 error 值來表示錯誤狀態。

與 fmt.stringer 類似,`error` 型別是乙個內建介面:

type error inte***ce

func (e *myerror) error() string

func run() error }

func main() }

執行:at2016-06-16 23:10:58.7118248 +0800 cst, it didn't work

io 包指定了 io.reader 介面, 它表示從資料流結尾讀取。

go 標準庫包含了這個介面的許多實現, 包括檔案、網路連線、壓縮、加密等等。

io.reader 介面有乙個 read 方法:

func (t) read(b byte) (n int, err error)

read 用資料填充指定的位元組 slice,並且返回填充的位元組數和錯誤資訊。 在遇到資料流結尾時,返回 io.eof 錯誤。

例子**建立了乙個 strings.reader。 並且以每次 8 位元組的速度讀取它的輸出。

package main

import (

"fmt"

"io"

"strings" )

func main() }

}執行:

n= 8 err = b = [72 101 108 108 111 44 32 82]

b[:n]= "hello, r"

n= 6 err = b = [101 97 100 101 114 33 32 82]

b[:n]= "eader!"

n= 0 err = eof b = [101 97 100 101 114 33 32 82]

b[:n]= ""

包 http 通過任何實現了 http.handler 的值來響應 http 請求:

packageimage 定義了 image 介面:

package image

type image inte***ce

執行:(0,0)-(100,100)

00 0 0

55 筆記go語言 go型別

很多人喜歡go語言的原因是簡單。go語言的型別也是設計的如此簡單。go語言預設定義了一些型別如boolean,numeric和string.這些預定義的型別用於構建其他複雜的型別,例如array,struct,pointer,slice,map,channel等。型別可以有乙個名字也可以沒有名字。命...

10 筆記go語言 併發

10.筆記go語言 併發 goroutine 是由 go 執行時環境管理的輕量級執行緒。go f x,y,z 開啟乙個新的 goroutine 執行 f x,y,z f x y 和 z 是當前 goroutine中定義的,但是在新的 goroutine 中執行 f goroutine 在相同的位址空...

34 筆記go語言 內建函式

34.筆記go語言 內建函式 預定義了少數函式,這意味著無需引用任何包就可以使用它們。close 用於channel通訊。使用它來關閉channel.delete 用於在map中刪除例項。len和cap 可用於不同的型別,len用於返回字串 slice和陣列的長度。new 用於各種型別的記憶體分配。...