要点
- interface关键字用来定义一个接口
- Go没有implements、extends等关键字
- 实现一个接口的方法就是直接定义接口中的方法
- 要实现多态,就要用指针或&object语法
示例
package main
import "fmt"
import "math"
type Shape interface {
area() float64
}
type Circle struct {
r float64
}
func (c *Circle) area() float64 {
return math.Pi * c.r * c.r
}
type Rectangle struct {
length, width float64
}
func (r *Rectangle) area() float64 {
return r.length * r.width;
}
func totalArea(shapes ... Shape) (total float64) {
total = 0
for _, shape := range shapes {
total += shape.area()
}
return
}
func main() {
circle := Circle{r:5}
ractangle := Rectangle{3, 4}
/*.\helloworld.go:40: cannot use circle (type Circle) as type Shape in argument to totalArea:
Circle does not implement Shape (area method has pointer receiver)
fmt.Println(totalArea(circle, ractangle)) // L40 */
fmt.Println(totalArea(&circle, &ractangle))
}
再论传值与传引用
在上面的代码中,注意到totalArea()声明的类型是Shape,但在后面调用的时候传入的是&cirlce这种。因此,冒出来一个疑问:为什么一个是“对象”,一个是地址(指针),却能够运行呢?
曾经考虑过是否Go和Java一样,存在基本类型和对象(用户自定义等)传值、传引用的区别。。。为此,有下面一系列的验证。
基本类型
package main
import "fmt"
func foo(i int) {
fmt.Println(i)
}
func main() {
i := 5
foo(i)
/* cannot use &i (type *int) as type int in argument to foo
foo(&i)*/
}
结构体类型
package main
import "fmt"
type Data struct {
x int
}
func (data* Data) debug() {
fmt.Println(data.x)
}
func foo(data Data) {
data.x++
}
func bar(data *Data) {
data.x++
}
func main() {
data := Data{1}
data.debug()
// cannot use &data (type *Data) as type Data in argument to foo
//foo(&data)
foo(data)
data.debug()
}
特殊的interface
package main
import "fmt"
type Debugger interface {
debug()
}
type Data struct {
x int
}
func (data* Data) debug() {
fmt.Println(data.x)
}
func foo(debugger Debugger) {
debugger.debug()
}
func bar(debugger *Debugger) {
//debugger.debug undefined (type *Debugger is pointer to interface, not interface)
//debugger.debug()
(*debugger).debug()
//syntax error: unexpected >, expecting expression
//debugger->debug()
}
func main() {
data := Data{1}
data.debug()
/*cannot use data (type Data) as type Debugger in argument to foo:
Data does not implement Debugger (debug method has pointer receiver)*/
//foo(data)
foo(&data)
/*cannot use &data (type *Data) as type *Debugger in argument to bar:
*Debugger is pointer to interface, not interface*/
//bar(&data)
/*cannot use data (type Data) as type *Debugger in argument to bar:
*Debugger is pointer to interface, not interface*/
//bar(data)
}
约定俗成(???)
假定接口为:
type I interface {...}
实现该接口的类为:
type Concreate struct {...}
仅依赖于接口的函数:
func foo(i I) {...}
调用约定:
concreate := Concreate {...}
foo(&concreate)
有疑问加站长微信联系(非本文作者)