Interface 可以說是 golang 的精髓之一。golang interface 特殊的語法以及概念也是工程師常常犯錯的地方。此題只是用來釐清自己的概念。
題目
請問以下程式輸出結果為何
package main
import "fmt"
type S struct{
val int
}
func (s S) F() {}
type IF interface {
F()
}
func InitType() S {
var s S
return s
}
func InitPointer() *S {
var s *S
return s
}
func InitEfaceType() interface{} {
var s S
return s
}
func InitEfacePointer() interface{} {
var s *S
return s
}
func InitIfaceType() IF {
var s S
return s
}
func InitIfacePointer() IF {
var s *S
return s
}
func main() {
// fmt.Println(InitType() == nil) // type mismatch
fmt.Println(InitPointer() == nil)
fmt.Println(InitEfaceType() == nil)
fmt.Println(InitEfacePointer() == nil)
fmt.Println(InitIfaceType() == nil)
fmt.Println(InitIfacePointer() == nil)
}
回歸基本
在回答問題之前先複習什麼是 Interface Satisfaction
和 Interface Values
,分別在 The Go Programming Language 章節 7.3 和 7.5。
Interface Satisfaction
直接給出書上的解釋,這兩段句子及範例程式已經淺顯易懂,不多作解釋:
A type satisfies
an interface if it possesses all the methods the interface requires.
The assignability rule for interfaces is very simple: an expression may be assigned to an interface only if its type satisfies the interface.
/*
package io
type Writer interface {
Write(p []byte) (n int, err error)
}
*/
var w io.Writer
w = os.Stdout // OK: *os.File has Write method
w = new(bytes.Buffer) // OK: *bytes.Buffer has Write method
w = time.Second // compile error: time.Duration lacks Write method
Interface Values
The Go Programming Language 7.5 第一句開門見山地馬上給出概念:
Conceptually, a value of an interface type, or interface value
has two components, a concrete type and a value of that type . These are called the interface’s dynamic type
and dynamic value
.
並且用一個例子做出了很棒的解釋:
var w io.writer
w = os.Stdout
w = new(bytes.Buffer)
w = nil
另一個例子:
var w io.Writer
var buf *bytes.Buffer
w = buf
fmt.Printf("%v %T\n", w, w) // <nil> *bytes.Buffer
if w != nil {
fmt.Println("w not nil") // This line will be executed
}
若 w != nil
要成立則 dynamic type
和 dynamic value
皆為 non-nil
才會成立。
因為 w 的 dynamic value 是 *bytes.Buffer
不為 nil
所以 w != nil
就會成立。
解答
題目的 Line 43, 44 難度不高,直接跳過 剩下的看下圖
Line 50 牽扯到了 method set
的細節,留著下篇解釋,可以參考 Reference 1, 2