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 用於各種型別的記憶體分配。...