简体   繁体   中英

golang comparing two structs that are implemented differently

I am new to go language, under learning. I have years OOP experience in C++. There is a stacker interface that is written in go and two implementations of it, one is slice base stack and another one is linkedlist base.

I find it is hard to compare two different structures and tell if they are containing the same data or not. The simple example code list below (notice a lot of functions/implementations are not listed because they are not relative with this question). The key function is stackEquals , I have tried different ways to approach it but they failed. Please see the comments in the code.

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.
}

How can I compare two stacks that implemented in different way and tell if they are the same (same means same values in same order) in the stack.

If you need to compare two interfaces, you can only use the methods in that interface, so in this case, String does not exist in the interface (even though both of your implementations have it, the interface itself does not).

A possible implementation would be:

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
}

This assumes that the only error pop would get is when there are no more values, otherwise you will need to do some better error checking and use isEmpty .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM