rtu*_*tut 6 struct interface go
我有带接口的代码:
package main
import (
"math"
"fmt"
)
type Circle struct {
x, y, r float64
}
type Rectangle struct {
x1, y1, x2, y2 float64
}
type Figure interface {
Area() float64
}
func (c *Circle) Area() float64 {
return math.Pi * c.r * c.r
}
func (r *Rectangle) Area() float64 {
return math.Abs(r.x2 - r.x1) * math.Abs(r.y2 - r.y1)
}
func main() {
figures := make([]Figure, 0)
figures = append(figures, &Circle{0, 0, 10})
figures = append(figures, &Rectangle{0, 0, 10, 20})
for _, figure := range figures {
fmt.Print(figure.Area(), "\n")
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
314.159265
200
Run Code Online (Sandbox Code Playgroud)
和只为我的结构编写方法的代码:
package main
import (
"math"
"fmt"
)
type Circle struct {
x, y, r float64
}
type Rectangle struct {
x1, y1, x2, y2 float64
}
func (c *Circle) Area() float64 {
return math.Pi * c.r * c.r
}
func (r *Rectangle) Area() float64 {
return math.Abs(r.x2 - r.x1) * math.Abs(r.y2 - r.y1)
}
func main() {
c := Circle{0,0,10}
r := Rectangle{0,0,10,20}
fmt.Print(c.Area(), "\n")
fmt.Print(r.Area(), "\n")
}
Run Code Online (Sandbox Code Playgroud)
和相同的输出:
314.1592653589793
200
Run Code Online (Sandbox Code Playgroud)
当我使用接口时,我有接口声明形式的额外代码。如果接口在 Go 中完美地实现了多态性,那么为什么结构体的方法呢?接口加什么,区别在哪里?可能是我的例子不好。谢谢!
你应该在你自己的代码中看到它:在第一种情况下,你可以处理所有的unity,作为Figureand 的值,所以你可以将它们存储在一个切片(类型[]Figure)中,并覆盖它们并调用它们的Area()方法。
在没有接口的第二种情况下,您没有将它们存储在切片中,也没有使用循环,而是必须在每个实例上Area() 手动调用。
没有接口,就没有类型可以为其创建切片并将每个存储在其中。唯一的选择是interface{}类型:
figures := make([]interface{}, 0)
figures = append(figures, &Circle{0, 0, 10})
figures = append(figures, &Rectangle{0, 0, 10, 20})
Run Code Online (Sandbox Code Playgroud)
但是当覆盖它们时,您将无法调用它们的Area()方法,因为该interface{}类型没有定义任何方法。
for _, figure := range figures {
fmt.Print(figure.Area(), "\n") // COMPILE-TIME error
}
Run Code Online (Sandbox Code Playgroud)
如果你只有 2 个实例,你可以Area()手动调用它们的方法,它会更短。但是如果你有一百或一千...
没有重复接口的优点,请参阅可能的重复:
为什么在 Golang 中需要接口?