检查结构中的每个项目是否都保持不变

时间:2018-05-19 08:20:10

标签: go struct comparison

我有以下套餐:

// Contains state read in from the command line
type State struct {
    Domain          string  // Domain to check for
    DomainList      string  // File location for a list of domains
    OutputNormal    string  // File to output in normal format
    OutputDomains   string  // File to output domains only to
    Verbose         bool    // Verbose prints, incl. Debug information
    Threads         int     // Number of threads to use
    NoColour        bool    // Strip colour from output
    Silent          bool    // Output domains only
    Usage           bool    // Print usage information
}

func InitState() (state State) {
    return State { "", "", "", "", false, 20, false, false, false }
}

func ValidateState(s *State) (result bool, error string ) {
    if s.Domain == "" && s.DomainList == "" {
        return false, "You must specify either a domain or list of domains to test"
    }

    return true, ""
}

ValidateState()内,如果State中的每个项目与InitState()中定义的项目相同,我想返回true。我可以看到一些方法来做到这一点,但似乎没有什么是简洁的。我非常重视某个方向!

1 个答案:

答案 0 :(得分:2)

如果所有字段都具有可比性,则结构值具有可比性(请参阅Spec: Comparison operators)。因为在你的情况下,我们可以利用这一点。

在您的情况下,实现此目的的最简单和最有效的方法是保存包含初始值的结构值,并且每当您想要判断结构值(如果其任何字段)是否已更改时,只需将其与保存的初始值。这就是所需要的:

var defaultState = InitState()

func isUnchanged(s State) bool {
    return s == defaultState
}

测试它:

s := InitState()
fmt.Println(isUnchanged(s))

s.Threads = 1
fmt.Println(isUnchanged(s))

输出(在Go Playground上尝试):

true
false

请注意,如果您通过添加/删除/重命名/重新排列字段来更改State类型,只要它们仍然具有可比性,则此解决方案仍可正常运行而无需任何修改。作为一个反例,如果你添加一个切片类型的字段,它就不再适用了,因为切片不具有可比性。这将导致编译时错误。要处理此类情况,可以使用reflect.DeepEqual()代替简单的==比较运算符。

另请注意,您应该像这样创建State的默认值:

func NewState() State {
    return State{Threads: 20}
}

您不必列出其值为其类型的零值的字段。