package main
import "fmt"
type Phone interface {
call()
sales() int
}
type NokiaPhone struct {
price int
}
func (nokiaPhone NokiaPhone) call() {
fmt.Println("I am Nokia, I can call you!")
}
func (nokiaPhone NokiaPhone) sales() int {
return nokiaPhone.price
}
type IPhone struct {
price int
}
func (iPhone IPhone) call() {
fmt.Println("I am iPhone, I can call you!")
}
func (iPhone IPhone) sales() int {
return iPhone.price
}
func main() {
var phones = [5]Phone{
NokiaPhone{price: 350},
IPhone{price: 5000},
IPhone{price: 3400},
NokiaPhone{price: 450},
IPhone{price: 5000},
}
var totalSales = 0
**for _, phone := *range phones* {
totalSales += phone.sales()
}**
fmt.Println(totalSales)
}
我不知道内部运行的“范围电话”。我只知道'电话'是以'[5]电话'顺序运行的,我想知道golang如何识别iphone或NokiaPhone。
谢谢,请原谅我蹩脚的英语。
答案 0 :(得分:0)
接口是合同的声明,即实现实例必须支持的行为。通过提供在接口上定义的方法,Go中的struct
自动实现该接口,并且可以在存在基于接口的声明的任何地方使用该接口来代替该接口。这与Java或C ++等许多其他语言略有不同,其中实例必须显式声明它实现的接口和扩展的类。在运行时,代码将获得一个具体实例并执行该实例的方法。对于编码器或声明并不重要,重要的是实例将具有接口上定义的方法,并且可以调用该方法,因此代码可以用通用接口术语编写。
接受接口并提供结构/实例的想法是控制和依赖注入反转的核心。
这正是你的例子中发生的事情。 NokiaPhone
和IPhone
通过提供在接口Phone
上声明的方法来实现Phone
接口。当涉及循环时,在每次迭代时,从数组中取出一个具体实例,对于该实例类型,查找代码中要求的方法,因此现在执行,并执行。它在Go,Java,C ++(使用虚方法)和许多其他支持继承或接口/实现模式的语言中以相同的方式工作。