本人初学go语言,正在学习中。我有多年的 C++ OOP 经验。有一个用go写的stacker接口(interface)和它的两种实现,一种是slice base stack,一种是linkedlist base。
我发现很难比较两个不同的结构并判断它们是否包含相同的数据。下面是简单的示例代码列表(注意很多函数/实现没有列出,因为它们与这个问题无关)。关键函数是stackEquals,我尝试了不同的方法来处理它,但都失败了。请查看代码中的注释。
package main
import (
"fmt"
"errors"
)
// The interface is fixed, cannot be modified
type Stacker interface {
isEmpty() bool
size() int
push(x int)
peek() (int, error)
pop() (int, error)
copy() Stacker
}
type StackSlice struct {
slice []int
}
type StackLinked struct {
next *StackLinked
value int
// possible with other variables that is not relative
}
// There are interface function/method implementations did not paste
func (s StackSlice) String() string {
// return all the value inside the stack as string
// like [5 4]
}
func (s StackLinked) String() string {
// return all the value inside the stack as string
// like [5 4]]
}
// Pre-condition:
// none
// Post-condition:
// returns true if s and t have the same elements in the same order;
// both s and t have the same value after calling stackEquals as before
// Annoying constraint:
// Use only Stackers in the body of this functions: don't use arrays,
// slices, or any container other than a Stacker.
func stackEquals(s, t Stacker) bool {
// This implementation below always return false unless they are the same thing
return s == t
// I tried return s.String() == t.String() but gave an error said interface doesn't have String() method.
}
我如何比较以不同方式实现的两个堆栈,并判断它们在堆栈中是否相同(相同意味着相同顺序的相同值)。
最佳答案
如果你需要比较两个接口(interface),你只能使用那个接口(interface)中的方法,所以在这种情况下,String
接口(interface)中不存在(即使您的两个实现都有它,接口(interface)本身不存在)。
一个可能的实现是:
func stackEquals(s, t Stacker) bool {
// if they are the same object, return true
if s == t {
return true
}
// if they have different sizes or the next element is not the same,
// then they are different
if s.size() != t.size() || s.peek() != t.peek() {
return false
}
// they could be the same, so let's copy them so that we don't mess up
// the originals
ss = s.copy()
tt = t.copy()
// iterate through the values and check if each one is
// the same. If not, return false
for ; i, err := ss.pop(); err == nil {
if j, err := tt.pop(); err != nil || i != j {
return false
}
}
return true
}
这假设唯一的错误 pop
当没有更多值时会得到,否则你需要做一些更好的错误检查并使用 isEmpty
.
关于golang比较两个实现不同的结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48290599/