<p>So I was just bitten by this (<a href="http://play.golang.org/p/pdIQABIM75">playground</a>):</p>
<pre><code>var got []float64
want := []float64{}
if !reflect.DeepEqual(got, want) {
fmt.Printf("got:(%T,%v) want:(%T,%v)\n", got, got, want, want)
}
// got:([]float64,[]) want:([]float64,[])
</code></pre>
<p>This fails, even though apparently they are equal! The documentation in <code>reflect.DeepEqual</code> is thankfully very explicit:</p>
<blockquote>
<p>An empty slice is not equal to a nil slice.</p>
</blockquote>
<p>Of course, this begs the question to <em>why</em>. The case where nil doesn't equate a nil interface (<a href="https://golang.org/doc/faq#nil_error">https://golang.org/doc/faq#nil_error</a>) also stands out, specially for newcomers - in C and Java, a <code>null</code> is always a <code>null</code>. I know the technical explanation regarding how interface pointers are represented, but it just says "it works as coded". Is there any other reason why nil can't be a bit more useful?</p>
<hr/>**评论:**<br/><br/>dsymonds: <pre><p>They are not equal. One is a nil slice, and one is an allocated but zero length slice. Those are different things. They do, however, work equivalently in many situations, like with len, cap, append, copy, etc.</p>
<p>You might find <a href="http://research.swtch.com/godata">http://research.swtch.com/godata</a> informative.</p></pre>iku_19: <pre><p>So, in theory this should be equal</p>
<pre><code>var got []float64
got = make([]float64, 0, 0)
want := []float64{}
if !reflect.DeepEqual(got, want) {
fmt.Printf("got:(%T,%v) want:(%T,%v)\n", got, got, want, want)
}
</code></pre></pre>dsymonds: <pre><p>Yes. The playground says those are equal.</p></pre>hobbified: <pre><ol>
<li><p>A slice with nothing in it is obviously different from no slice at all. You might find it annoying that a <code>[]float64</code> is allowed to be "no slice at all" rather than merely empty, but preventing you from ever seeing an uninitialized slice (as dynamic languages would do) would be expensive and counter to the general design of Go.</p></li>
<li><p>Nil interfaces are a bit weirder, and honestly I find it easy to read the spec in a way that says that types are irrelevant when comparing an interface value with nil. Maybe someone should rephrase it a little bit. I'm pretty sure it was done the way it is for simplicity/efficiency of implementation, rather than user-friendliness.</p></li>
</ol></pre>dilap: <pre><p>They are not equal in a literal sense, in that the memory used by each is different.</p>
<p>That said, I think they behave exactly the same (trying to think of somewhere they don't; can't), so I'm not sure exactly what purpose is served by not considering them 'equal' for DeepEqual purposes, other than philosophical purity.</p>
<p>(In contrast, a nil map doesn't act at all like an empty map, tho I wonder why [perf?].)</p></pre>brunokim: <pre><p>Yes, from what I understand now I believe == should return false, and reflect.DeepEqual should return true. After all, DeepEqual cares about semantics, not memory equality.</p></pre>