软件包term
:
type Num interface {
IsNeg() bool
Add(Num) Num
}
type Term struct {
Coeff Num
Var string
}
外部包装
frac64
type Frac64 struct {
Numer uint64
Denom uint64
Neg bool
}
func (a Frac64) Add(b Frac64) Frac64 { // Pretend this is implemented }
软件包
client
type Frac Frac64
func (f Frac) IsNeg() bool { return f.Neg }
func (f Frac) Add(v Num) Num { // Call Frac64's Add here? }
我将如何实现
Add
的Frac
,以便它实现Num
接口(interface)?编辑:附加信息
外部软件包
frac64
只是一个示例。我不打算使用它。这里的目标(我应该更清楚)是我的包公开使用
Term
作为其两个属性之一的struct Num
。现在,我希望我的软件包的用户能够使用big.Rat
或Frac64
或int64
或rune
或他们想要的任何东西,只要他们实现Num
接口(interface)即可。我遇到的问题是尝试为已经具有与
Num
中的函数同名的函数的结构实现Num
接口(interface)。这就是Frac64
出现的地方。我还可以使用big.Rat
为例,因为它也有一个名为Add
的函数。我不能更改
Frac64
(或big.Rat
)的实现,也不能使用Add
函数扩展它,因为它已经存在。这就是为什么我尝试使用type Frac Frac64
(或type Frac big.Rat
),然后尝试扩展Frac
的原因。但是我无法为
Num
实现Frac
,因为我无法从Frac64
的Add
函数调用Frac
的Add
。 最佳答案
您可以使用embedding解决此问题...
type Frac struct {
*Frac64
}
现在
Frac
可以使用Frac64
的方法,而无需重写它们。// `Frac.New(numer, denom, bool)` would remove this implementation leak.
foo := Frac{
&Frac64 {
Numer: 45,
Denom: 99,
Neg: false,
},
}
fmt.Println(foo.IsNeg())
但是,当我们尝试使用
Add
时有一个障碍。// cannot use foo (type Frac) as type Frac64 in argument to foo.Frac64.Add
fmt.Println(foo.Add(foo))
嵌入仅适用于继承方法。当用作参数时,它不会为您使用嵌入式引用,您必须显式地执行此操作。
真正的问题是
func (a Frac64) Add(b Frac64) Frac64
不满足Num接口(interface)。如果我们修复它工作正常,因为Frac
实现Num
。func (a Frac64) Add(b Num) Num {
return Frac64{
Numer: 12,
Denom: 23,
Neg: false,
}
}
可以,但是从更特定的类型
Frac
来构建一个较不特定的类型Frac64
是很尴尬的。从这里开始,
Frac
是带有某些扩展名的Num
变得更加明显。 Frac
应该是扩展Num
并添加分子和分母的接口(interface)。 Frac64
成为实现Frac
的类型。type Num interface {
IsNeg() bool
Add(Num) Num
}
type Frac interface {
Numer() uint
Denom() uint
Num
}
type Frac64 struct {
numer uint64
denom uint64
neg bool
}
func (f Frac64) IsNeg() bool {
return f.neg
}
func (f Frac64) Numer() uint {
return uint(f.numer)
}
func (f Frac64) Denom() uint {
return uint(f.denom)
}
func (a Frac64) Add(b Num) Num {
// Just a placeholder to show it compiles.
return Frac64{
numer: 12,
denom: 34,
neg: false,
}
}
这对练习很好。在生产中,请考虑使用
big.Rat
。关于go - 与返回自身的方法接口(interface),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49119362/