我希望能通过一个简单的示例来了解Go语言中接口类型的使用。
我已经阅读了网络文档,但是仍然不理解。
我希望能通过一个简单的示例来了解Go语言中接口类型的使用。
我已经阅读了网络文档,但是仍然不理解。
Go接口背后的理念是鸭子类型。简而言之:如果你看起来像一只鸭子,叫声像一只鸭子,那么你就是一只鸭子。这意味着,如果您的对象实现了所有鸭子的特征,那么使用它作为鸭子应该是没有问题的。以下是一个例子:
package main
import (
"fmt"
)
type Walker interface {
Walk() string
}
type Human string
type Dog string
func (human Human) Walk() string { //A human is a walker
return "I'm a man and I walked!"
}
func (dog Dog) Walk() string { //A dog is a walker
return "I'm a dog and I walked!"
}
//Make a walker walk
func MakeWalk(w Walker) {
fmt.Println(w.Walk())
}
func main() {
var human Human
var dog Dog
MakeWalk(human)
MakeWalk(dog)
}
在这里,一个Human
是一个Walker
,而一个Dog
也是一个Walker
。为什么?因为他们都......嗯......走路
。它们都实现了Walk() string
函数。因此,你可以在它们身上执行MakeWalk
。
当你希望不同类型以相同的方式行为时,这非常有用。一个实际的例子是文件类型对象(套接字、文件对象)-你需要一个Write和一个Read函数。然后你可以以相同的方式使用Write和Read来独立于它们的类型-这很酷。
这是另一个工作示例,展示了接口和结构之间的交互
package main
import "fmt"
type Info interface {
Noofchar() int
Increment()
}
type Testinfo struct {
noofchar int
}
func (x *Testinfo) Noofchar() int {
return x.noofchar
}
func (x *Testinfo) Increment() {
x.noofchar++
}
func main(){
var t Info = &Testinfo{noofchar:1}
fmt.Println("No of char ",t.Noofchar())
t.Increment()
fmt.Println("No of char ",t.Noofchar())
}
在@AlexPlugaru和https://stackoverflow.com/a/18854285/12817546的卓越答案之外,还要补充@NickCraig-Wood的意见。
package main
import . "fmt"
func main() {
cat("Bird").Eat() // Bird
eater.Eat(cat("Milk")) // Milk
Break(cat("Fish")) // Fish
Lunch().Eat() // Mice
Tea(true) // Bird
}
type cat string
type eater interface{ Eat() }
func (c cat) Eat() { Println(c) }
func Break(e eater) { e.Eat() }
func Lunch() eater { return cat("Mice") }
func Tea(b bool) {
if b {
cat("Bird").Eat()
}
}
结构体或任何其他具体类型上的方法是静态解析的。请参见cat("Bird").Eat()
和eater.Eat(cat("Milk"))
。唯一具有动态分派方法的方式是通过接口。请参见Break(cat("Fish"))
和Lunch().Eat()
,http://www.golangbr.org/doc/faq#How_do_I_get_dynamic_dispatch_of_methods。
Tea(true)
调用一个方法而不使用接口进行动态调度。请参见https://talks.golang.org/2014/taste.slide#19。但是,接口-按设计和约定-鼓励我们编写可组合的代码。请参见https://talks.golang.org/2014/go4gophers.slide#21。
Break(cat("Fish"))
和Lunch().Eat()
,https://code.tutsplus.com/tutorials/lets-go-object-oriented-programming-in-golang--cms-26540。package main
import(
"fmt"
"math"
)
func main(){
rect := Rectangle{20,50}
cir := Circle{2}
//According to object you passed in getArea method,
// it will change the behaviour and that is called Polymorphism.
fmt.Println("Area of Rectangle =",getArea(rect))
fmt.Println("Area of Circle =",getArea(cir))
}
//Interface Shape with one area method
type Shape interface{
area() float64
}
//Creating Rectangle and Circle type using struct
type Rectangle struct{
height float64
width float64
}
type Circle struct{
radius float64
}
//Receiver function, which implements struct's area methods
func(r Rectangle) area() float64{
return r.height * r.width
}
func(c Circle) area() float64{
return math.Pi * math.Pow(c.radius,2)
}
//passing interface as arguments, which can calculate shape of any mentioned type
//All the struct are tied together because of the Interface.
func getArea(shape Shape) float64{
return shape.area()
}