Data type interface - cruisechang/wiki-golang GitHub Wiki
Basics
interface 是type中重要的一類。他體現一組固定的methods。
interface variable能儲存任何具體的值,該值是實作了這個interface的methods。
例如 io.Reader / io.Writer from io package.
// Reader is the interface that wraps the basic Read method.
type Reader interface {
Read(p []byte) (n int, err error)
}
// Writer is the interface that wraps the basic Write method.
type Writer interface {
Write(p []byte) (n int, err error)
}
任何type只要實作Read(p []byte) (n int, err error),就可稱為它實作io.Reader。
而你只要自訂一個io.Reader的變數,就可儲存這個type。
但是這個io.Reader變數只能呼叫Read這個method。
var r io.Reader
r = os.Stdin //can store os.Stdin
r = bufio.NewReader(r) //can store bufio.NewReader(r)
r = new(bytes.Buffer) //can store bytes.Buffer
// and so on
interface type
- interface type variable儲存兩個部分:實體的value及value's type descriptor.
value就是底層實際資料物件,它本身實作了這個interface的methods set。
type descriptor說明底層實際物件的詳細type。
var r io.Reader
tty, err := os.OpenFile("/dev/tty", os.O_RDWR, 0)
if err != nil {
return nil, err
}
r = tty
r儲存了the (value, type) pair, (tty, *os.File).
value=tty
type=*os.File
這個type實作了許多io.Reader沒有的method,但是我們只能呼叫io.Reader有的Read這個。
也因為r的type descriptor有完整的*os.File描述,所以我們可以轉型,
把r從io.Reader轉成io.Writer。因為*os.File type,實作了io.Writer的Write method.
var w io.Writer
w = r.(io.Writer)
結論就是interface type決定的該interface variable包含哪些methods,但是variable內實際的資料包括的methods可能更多。
Empty interface type : interface{}
它體現了一組空個methods,所以interface{}的變數可以儲存任何type,無論這個type有沒有methods。
這不代表interface type是dynamic type,實際上它是有固定類型的,它的類型就是interface{},
即便他儲存的資料在runtime改變了type,它本身的type是不變的。
承上例,我們可以轉型成interface{}
var empty interface{}
empty=w
這時不需要assertion,因為interface{} type 能接受任何type。
empty同樣也儲存了(value, type) pair, (tty, *os.File)。
我們隨時可以把empty轉回 empty(io.Writer)