Go的介面特色為隱式介面(implicit interfaces),也就是說type實作介面的全部方法即實作了該介面,而非已明確宣告的方式,所以無法一眼從程式碼或API文件判斷一個type是否實作了某介面(去核對介面的每個方法簽章是否相同是很痛苦的事),可利用下面方法來確認。
若要知道type是否實作某介面,可利用Go的編譯器來判斷,也就是直接把type的值塞到介面的變數看是否出現出現錯誤。
例如下面確認型態T
是否為介面I
的實作。,若T
未實作I
則出現編譯錯誤:cannot use (T literal) (value of type T) as I value in variable declaration: T does not implement I (missing method <method>)
。
var _ I = T{} // check value of T implements I
var _ I = new(T) // check pointer of T implments I
例如用以上技巧來檢視Go寫出資料用的io.Writer
介面的實作型態包括os.File
、bytes.Buffer
、strings.Builder
。
main.go
package main
import (
"bytes"
"io"
"os"
"strings"
)
func main() {
var w1 io.Writer = new(os.File)
var w2 io.Writer = new(bytes.Buffer)
var w3 io.Writer = new(strings.Builder)
...
}
但要怎麼知道一個介面有哪些實作或該用哪些實作?答案是經驗的累積,或是說對Go標準函式庫的掌握。例如寫出檔案的時候為什麼知道io.Writer
參數要用os.File
?因為這就是標準函式庫提供的工具,若不知道工具的存在即無法知道有什麼實作可用。
沒有留言:
張貼留言