golang比较两个实现不同的结构

标签 go struct

本人初学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/

相关文章:

golang 反射(reflect)到 []interface{}

go - 在完成时将 channel 结果添加到队列的更惯用的方法

go - 指针与值参数和接收者的权衡

go - 我可以通过 GO 中的方法扩展错误接口(interface)吗?

c - Typedef、标记和未标记结构以及不兼容的指针类型

c - 如何创建 const 结构数组

c - 结构中的链表

c++ - 具有基于位置的枚举编译错误的结构

string - 将 base64 行拆分为 block

java - 找不到 "libgojni.so"