3 回答
TA贡献1810条经验 获得超4个赞
这些类型的问题通常是以下结果:
过早的接口
假界面,或“气泡包装”(请参阅我的咆哮 这里)
并行接口
您遇到的错误与第 3 个问题最具体相关,但每个错误都存在于此处的示例设计中。
好的接口应该传达(以它们的名称和方法签名)一组行为。接口的名称应由它包含的方法暗示,因为该名称只是应该捕获该行为的本质。
为此目的似乎唯一需要的接口是:
type Mover interface {
Move() MoveResult
}
对于 MoveResult,您可以执行此操作(如果您愿意,可以使用 int 交换 float):
type MoveResult struct {
Distance, Height float64
}
给定以下假设,此类型可以作为结构很好地发挥作用:
移动结果只是数据点(它们不需要是动态的;您可以设置值并保留它们)
“额外”数据(如高度)在未指定时以零值正确运行。
现在,实现 bird 类型:
type Bird struct {
// some internal data
}
func (b *Bird) Move() MoveResult {
// some movement calculations
return MoveResult{Distance: howFar, Height: howHigh}
}
现在实现 foo:
func foo(m Mover) float64 {
return m.Move().Distance
}
现在主要使用它:
func main() {
foo(&Bird{})
}
现在我们可以将其他类型的s添加到程序中,并毫无问题地使用它们。Moverfoo
解决您的注释,其中 和 都是外部的,您无法修改它们:AnimalAnimalMoveResultfoo
我如何用我的理解提出问题:有这个函数,旨在接受一个名为的接口,其特征是它如何返回专有类型。您希望将类型用作 ,但无法将所需的所有行为都适合该专有返回类型。fooAnimalBirdAnimal
那么如何解决这个问题呢?
实现您自己的、更广泛的返回类型
type birdMoveResult struct {
// some internal data
}
func (r birdMoveResult) GetDistance() int {
// get the distance
}
func (r birdMoveResult) GetHeight() int {
// get the height
}
现在,实现 Bird 类型
type Bird struct {
// some internal data
}
func (b *Bird) Move() AnimalMoveResult {
var result birdMoveResult
// calculate the move result
return birdMoveResult
}
请注意,返回类型,因此现在将满足接口。我们能够做到这一点,因为满足类型,所以在这里返回它是合法的。MoveAnimalMoveResultBirdAnimalbirdMoveResultAnimalMoveresult
剩下的问题是 s 方法缩小了宽界面的范围,我们实际上已经丢失了您添加的新功能。为了在仍然满足接口的同时将其取回,我们根本无法更改方法签名。以下是 2 种可能的解决方法。BirdMoveAnimalMove
使用 bird 类型时,您可以对结果进行类型断言,以访问额外的方法
var b Bird
// ...
height := b.Move().(birdMoveResult).GetHeight()
向中添加一个新方法,该方法返回更广泛的类型,使现有方法具有相同的签名BirdMove
func (b *Bird) MoveFull() birdMoveResult {
var result birdMoveResult
// calculate the move result
return birdMoveResult
}
func (b *Bird) Move() AnimalMoveResult {
return b.MoveFull()
}
height := b.MoveFull().GetHeight()
这些都可以工作,这主要是偏好问题。
TA贡献1817条经验 获得超14个赞
在Go中,有没有办法使用方法实现接口,其中实现中相应方法的返回类型是“比”预期的返回类型“宽”的?
不。方法签名必须按字面匹配。围棋没有协变或逆变的概念。
TA贡献2012条经验 获得超12个赞
Go的类型系统使用类型名称匹配。即使使用不同的类型名称返回相同的接口,此操作也会失败。
但是,您可以声明该方法以满足接口,但返回可以类型断言的更广泛的实现。
- 3 回答
- 0 关注
- 75 浏览
添加回答
举报