Comparing slices

3,038 views
Skip to first unread message

Archos

unread,
Apr 21, 2012, 11:58:33 AM4/21/12
to golang-nuts
Why arraies can be compared but not slices?

package main

func main() {
if [2]int{1,2} == [2]int{1,2} {
println("equal array")
}

if []int{1,2} == []int{1,2} {
println("equal slice")
}
}

>>> invalid operation: []int literal == []int literal (slice can only
be compared to nil)

minux

unread,
Apr 21, 2012, 12:06:17 PM4/21/12
to Archos, golang-nuts
This have been discussed several times on the mailing list.

I only point out the following program mentioned in a previous discussion:

package main
import "fmt"
type N []N
func main() {
	var n N = make(N, 1)
	n[0] = n
	fmt.Println(n)
}
As shown by this program, slices can be self referential, so it's very hard
to come up with a suitable definition of equality for slices.

On Sat, Apr 21, 2012 at 11:58 PM, Archos <raul...@sent.com> wrote:
Why arraies can be compared but not slices?

       package main

       func main() {
               if [2]int{1,2} == [2]int{1,2} {
                       println("equal array")
               }

               if []int{1,2} == []int{1,2} {
For example, to make this comparison works as you expected, the program
must traverse the slice and compare one by one, as shown, this could lead to
endless loop.

Archos

unread,
Apr 21, 2012, 12:19:13 PM4/21/12
to golang-nuts

On Apr 21, 5:06 pm, minux <minux...@gmail.com> wrote:
> On Sat, Apr 21, 2012 at 11:58 PM, Archos <raul....@sent.com> wrote:
> > Why arraies can be compared but not slices?
>
> >        package main
>
> >        func main() {
> >                if [2]int{1,2} == [2]int{1,2} {
> >                        println("equal array")
> >                }
>
> >                if []int{1,2} == []int{1,2} {
>
> For example, to make this comparison works as you expected, the program
> must traverse the slice and compare one by one, as shown, this could lead to
> endless loop.
There is a faster way:

slice1 := []int{1,2}
slice2 := []int{1,2}

strSlice1 := fmt.Sprintf("%v", slice1)
strSlice2 := fmt.Sprintf("%v", slice2)

if strSlice1 == strSlice2 {
println("equal slice")
}

Brad Fitzpatrick

unread,
Apr 21, 2012, 12:23:42 PM4/21/12
to Archos, golang-nuts

minux

unread,
Apr 21, 2012, 12:26:32 PM4/21/12
to Archos, golang-nuts
On Sun, Apr 22, 2012 at 12:19 AM, Archos <raul...@sent.com> wrote:
On Apr 21, 5:06 pm, minux <minux...@gmail.com> wrote:
> On Sat, Apr 21, 2012 at 11:58 PM, Archos <raul....@sent.com> wrote:
> > Why arraies can be compared but not slices?
> >        package main
> >        func main() {
> >                if [2]int{1,2} == [2]int{1,2} {
> >                        println("equal array")
> >                }
> >                if []int{1,2} == []int{1,2} {
>
> For example, to make this comparison works as you expected, the program
> must traverse the slice and compare one by one, as shown, this could lead to
> endless loop.
There is a faster way:

       slice1 := []int{1,2}
       slice2 := []int{1,2}

       strSlice1 := fmt.Sprintf("%v", slice1)
Sprintf still traverses the slice and if the slice is self referential, it will still fall into endless loop;
let alone the fact the user could override String/Error method for slice elements.

Archos

unread,
Apr 21, 2012, 12:36:06 PM4/21/12
to golang-nuts
Then, using json:

strSlice1, _ := json.Marshal(slice1)
strSlice2, _ := json.Marshal(slice2)

if string(strSlice1) == string(strSlice2) {
println("equal slice")
}

although it follows without working with slices self referential.

On Apr 21, 5:23 pm, Brad Fitzpatrick <bradf...@golang.org> wrote:

minux

unread,
Apr 21, 2012, 12:43:08 PM4/21/12
to Archos, golang-nuts
On Sun, Apr 22, 2012 at 12:36 AM, Archos <raul...@sent.com> wrote:
Then, using json:

       strSlice1, _ := json.Marshal(slice1)
       strSlice2, _ := json.Marshal(slice2)

       if string(strSlice1) == string(strSlice2) {
               println("equal slice")
       }

although it follows without working with slices self referential.
And it can't handle float NaN or Inf, and struct with un-exported fields.

Thomas Bushnell, BSG

unread,
Apr 22, 2012, 1:58:32 AM4/22/12
to minux, golang-nuts, Archos

No, lisp systems have long known how to reliably do deep compare or copy of recursive structures without a loop.

The more serious problem is that, since slices are reference types, it is unclear whether equality should be the same segment of the same underlying array, or simply equality of elements.

Thomas

minux

unread,
Apr 22, 2012, 2:05:20 AM4/22/12
to Thomas Bushnell, BSG, golang-nuts, Archos
On Sun, Apr 22, 2012 at 1:58 PM, Thomas Bushnell, BSG <tbus...@google.com> wrote:

No, lisp systems have long known how to reliably do deep compare or copy of recursive structures without a loop.

Of course there are solutions. I merely point out that proper definition of slice equality must take self referential
slices into account (because this fact is often overlooked).
Reply all
Reply to author
Forward
0 new messages