title: Why is errorString a struct, not a string
body: <p>I am reading The Go Programming Language book and in it's description of the error package and the interface</p>
  
  <pre><code>package errors
  
  type error interface {
      Error() string
  }
  
  func New(text string) error { return &amp;errorString{text} }
  
  type errorString struct { text string }
  
  func (e *errorString) Error() string { return e.text }
  </code></pre>
  
  <p>it says</p>
  
  <blockquote>
    <p>The underlying type of errorString is a struct, not a string, to protect its representation from inadvertent (or premeditated) updates.</p>
  </blockquote>
  
  <p>What does this mean? Wouldn't the package hide the underlying type since <code>errorString</code> isn't exported?</p>
  
  <p><strong>Update</strong>
  Here is the test code I used implementing <code>errorString</code> using a <code>string</code> instead. Note that when try to use it from another package, you can't just assign a string as an error.</p>
  
  <pre><code>package testerr
  
  type Error interface {
          Error() string
  }
  
  func New(text string) Error {
          return errorString(text)
  }
  
  type errorString string
  
  func (e errorString) Error() string { return string(e) }
  </code></pre>
  
  <p>And testing it with the suggested codes</p>
  
  <pre><code>func main() {
      err := errors.New("foo")
      err = "bar"
      fmt.Prinln(err)
  }
  </code></pre>
  
  <p>Will end up producing an error when compiling</p>
  
  <p><code>cannot use "bar" (type string) as type testerr.Error in assignment:
      string does not implement testerr.Error (missing Error method)</code></p>
  
  <p>Of course there is a <strong>downside</strong> to this since different errors that happen to have the same error string will evaluate to being equal which we don't want.</p>