Golangのパッケージ名はどうするのが正解か
https://go.dev/blog/package-names を訳してみる
Introduction
Go code is organized into packages. Within a package, code can refer to any identifier (name) defined within, while clients of the package may only reference the package’s exported types, functions, constants, and variables. Such references always include the package name as a prefix: foo.Bar refers to the exported name Bar in the imported package named foo.
はじめに
Go のコードはパッケージにまとめられています。
パッケージ内では、コードは内で定義された任意の識別子 (名前) を参照できますが、パッケージのクライアントは、パッケージのエクスポートされた型、関数、定数、および変数のみを参照できます。
このような参照には、常にパッケージ名がプレフィックス: foo.Bar として含まれます。
Bar は、foo という名前のインポートされたパッケージ内のエクスポートされた名前 Bar を参照します。
Good package names make code better. A package’s name provides context for its contents, making it easier for clients to understand what the package is for and how to use it. The name also helps package maintainers determine what does and does not belong in the package as it evolves. Well-named packages make it easier to find the code you need.
良いパッケージ名はコードをより良くします。
パッケージの名前はそのコンテンツのコンテキストを提供し、クライアントがパッケージの目的と使用方法を理解しやすくします。
また、この名前は、パッケージのメンテナが、展開時にパッケージに何が含まれ、何が含まれていないかを判断するのにも役立ちます。
適切な名前のパッケージを使用すると、必要なコードを見つけやすくなります。
Effective Go provides guidelines for naming packages, types, functions, and variables. This article expands on that discussion and surveys names found in the standard library. It also discusses bad package names and how to fix them.
Effective Go には、パッケージ、型、関数、変数の命名に関するガイドラインがあります。
この記事では、標準ライブラリーに見られる議論と名前について詳しく説明します。
また、よくないパッケージ名とその修正方法についても説明します。
Effective Goは暇な時ちゃんと読むべきだと思った
Package names
Good package names are short and clear. They are lower case, with no under_scores or mixedCaps. They are often simple nouns, such as:
パッケージ名
良いパッケージ名は短くて明確です。小文字で、「under_scores」(アンダースコア 👉 _ ) または 「mixedCaps」(意味区切りで大文字) はありません。多くの場合、次のようなシンプルな名詞です。
time (provides functionality for measuring and displaying time)
list (implements a doubly linked list)
http (provides HTTP client and server implementations)
The style of names typical of another language might not be idiomatic in a Go program. Here are two examples of names that might be good style in other languages but do not fit well in Go:
- time (時間を測定および表示する機能を提供します)
- list (Linked List を実装する)
- http (HTTPクライアントおよびサーバ実装を提供)
他の言語で一般的な名前のスタイルは、Goプログラムではイディオム(慣習)に従っていない可能性があります。
他の言語では適切なスタイルであっても、Goでは適切でない名前の例を2つ示します。
computeServiceClient
priority_queue
- computeServiceClient
- priority_queue
A Go package may export several types and functions. For example, a compute package could export a Client type with methods for using the service as well as functions for partitioning a compute task across several clients.
Goパッケージは、複数の型と関数をエクスポートできます。たとえば、コンピュート パッケージは、サービスを使用するためのメソッドのクライアントの型を、複数のクライアント間でコンピューティングタスクを分割するための関数を使用して、エクスポートできます。
Abbreviate judiciously. Package names may be abbreviated when the abbreviation is familiar to the programmer. Widely-used packages often have compressed names:
慎重に略しましょう。
パッケージ名は、その省略形がプログラマにとってなじみのあるものであれば省略することができます。
広く使用されているパッケージには、圧縮された名前が付いていることがよくあります。
strconv (string conversion)
syscall (system call)
fmt (formatted I/O)
On the other hand, if abbreviating a package name makes it ambiguous or unclear, don’t do it.
- strconv (文字列変換)
- syscall (システムコール)
- fmt (フォーマットされたI/O)
一方、パッケージ名を省略することであいまいまたは不明瞭になる場合は、省略しないでください。
Don’t steal good names from the user. Avoid giving a package a name that is commonly used in client code. For example, the buffered I/O package is called bufio, not buf, since buf is a good variable name for a buffer.
ユーザーから良い名前を盗んではいけません。
クライアントコードで一般的に使用される名前をパッケージに付けることは避けてください。
たとえば、bufはバッファに適した変数名であるため、バッファI/Oパッケージはbufではなくbufioと呼ばれます。
ハイフン(-)は使っていいんだと思う。
ここには特に指摘がないし、実際ハイフンをパッケージ名として使っているライブラリはたまに見かけている。
例えば「rrule-go」とかハイフン使っている
というぐあいにスター数の多いリポジトリでもちらほらハイフンを使っている例がある
ただしこれはリポジトリ名なのでパッケージ名とは別の場合もある。
リポジトリ名とパッケージ名はなるべく同じの方が良いと思った。
リポジトリ名とパッケージ名はなるべく同じの方が良いと思った。
Effective goにこの辺の詳しい記載があるっぽい
@Yoichiro Shimizu さんからご指摘をいただきました、ありがとうございます。
-(ハイフン)を使ってパッケージを定義できませんでした。
ハイフンはそもそも言語仕様的にpacakge名に使えないから記述が無いんだと思います。
kube-proxy など、main関数を置くディレクトリとしては利用できますが、 kube-proxy packgeは作れません。
Golangで記述されている kubernetes https://github.com/kubernetes/kubernetes/tree/master/cmd
cmd ディレクトリなど見た際、パッケージを集約し、インターフェースを提供する場合に機能に基づいて「プレフィックスの境界」として-(ハイフン)を利用しているように見えるが、
このことからプレフィックスとして -(ハイフン) を利用する等は問題ないと思われます。
ちなみに、-(ハイフン)を使ってはいけない等記述は effective go や公式ブログなどには記述がないので、これはプロジェクトもしくはコーダーの各々のルールに従えば良いと思います。
Naming package contents
A package name and its contents' names are coupled, since client code uses them together. When designing a package, take the client’s point of view.
パッケージの内容の命名
パッケージ名とその内容の名前は、クライアント・コードが一緒に使用するため、結合されます。パッケージを設計するときは、クライアントの視点に立ってください。
Avoid repetition. Since client code uses the package name as a prefix when referring to the package contents, the names for those contents need not repeat the package name. The HTTP server provided by the http package is called Server, not HTTPServer. Client code refers to this type as http.Server, so there is no ambiguity.
繰り返しは避けてください。クライアントコードでは、パッケージの内容を参照するときにパッケージ名をプレフィックスとして使用するため、パッケージ名を繰り返す必要はありません。httpパッケージが提供するHTTPサーバーは、HTTPServerではなくServerと呼ばれます。クライアントコードでは、この型をhttpと呼びます。サーバーなので、曖昧さはありません。
Simplify function names. When a function in package pkg returns a value of type pkg.Pkg (or *pkg.Pkg), the function name can often omit the type name without confusion:
関数名を単純化します。パッケージ「pkg」内の関数が pkg.Pkg (または*pkg.Pkg) 型 の値を返す場合、関数名は混同することなく型名を省略することができます。
start := time.Now() // start is a time.Time
t, err := time.Parse(time.Kitchen, "6:06PM") // t is a time.Time
ctx = context.WithTimeout(ctx, 10*time.Millisecond) // ctx is a context.Context
ip, ok := userip.FromContext(ctx) // ip is a net.IP
A function named New in package pkg returns a value of type pkg.Pkg. This is a standard entry point for client code using that type:
パッケージ「pkg」のNewという名前の関数は、pkg.Pkg 型の値を返します。
これは、そのタイプを使用するクライアントコードの標準エントリーポイントです。
q := list.New() // q is a *list.List
When a function returns a value of type pkg.T, where T is not Pkg, the function name may include T to make client code easier to understand. A common situation is a package with multiple New-like functions:
関数が pkg.T 型の値を返す場合。pkg.T (ここで、T は Pkg ではありません) 。関数名には、クライアントコードを理解しやすくするために T を含めることができます。一般的な状況は、複数の New のような関数を持つパッケージです。
d, err := time.ParseDuration("10s") // d is a time.Duration
elapsed := time.Since(start) // elapsed is a time.Duration
ticker := time.NewTicker(d) // ticker is a *time.Ticker
timer := time.NewTimer(d) // timer is a *time.Timer
Types in different packages can have the same name, because from the client’s point of view such names are discriminated by the package name. For example, the standard library includes several types named Reader, including jpeg.Reader, bufio.Reader, and csv.Reader. Each package name fits with Reader to yield a good type name.
異なるパッケージ内の型には同じ名前を付けることができます。
これは、クライアントの観点からは、このような名前はパッケージ名によって区別されるためです。
たとえば、標準ライブラリには、jpegなど、Readerという名前のいくつかの型が含まれています。
- jpeg.Reader
- bufio.Reader
- csv.Reader
各パッケージ名は、適切な型名を生成するために Reader という名前を適用している。
If you cannot come up with a package name that’s a meaningful prefix for the package’s contents, the package abstraction boundary may be wrong. Write code that uses your package as a client would, and restructure your packages if the result seems poor. This approach will yield packages that are easier for clients to understand and for the package developers to maintain.
パッケージの内容に対して意味のあるプレフィックスとなるパッケージ名を見つけることができない場合、パッケージの抽象化境界が間違っている可能性があります。
パッケージをクライアントとして使用するコードを記述し、結果が悪いと思われる場合はパッケージを再構築します。
このアプローチにより、クライアントが理解しやすく、パッケージ開発者が保守しやすいパッケージが作成されます。
Package paths
A Go package has both a name and a path. The package name is specified in the package statement of its source files; client code uses it as the prefix for the package’s exported names. Client code uses the package path when importing the package. By convention, the last element of the package path is the package name:
パッケージパス
Goパッケージには名前とパスの両方があります。パッケージ名は、ソースファイルのパッケージ文(import部分)で指定されます。
クライアントコードでは、パッケージのエクスポートされた名前のプレフィックスとして使用されます。
クライアントコードは、パッケージをインポートするときにパッケージパスを使用します。
通常、パッケージパスの最後の要素はパッケージ名です。
import (
"context" // package context
"fmt" // package fmt
"golang.org/x/time/rate" // package rate
"os/exec" // package exec
)
Build tools map package paths onto directories. The go tool uses the GOPATH environment variable to find the source files for path "github.com/user/hello" in directory $GOPATH/src/github.com/user/hello. (This situation should be familiar, of course, but it’s important to be clear about the terminology and structure of packages.)
構築ツールはパッケージパスをディレクトリにマッピングします。
goツールは、GOPATH環境変数を使用して、ディレクトリ「$GOPATH/src/github.com/user/hello」内のパス「github.com/user/hello」のソースファイルを検索します。
(もちろん、この状況はよく知っているはずですが、パッケージの用語と構造を明確にすることが重要です。)
Directories. The standard library uses directories like crypto, container, encoding, and image to group packages for related protocols and algorithms. There is no actual relationship among the packages in one of these directories; a directory just provides a way to arrange the files. Any package can import any other package provided the import does not create a cycle.
ディレクトリ。標準ライブラリは、crypto、container、encoding、imageなどのディレクトリを使用して、関連するプロトコルやアルゴリズムのパッケージをグループ化します。
これらのディレクトリのいずれかにあるパッケージ間に実際の関係はありません。
ディレクトリは単にファイルを整理する手段を提供するだけです。
インポートでサイクルが作成されない場合、どのパッケージでも他のパッケージをインポートできます。
Just as types in different packages can have the same name without ambiguity, packages in different directories can have the same name. For example, runtime/pprof provides profiling data in the format expected by the pprof profiling tool, while net/http/pprof provides HTTP endpoints to present profiling data in this format. Client code uses the package path to import the package, so there is no confusion. If a source file needs to import both pprof packages, it can rename one or both locally. When renaming an imported package, the local name should follow the same guidelines as package names (lower case, no under_scores or mixedCaps).
異なるパッケージ内の型が曖昧さなく同じ名前を持つことができるのと同様に、異なるディレクトリ内のパッケージも同じ名前を持つことができます。
たとえば、runtime/pprofはpprofプロファイリングツールが期待する形式でプロファイリングデータを提供し、net/http/pprofはこの形式でプロファイリングデータを提供するHTTPエンドポイントを提供します。
クライアントコードはパッケージパスを使用してパッケージをインポートするため、混乱はありません。
ソースファイルで両方のpprofパッケージをインポートする必要がある場合は、一方または両方の名前をローカルに変更できます。
インポートしたパッケージの名前を変更する場合、ローカル名はパッケージ名と同じガイドラインに従う必要があります(小文字、「under_scores」または「mixedCaps」はダメ)。
Bad package names
Bad package names make code harder to navigate and maintain. Here are some guidelines for recognizing and fixing bad names.
よくないパッケージ名
パッケージ名が悪いと、コードのナビゲートと保守が困難になります。ここでは、悪い名前を認識して修正するためのガイドラインを示します。
Avoid meaningless package names. Packages named util, common, or misc provide clients with no sense of what the package contains. This makes it harder for clients to use the package and makes it harder for maintainers to keep the package focused. Over time, they accumulate dependencies that can make compilation significantly and unnecessarily slower, especially in large programs. And since such package names are generic, they are more likely to collide with other packages imported by client code, forcing clients to invent names to distinguish them.
意味のないパッケージ名は避けてください。
util、common、またはmiscという名前のパッケージは、パッケージの内容をクライアントに認識されません。
これにより、クライアントがパッケージを使用するのが難しくなり、メンテナがパッケージに集中するのが難しくなります。
時間の経過とともに依存性が蓄積され、特に大規模なプログラムでは、コンパイルが著しく不必要に遅くなる可能性があります。
また、このようなパッケージ名は汎用であるため、クライアントコードによってインポートされた他のパッケージと衝突する可能性が高く、クライアントは名前を作成して区別する必要があります。
Break up generic packages. To fix such packages, look for types and functions with common name elements and pull them into their own package. For example, if you have
汎用パッケージを分割します。このようなパッケージを修正するには、共通の名前要素を持つ型と関数を探し、それらを独自のパッケージに取り込みます。
たとえば、次のものがあるとします。
package util
func NewStringSet(...string) map[string]bool {...}
func SortStringSet(map[string]bool) []string {...}
then client code looks like
その時クライアントコードは次のようになります。
set := util.NewStringSet("c", "a", "b")
fmt.Println(util.SortStringSet(set))
Pull these functions out of util into a new package, choosing a name that fits the contents:
これらの関数をutilから新しいパッケージに取り出し、内容に合う名前を選択します。
package stringset
func New(...string) map[string]bool {...}
func Sort(map[string]bool) []string {...}
then the client code becomes
その時クライアントコードはこうなる
set := stringset.New("c", "a", "b")
fmt.Println(stringset.Sort(set))
Once you’ve made this change, its easier to see how to improve the new package:
この変更を行うと、新しいパッケージを改善する方法がわかりやすくなります。
package stringset
type Set map[string]bool
func New(...string) Set {...}
func (s Set) Sort() []string {...}
which yields even simpler client code:
これにより、さらに単純なクライアントコードが生成されます。
set := stringset.New("c", "a", "b")
fmt.Println(set.Sort())
The name of the package is a critical piece of its design. Work to eliminate meaningless package names from your projects.
パッケージの名前は、そのデザインの重要な要素です。
プロジェクトから無意味なパッケージ名を削除します。
Don’t use a single package for all your APIs. Many well-intentioned programmers put all the interfaces exposed by their program into a single package named api, types, or interfaces, thinking it makes it easier to find the entry points to their code base. This is a mistake. Such packages suffer from the same problems as those named util or common, growing without bound, providing no guidance to users, accumulating dependencies, and colliding with other imports. Break them up, perhaps using directories to separate public packages from implementation.
すべてのAPIに単一のパッケージを使用しないでください。
多くの善意のプログラマは、プログラムによって公開されているすべてのインタフェースをapi、types、またはinterfacesという名前の単一のパッケージに入れ、コードベースへのエントリポイントを見つけやすくすると考えています。
これは間違いです。このようなパッケージは、utilやcommonという名前のパッケージと同じ問題に悩まされ、制約を受けずに成長し、ユーザーに何のガイダンスも提供せず、依存関係を蓄積し、他のインポートと衝突します。公開パッケージと実装を分離するためにディレクトリを使用するなどして分割します。
Avoid unnecessary package name collisions. While packages in different directories may have the same name, packages that are frequently used together should have distinct names. This reduces confusion and the need for local renaming in client code. For the same reason, avoid using the same name as popular standard packages like io or http.
不要なパッケージ名の衝突を回避します。
異なるディレクトリにあるパッケージには同じ名前を付けることができますが、頻繁に一緒に使用されるパッケージには異なる名前を付ける必要があります。
これにより、混乱が少なくなり、クライアントコードでローカル名を変更する必要がなくなります。
同じ理由で、ioやhttpなどの一般的な標準パッケージと同じ名前を使用しないでください。
perhaps using directories to separate public packages from implementation.
ということは今作ってみているgraphライブラリに関してもディレクトリでセグメントを切って管理する必要があるということだと思う。
今度やってみよう。
ちょっと実践してみている
Conclusion
Package names are central to good naming in Go programs. Take the time to choose good package names and organize your code well. This helps clients understand and use your packages and helps maintainers to grow them gracefully.
結論
Goプログラムでは、パッケージ名が適切なネーミングの中核となります。時間をかけて適切なパッケージ名を選択し、コードを適切に整理します。これにより、クライアントはパッケージを理解して使用する助けとなり、メンテナはパッケージを適切に成長させることができます。
キーポイント
-
良いパッケージ名は短くて明確です。小文字で、「under_scores」(アンダースコア 👉 _ ) または 「mixedCaps」(意味区切りで大文字) はありません。
-
他の言語では適切なスタイルであっても、Goでは適切でない名前の例を2つ示します。
(
computeServiceClient
priority_queue
)
- パッケージ名は、その省略形がプログラマにとってなじみのあるものであれば省略することができます。
広く使用されているパッケージには、圧縮された名前が付いていることがよくあります。
(
strconv (文字列変換)
syscall (システムコール)
fmt (フォーマットされたI/O)
)
-
クライアントコードで一般的に使用される名前をパッケージに付けることは避けてください。
たとえば、bufはバッファに適した変数名であるため、バッファI/Oパッケージはbufではなくbufioと呼ばれます。 -
繰り返しは避けてください。クライアントコードでは、パッケージの内容を参照するときにパッケージ名をプレフィックスとして使用するため、パッケージ名を繰り返す必要はありません。
-
異なるパッケージ内の型には同じ名前を付けることができます。
これは、クライアントの観点からは、このような名前はパッケージ名によって区別されるためです。
たとえば、標準ライブラリには、jpegなど、Readerという名前のいくつかの型が含まれています。
(
jpeg.Reader
bufio.Reader
csv.Reader
)
-
パッケージの内容に対して意味のあるプレフィックスとなるパッケージ名を見つけることができない場合、パッケージの抽象化境界が間違っている可能性があります。
-
意味のないパッケージ名は避けてください。
util、common、またはmiscという名前のパッケージは、パッケージの内容をクライアントに認識されません。 -
すべてのAPIに単一のパッケージを使用しないでください。
-
異なるディレクトリにあるパッケージには同じ名前を付けることができますが、頻繁に一緒に使用されるパッケージには異なる名前を付ける必要があります。
とりあえず次はここら辺の命名に関する部分をピックアップして訳してみる。
いい資料っぽい
Effective Go
パッケージ名
パッケージをインポートすると、パッケージ名はパッケージ内容へのアクセッサになります。次のように:
import "bytes"
と書くと、インポートされるパッケージを通してbytes.Bufferを使用することができます。パッケージを使用する人々が、パッケージ内容を参照する際に同じ名前を使用することができれば、それは役に立ちます。このことは、パッケージ名が短く、簡潔で、意味明瞭なものほど良いことを意味します。規約により、パッケージには小文字の1単語である名前が与えられます。アンダースコアの使用や大文字小文字の混在は必要ありません。また、あなたのパッケージを使う人々が使う度にパッケージ名を打ち込むことを考えて、パッケージ名を簡潔過ぎるほど簡潔にしてしまう場合があります。その場合でも、名前の事前衝突を心配する必要はありません。なぜなら、パッケージ名はインポートするためのデフォルト名でしかないからです。すなわち、ソースコード全体でパッケージ名がユニークである必要はありません。万が一インポートされるパッケージ名が衝突する場合にも、局所的に異なるパッケージ名を選択することが可能です。どのような場合でも、インポート機能において、ファイル名がどのパッケージが使用されているかを決定するので、混乱することはまれです。
もう一つの規約は、パッケージ名はそのソースファイルのディレクトリの基本名であるということです。src/pkg/container/vectorパッケージは、”container/vector”としてインポートされます。パッケージ名はvectorであって、container_vectorでもcontainerVectorでもありません。
パッケージインポータは、パッケージ内容を参照するためにパッケージ名を使用します(.(ドット)記法を使ったインポートは、テストや他のまれな場面で使用します)。
もう一つの短い例は、once.Doです。onche.Do(setup)は読みやすく、once.DoOrWaitUntileDone(setup)と書いてもより読みやすくなることはありません。より長い名前を使えば、より読みやすくなるということはありません。もし名前が難解であったり、捉えにくい場合、名前にすべての情報を詰め込もうとするより、役に立つDocコメントを記述するのがより良いのが普通です。
表現がダイレクトで頭に入ってこないな。
この部分本家も読もうか。
ざっと本家を読んでみたけど、残念ながら現在のドキュメントと若干内容が違う気がした。
2009年版なので更新されてないだけっぽいな。
https://golang.org/doc/effective_go#names を読んでみるよ。
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.
名前
名前というのは、いくつかの言語でも同様ですが、Goにおいても重要です。
これらの名前は意味があり、文法的な効果を持ちあわせている:
外部パッケージの名前の一文字目が大文字かどうかで可視性が決定されます。
(つまり最初の一文字が大文字であるとこれは内部パッケージから外部パッケージを参照できるということ)
したがって、Goにおけるプログラムを記述することにおいて、ネーミング(いわゆる命名規則)について多少の時間をとって考え議論することは価値のあることです。
Package names
When a package is imported, the package name becomes an accessor for the contents.
パッケージ名
パッケージをインポートする際、そのパッケージ名はコンテンツのアクセサとなる。
アクセサとは、オブジェクト指向プログラミングで、オブジェクト内部のメンバ変数(属性、プロパティ)に外部からアクセスするために用意されたメソッド。メンバ変数をオブジェクト内部に隠蔽し、外部から直接参照させないようにするために用意される。
https://e-words.jp/w/アクセサ.html
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.
次のように、
import "bytes"
このインポートしているパッケージ、bytes.Bufferについて話していこう。
これは仮に、皆がパッケージを、そのコンテンツ名と同じ名前で参照して使用することができれば、それは役に立ちます。
良いパッケージ名
- 短く
- 簡潔
- 明快
(コーディング)規約により、パッケージには「小文字」の「1単語」の、名前が与えられます。
アンダースコアの使用や大文字小文字の混在は必要ないです。
また、あなたのパッケージを使う人々が使う度にパッケージ名を打ち込むことを考えて、
パッケージ名を簡潔にする場合があります。
そのような場合においても、その名前の衝突(コリジョン)を事前に考慮する必要はありません。
このパッケージ名はインポートするただのデフォルト名だからです。
すなわち、パッケージ名が全てのソースコードを跨ぐ際、ユニークである必要はありません。
万が一インポートされるパッケージ名の衝突(コリジョン)がある場合にも、部分的に異なるパッケージ名を選択できます。
どのような場合でも、importする際に、ファイル名がどのパッケージから使用されているかを決定するので、あまり混乱することはありません。
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.
もう1つの(コーディング)規約は、パッケージ名がソースディレクトリのベース名であることです。この src/encoding/base64
のパッケージは "encoding/base64" としてインポートされますが、名前はbase64で、encoding_base 64でも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 repetition. (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.
パッケージのインポーター(importer)は、そのパッケージの内容を参照するための名前を使用するため、パッケージ内のエクスポートされた名前は、繰り返しを回避できます。
(インポートを使用しないでください。これにより、テスト対象のパッケージの外部で実行する必要があるテストを簡素化できますが、それ以外の場合は避ける必要があります。)
たとえば、bufio
パッケージ内のバッファリングされたreader型
は、BufReaderではなくReaderと呼ばれます。
これは、bufioとして表示されるためです。
Readerは明確で簡潔な名前です。
さらに、インポートされたエンティティは常にパッケージ名 bufio でアドレス指定されるためです。
bufio.Reader は io.Reader と競合しません。
同様に、ring.Ring の新しいインスタンスを作成する関数。
Goのコンストラクタの定義である ring.Ring は、通常は NewRing と呼ばれますが、Ring はパッケージによってエクスポートされる唯一の型であり、パッケージはringと呼ばれるため、単に New と呼ばれ、パッケージのクライアントはこれを ring.New と見なします。
パッケージの構造体を使用すると、適切な名前の選択を助けてくれます。
コンストラクタは、オブジェクト指向のプログラミング言語で新たなオブジェクトを生成する際に呼び出されて内容の初期化などを行なう関数あるいはメソッドのことである。対義語はデストラクタ。
https://ja.wikipedia.org/wiki/コンストラクタ
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.
もう1つの短い例は、once.Do;
once.Do (setup)
は読みやすく、一度書いたらそれ以上は良くはならないだろう。
once.DoOrWaitUntilDone(setup).
というふうに長い名前を付けたとしても、必然的に読みやすくはならない。
役立つドキュメントのコメントは、大体は、特別に長い名前にするよりも価値があります。
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:
Getters
Goは、GettersとSettersを自動的にサポートはしません。
gettersとsettersを自分で提供することには何の問題もないし、そうするのが適切なこともよくあるが、慣用句でもなければ、Getをgetterの名前に入れる必要もないです。
もしowner (小文字、エクスポートされないつまり外部で使えない)というフィールドがある場合、GetterメソッドはGetOwnerではなくOwner (大文字、エクスポートつまり外部で使える)と呼ぶべきである。
エクスポートで大文字の名前を使用すると、メソッドからフィールドを識別するためのフックが提供されます。
また必要に応じて、setter関数はSetOwnerと呼ばれます。
どちらの名前も実際に読みやすいです。
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.
インタフェース名
慣習的に、1メソッドのインタフェースは、Reader、Writer、Formatter、CloseNotifierなどの動作主名詞(erをつけたりするもの)を構築するために、メソッド名に -er 接尾辞または同様の修正を加えた名前になります。
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.
このような名前は数多くあり、そのような名前とそれらを捉える関数名を尊重することは生産的です。
Read 、Write 、Close 、Flush 、String などには、正規の署名と意味を持ちます。
混乱を避けるために、同じ署名と意味を持っていないメソッドには、これらの名前を付けないでください。
逆に、型がよく知られた型のメソッドと同じ意味を持つメソッドを実装する場合は、同じ名前と同じ署名を指定します。
あなたのstring-converterメソッドではToStringではなくてStringで呼び出します。
MixedCaps
Finally, the convention in Go is to use MixedCaps or mixedCaps rather than underscores to write multiword names.
MixedCaps(例えばLastNameのようにLとNを大文字にしたりするもの)
最後に、Goの規則では、アンダースコアではなく MixedCaps または mixedCaps を使用して複数語の名前を記述します。
とりあえず、わりと綺麗にまとめられたのでもう少し読みやすく調整してUsecaseごとにまとめた形で記事化しようと思う。
このスクラップは一旦クローズする。