Go naming rules that other language programmers should at least care about

Overview

As the title suggests, we have summarized the naming rules that beginners from other languages should at least care about.

Target audience

It is intended for those who understand the basic syntax of Go.

What to explain in this article, what not to explain

To explain

Explains rules and conventions for naming Go file names, variable names, etc.

Don't explain

There are several ways to write Go that you should be aware of other than naming.

However, they are not covered in this article.

Writer's background

He has been a programmer for about eight years and has experience in the following languages besides Go.

I wrote Go a while ago, and I didn't write it for a while, but recently I wrote it again.

In total, Go has about a year and a half experience.

Naming rules to be aware of

package name

Character strings that can be used

Effective Go recommends a concise and clear name.

It is desirable to use only lowercase letters and consist of one word (singular).

--Good example

However, there is one exception.

It's a pattern with the _test suffix.

Go does not allow multiple package names under the same directory, but you can do so with _test.

Since it will be a different package, you will not be able to refer to private methods etc.

However, there are merits such as avoiding the problem of circular reference by using this.

This is a technique that is also used in standard packages.

//(Example) Heap package test, so heap_Become a test
package heap_test

Words to avoid

Also, it is safe not to use the following names.

These names are "concise names," but not "explicit names."

If you're wondering how to name it, it's a good idea to refer to Go's standard package name.

file name

I couldn't find any mention of "what to do with the filename" in Go's official information (please let me know in the comments, if any).

Snakecase naming is used in well-known OSS and standard packages such as kubernetes and terraform. So it seems safe to follow it.

(Example)

Directory name

As with the filename, I couldn't find a statement saying "what to do with Go's official information" (please let me know in the comments, if any).

For this, it's best to give it a one-word name that is as concise and clear as the package name.

So it seems correct to use only lowercase letters.

