That's correct, and part of the larger notion that you cannot add methods to types from another module. (Primitive types come from the same pseudo-module that declares append, len, etc.)
Think about it. How would you cleanly implement this? If you allow e.g.
func (x int) String() string { return strconv.Itoa(x) }
Then what does the compiler do when two modules declare that method? You could forbid it, but this will lead to situations where existing application code breaks because a library is updated and the new library version includes a method that was already implemented (possibly differently) by the application.
The other option is to allow implicit casts such as
func foo(s Stringer) { fmt.Println(s.String()) }
foo(1) # implicitly casts to ValueMeters to satisfy Stringer interface
But then you run into the same problem. How would you select (forward-compatibly!) the right interface implementation to cast to?
EDIT: The only solution that I can see is to allow function overloads:
func foo(s Stringer) { ... }
func foo(x int) { ... }
Without having thought it through very far, I think that this can be done consistently (precisely because all types are final in Go once the module is cmplete), but it would probably still lead to some surprising behavior.
Actually, I just now see a problem with this:
func foo(x int) { ... }
func foo(x uint) { ... }
foo(0) # which one to use?
Literals don't have a type in Go until they're used in a place that requires a specific type. To make this example even more interesting, consider this:
func foo(x int) uint { ... }
func foo(x uint) int { ... }
fmt.Printf("%t", foo(0)) # prints "uint" or "int", but which?