golang中判斷兩個slice是否相等與判斷值下的 陣列是否相等

wangchunbo發表於2021-04-02

在golang中我們可以輕鬆地通過==來判斷兩個陣列(array)是否相等,但遺憾的是slice並沒有相關的運算子,當需要判斷兩個slice是否相等時我們只能另尋捷徑了。

slice相等的定義

我們選擇最常見的需求,也就是當兩個slice的型別和長度相同,且相等下標的值也是相等的,比如:


a := []int{1, 2, 3}
b := []int{1, 2, 3}
c := []int{1, 2}
d := []int{1, 3, 2}

上述程式碼中ab是相等的,c因為長度和a不同所以不相等,d因為元素的排列順序和a不同所以也不相等。

判斷兩個[]byte是否相等

為什麼要單獨將[]byte列舉出來呢?

因為標準庫提供了優化的比較方案,不再需要我們造輪子了:

package main

import (
    "bytes"
    "fmt"
)

func main() {
    a := []byte{0, 1, 3, 2}
    b := []byte{0, 1, 3, 2}
    c := []byte{1, 1, 3, 2}

    fmt.Println(bytes.Equal(a, b))
    fmt.Println(bytes.Equal(a, c))
}

使用reflect判斷slice(陣列)是否相等

在判斷型別不是[]byte的slice時,我們還可以藉助reflect.DeepEqual,它用於深度比較兩個物件包括它們內部包含的元素是否都相等:

func DeepEqual(x, y interface{}) bool

DeepEqual reports whether x and y are “deeply equal,” defined as follows. Two values of identical type are deeply equal if one of the following cases applies. Values of distinct types are never deeply equal.

Slice values are deeply equal when all of the following are true: they are both nil or both non-nil, they have the same length, and either they point to the same initial entry of the same underlying array (that is, &x[0] == &y[0]) or their corresponding elements (up to length) are deeply equal. Note that a non-nil empty slice and a nil slice (for example, []byte{} and []byte(nil)) are not deeply equal.

這段話的意思不難理解,和我們在本文最開始時討論的如何確定slice相等的原則是一樣的,只不過它藉助了一點執行時的“黑魔法”。

看例子:

package main

import (
    "fmt"
    "reflect"
)

func main() {
    a := []int{1, 2, 3, 4}
    b := []int{1, 3, 2, 4}
    c := []int{1, 2, 3, 4}
    fmt.Println(reflect.DeepEqual(a, b))
    fmt.Println(reflect.DeepEqual(a, c))
}

手寫判斷

在golang中使用reflect通常需要付出效能代價,如果我們確定了slice的型別,那麼自己實現slice的相等判斷相對來說也不是那麼麻煩:

func testEq(a, b []int) bool {
    // If one is nil, the other must also be nil.
    if (a == nil) != (b == nil) {
        return false;
    }

    if len(a) != len(b) {
        return false
    }

    for i := range a {
        if a[i] != b[i] {
            return false
        }
    }

    return true
}

測試程式碼:

package main import "fmt" func main() {    a := []int{1, 2, 3, 4}    b := []int{1, 3, 2, 4}    c := []int{1, 2, 3, 4}    fmt.Println(testEq(a, b))    fmt.Println(testEq(a, c))}
參考

Checking the equality of two slices

轉載於:www.cnblogs.com/apocelipes/p/11116...

本作品採用《CC 協議》,轉載必須註明作者和本文連結
感謝關注 上海PHP自學中心-免費程式設計視訊教學|

相關文章