Skip to content

Commit

Permalink
Add guidance to avoid using built-in names (#93)
Browse files Browse the repository at this point in the history
  • Loading branch information
mway authored Jun 4, 2020
1 parent 8517980 commit 2910ce2
Showing 1 changed file with 95 additions and 0 deletions.
95 changes: 95 additions & 0 deletions style.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ row before the </tbody></table> line.
- [Use go.uber.org/atomic](#use-gouberorgatomic)
- [Avoid Mutable Globals](#avoid-mutable-globals)
- [Avoid Embedding Types in Public Structs](#avoid-embedding-types-in-public-structs)
- [Avoid Using Built-In Names](#avoid-using-built-in-names)
- [Performance](#performance)
- [Prefer strconv over fmt](#prefer-strconv-over-fmt)
- [Avoid string-to-byte conversion](#avoid-string-to-byte-conversion)
Expand Down Expand Up @@ -1420,6 +1421,100 @@ an implementation detail, leaves more opportunities for change, and also
eliminates indirection for discovering the full List interface in
documentation.

### Avoid Using Built-In Names

The Go [language specification] outlines several built-in,
[predeclared identifiers] that should not be used as names within Go programs.

Depending on context, reusing these identifiers as names will either shadow
the original within the current lexical scope (and any nested scopes) or make
affected code confusing. In the best case, the compiler will complain; in the
worst case, such code may introduce latent, hard-to-grep bugs.

[language specification]: https://golang.org/ref/spec
[predeclared identifiers]: https://golang.org/ref/spec#Predeclared_identifiers

<table>
<thead><tr><th>Bad</th><th>Good</th></tr></thead>
<tbody>
<tr><td>

```go
var error string
// `error` shadows the builtin

// or

func handleErrorMessage(error string) {
// `error` shadows the builtin
}
```

</td><td>

```go
var errorMessage string
// `error` refers to the builtin

// or

func handleErrorMessage(msg string) {
// `error` refers to the builtin
}
```

</td></tr>
<tr><td>

```go
type Foo struct {
// While these fields technically don't
// constitute shadowing, grepping for
// `error` or `string` strings is now
// ambiguous.
error error
string string
}

func (f Foo) Error() error {
// `error` and `f.error` are
// visually similar
return f.error
}

func (f Foo) String() string {
// `string` and `f.string` are
// visually similar
return f.string
}
```

</td><td>

```go
type Foo struct {
// `error` and `string` strings are
// now unambiguous.
err error
str string
}

func (f Foo) Error() error {
return f.err
}

func (f Foo) String() string {
return f.str
}
```
</td></tr>
</tbody></table>


Note that the compiler will not generate errors when using predeclared
identifiers, but tools such as `go vet` should correctly point out these and
other cases of shadowing.

## Performance

Performance-specific guidelines apply only to the hot path.
Expand Down

0 comments on commit 2910ce2

Please sign in to comment.