Kebab cases (use - to separate words" in famous OSS such as kubernetes and terraform I found a pattern that uses).

If you really want a word break, you may want to use a kebab case.

(Example)

I don't use a kebab case, but try to use all lowercase letters.

By the way, it doesn't matter if the package name and the directory name are different, but it is safer to match them.

Function, type, structure

Name it in camel case.

For functions and structures that are exposed to the outside, there is a language specification that capitalizes the beginning, so the upper camel case (starting with the first uppercase letter) or lower camel case (starting with the first lowercase letter) is determined accordingly.

//When publishing outside the package
func Contents(filename string) (string, error) {}

//When using only in the package
func contents(filename string) (string, error) {}

Receiver name

Name as short as possible with one or two letters in English.

If the type is Client, then c, cl, etc.

The receiver name must be the same (it is NG if c or cl is used depending on the location)

It is also important that you do not use modifiers.

For example, for httpClient, the receiver name will be c, and for DBCreator, it will be c.

Variable / argument name

We also recommend short variable names.

For the argument, you can use one character like the receiver name.

Ideally, the variable name should be as short as possible, but be careful with the scope.

If you use a function with a large scope and a short variable, the readability will be greatly reduced.

Also, be careful about abbreviations.

There is no problem with using abbreviations that are common among programmers as shown below, but if you forcibly abbreviate them and the variable names do not make sense, readability will decrease.

In my opinion, if you can't come up with a good abbreviation, it's safe to use variable names that normally use English words.

Just because a short variable name is recommended doesn't mean that you can neglect the naming convention, so be careful about this.

error variable name

If you declare error as a variable, declare it with the Err prefix.

It's not explicitly stated, but Go's official blog Working with Errors in Go 1.13 says something like this. You can see an example of using variable names.

In addition, Effective Go also has the following description.

// Error codes returned by failures to parse an expression.
var (
    ErrInternal      = errors.New("regexp: internal error")
    ErrUnmatchedLpar = errors.New("regexp: unmatched '('")
    ErrUnmatchedRpar = errors.New("regexp: unmatched ')'")
    ...
)

By the way, Go's error handling checks err to see if the error is nil to see if there are any errors.

Therefore, a lot of code like the following comes out.

    data, err := ioutil.ReadFile(src)
    if err != nil {
        return nil, err
    }

At this time, it is customary to receive it with the variable name err.

The Err prefix is just a rule for declaring error as a variable, so it is not used for error handling as described above.

As mentioned in the following article, if you confine the scope of err in the if syntax or use the writing method using: = , you can do most of the cases with just err. I will.

(Reference) [Explanation of "Go beginners should be careful" Too many variations of err variable names (in most cases, only "err" is required)](https://zenn.dev/nobonobo/articles/e0af4e8afc6c38b42ae1# % E3% 82% A8% E3% 83% A9% E3% 83% BC% E3% 83% 8F% E3% 83% B3% E3% 83% 89% E3% 83% AA% E3% 83% B3% E3 % 82% B0% E5% 91% A8% E3% 82% 8A)

If you find that you can't just use err, you can use Err prefix.

By the way, famous OSS such as kubernetes and terraform adopt the method using Err prefix. I didn't.

There seems to be no clear rule on what to do in this area, so it seems that it is good to adjust it for each project.

Existence check of map etc.

It seems customary to use the variable name ok when checking for the existence of a particular key, as shown below.

id, ok := users[userID]

This isn't specified anywhere, but this pattern is often used in standard packages.

About the naming of words with acronyms and acronyms

It is the contents described below.

https://github.com/golang/go/wiki/CodeReviewComments#initialisms

Go's naming is basically camelcase, but the originally pervasive abbreviations use consistent uppercase and lowercase letters.

Use URL instead of url, or use HTTP instead of http.

In my opinion, it was initially difficult to understand this rule.

For example, I was confused as to whether words such as GitHub and Twitter should not be used with github and twitter.

There is a part that checks this notation with a tool called golangci-lint, but the covered words are as follows.

(Applicable part, excerpt below). https://github.com/morix1500/lint/blob/master/lint.go#L743

var commonInitialisms = map[string]bool{
	"ACL":   true,
	"API":   true,
	"ASCII": true,
	"CPU":   true,
	"CSS":   true,
	"DNS":   true,
	"EOF":   true,
	"GUID":  true,
	"HTML":  true,
	"HTTP":  true,
	"HTTPS": true,
	"ID":    true,
	"IP":    true,
	"JSON":  true,
	"LHS":   true,
	"QPS":   true,
	"RAM":   true,
	"RHS":   true,
	"RPC":   true,
	"SLA":   true,
	"SMTP":  true,
	"SQL":   true,
	"SSH":   true,
	"TCP":   true,
	"TLS":   true,
	"TTL":   true,
	"UDP":   true,
	"UI":    true,
	"UID":   true,
	"UUID":  true,
	"URI":   true,
	"URL":   true,
	"UTF8":  true,
	"VM":    true,
	"XML":   true,
	"XMPP":  true,
	"XSRF":  true,
	"XSS":   true,
}

I would like to check such rules mechanically with golangci-lint, but check words such as gRPC and GraphQL that often appear recently. It doesn't seem to be done.

In addition, some tools that automatically generate Go code may also generate code that ignores this rule.

I have turned off this rule in golangci-lint and unified it so that it is named in camel case normally.

Referenced information

I referred to the following information when writing this article.

Official information

Personal blog etc.

-Go Codereview Comments (Japanese translation) -THE GO BLOG Japanese translation Package names -Is the Go package name singular? Plural form? -What is "Go language-ness"? It is good to understand the philosophy of Simplicity and proceed with development along the Go Way -Read the source of golint and learn how to write Go -Go Naming Convention -Troubles and solutions for error handling in Go's actual project -Explanation of "Go beginners should be careful"

Afterword

We have summarized the Go naming conventions.

You can check some of the rules listed here at golangci-lint.

I'm still working on it, but in the future I'll write about the settings for golangci-lint.

Thank you for reading to the end.

Recommended Posts

Go naming rules that other language programmers should at least care about
[Golang] About Go language channel