Which way to name a function in Go, CamelCase or Semi-CamelCase?

GoNaming Conventions

Go Problem Overview


I want to write a function in Go to insert a document into a collection in a MongoDB database. Which way to name the function is better,

  • writeToMongoDB or
  • WriteToMongoD?

The second is CamelCase, while I saw someone using the style of the first one, so I am not sure which one is more appropriate. Thanks.

Go Solutions


Solution 1 - Go

Syntax

In Go this is not a matter of style, it is a matter of syntax.

Exported names (that is, identifiers that can be used from a package other than the one where they are defined) begin with a capital letter. Thus if your method is part of your public API, it should be written:

WriteToDB

but if it is an internal helper method it should be written:

writeToDB

The benefit of doing it this way over using keywords to define exportedness (extern, public, etc.) is that making it a part of the name ensures that anywhere an identifier is used you can tell if it is exported or not without having to find where it was defined (to see if the definition contains a keyword).

See also: Exported Identifiers from the spec.

i18n

Because Go is UTF-8 encoded and supports any Unicode character with the letters or numbers property in identifier names some people in locales that don't have a concept of case may have trouble creating exported methods (the default is non-exported). In this case (pun intended) it is common to prefix identifiers with an X to indicate exportedness. For example: X日本語

See also: What's up with Unicode identifiers? from the FAQ.

Style

As far as the general style goes, it is to always use camel-case (except for the first letter, as previously mentioned). This includes constants, functions, and other identifiers. So for example a list of (exported) constants might look like:

const (
    StateConnected = iota
    StateError
    StateDone

    internalStateMask = 0x2 
)

Furthermore, abbreviations are always written with the same case, so you would write one of the following:

dbWrite
writeDB

instead of writeDb or DbWrite.

Solution 2 - Go

In Go, it is convention to uses mixed cap. From the docs: https://golang.org/doc/effective_go.html#mixed-caps

> Finally, the convention in Go is to use MixedCaps or mixedCaps rather > than underscores to write multiword names.

Note that file level names beginning with Capital letter are exported at package level: https://golang.org/doc/effective_go.html#Getters

Also, it is convention to write acronyms on all caps. So below is fine:

writeToMongoDB // unexported, only visible within the package

or

WriteToMongoDB // exported

And not:

writeToMongoDb

Solution 3 - Go

Names

> Names are as important in Go as in any other language. They even have > semantic effect: the visibility of a name outside a package is > determined by whether its first character is upper case. It's > therefore worth spending a little time talking about naming > conventions in Go programs.

Package names

> When a package is imported, the package name becomes an accessor for > the contents. After > > import "bytes" the importing package can talk about bytes.Buffer. It's > helpful if everyone using the package can use the same name to refer > to its contents, which implies that the package name should be good: > short, concise, evocative. By convention, packages are given lower > case, single-word names; there should be no need for underscores or > mixedCaps. Err on the side of brevity, since everyone using your > package will be typing that name. And don't worry about collisions a > priori. The package name is only the default name for imports; it need > not be unique across all source code, and in the rare case of a > collision the importing package can choose a different name to use > locally. In any case, confusion is rare because the file name in the > import determines just which package is being used. > > Another convention is that the package name is the base name of its > source directory; the package in src/encoding/base64 is imported as > "encoding/base64" but has name base64, not encoding_base64 and not > encodingBase64. > > The importer of a package will use the name to refer to its contents, > so exported names in the package can use that fact to avoid stutter. > (Don't use the import . notation, which can simplify tests that must > run outside the package they are testing, but should otherwise be > avoided.) For instance, the buffered reader type in the bufio package > is called Reader, not BufReader, because users see it as bufio.Reader, > which is a clear, concise name. Moreover, because imported entities > are always addressed with their package name, bufio.Reader does not > conflict with io.Reader. Similarly, the function to make new instances > of ring.Ring—which is the definition of a constructor in Go—would > normally be called NewRing, but since Ring is the only type exported > by the package, and since the package is called ring, it's called just > New, which clients of the package see as ring.New. Use the package > structure to help you choose good names. > > Another short example is once.Do; once.Do(setup) reads well and would > not be improved by writing once.DoOrWaitUntilDone(setup). Long names > don't automatically make things more readable. A helpful doc comment > can often be more valuable than an extra long name.

Getters

> Go doesn't provide automatic support for getters and setters. There's > nothing wrong with providing getters and setters yourself, and it's > often appropriate to do so, but it's neither idiomatic nor necessary > to put Get into the getter's name. If you have a field called owner > (lower case, unexported), the getter method should be called Owner > (upper case, exported), not GetOwner. The use of upper-case names for > export provides the hook to discriminate the field from the method. A > setter function, if needed, will likely be called SetOwner. Both names > read well in practice:

owner := obj.Owner()
if owner != user {
    obj.SetOwner(user)
}

Interface names

> By convention, one-method interfaces are named by the method name plus > an -er suffix or similar modification to construct an agent noun: > Reader, Writer, Formatter, CloseNotifier etc. > > There are a number of such names and it's productive to honor them and > the function names they capture. Read, Write, Close, Flush, String and > so on have canonical signatures and meanings. To avoid confusion, > don't give your method one of those names unless it has the same > signature and meaning. Conversely, if your type implements a method > with the same meaning as a method on a well-known type, give it the > same name and signature; call your string-converter method String not > ToString.

MixedCaps

> Finally, the convention in Go is to use MixedCaps or mixedCaps rather > than underscores to write multiword names.

ref: Effective Go

Solution 4 - Go

In Golang, any variable (or a function) with an identifier starting with an upper-case letter (example, CamelCase) is made public (accessible) to all other packages in your program, whereas those starting with a lower-case letter (example, camelCase) is not accessible to any package except the one it is being declared in.

You should use CamelCase in case you intend to use the variable (or function) in another package, or you can safely stick with camelCase.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionTimView Question on Stackoverflow
Solution 1 - GoSam WhitedView Answer on Stackoverflow
Solution 2 - GoabhinkView Answer on Stackoverflow
Solution 3 - Gouser6169399View Answer on Stackoverflow
Solution 4 - GoTanmay GargView Answer on Stackoverflow