[翻译] effective go 之 Names Semicolons
2019獨角獸企業重金招聘Python工程師標準>>>
Names
Names are as important in Go as in any other language. In some cases they even have semantic effect: for instance, 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.
上述代碼中 bytes被導入后 我們可以直接使用bytes.Buffer 假如每個使用包的人 可以通過同樣的名字引用到包中的內容 那將非常給力 這也意味著包的名字需要精簡 富有含義 習慣上包名是小寫的單個單詞 通常不需要使用下劃線或者駱駝式來給包起名 不必擔心包名有沖突 包名只是在導入時使用的默認名字 它不需要在所有的代碼中獨一無二 如果出現名字沖突 可以起一個本地的不同的名字 類似python中的import xxx as yyy?
Another convention is that the package name is the base name of its source directory; the package in?src/pkg/encoding/base64?is imported as?"encoding/base64"?but has name?base64, not?encoding_base64?and not?encodingBase64.
另外一個習慣是 包名是源代碼結構里的目錄名字 包src/pkg/encoding/base64 可以通過"encoding/base64"導入 而不是 encoding_base64 或者 encodingBase64
The importer of a package will use the name to refer to its contents (the?import .?notation is intended mostly for tests and other unusual situations and should be avoided unless necessary), so exported names in the package can use that fact to avoid stutter. For instance, the buffered reader type in the?bufio?package is called?Reader, notBufReader, 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 asring.New. Use the package structure to help you choose good names.
包導入后 可以通過包名訪問它的內容 這樣帶來的好處是 減少名字中的有重復含義的部分 例如 沒必要在導入bufio包后 還使用BufReader來使用Reader 可以直接使用bufio.Reader 這樣的使用方式給人的感覺更加簡單明了 另外 包中內容總是通過包名來訪問 所以bufio.Reader 就不會和 io.Reader沖突 同樣地 創建ring.Ring的函數 在其它語言里可能被定義為NewRing 但是Ring就是唯一一個被導出的類型 而且包名是ring 那么可以函數名可以定義為New 使用的時候 調用ring.New
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. If the name represents something intricate or subtle, it's usually better to write a helpful doc comment than to attempt to put all the information into the name.
再舉個例子 once.Do; once.Do(setup)就是一個很好的命名方式 寫成once.DoOrWatiUnitDone(setup)并不會給理解這個函數的功能提供更多的信息 冗長的名字并不會讓代碼更加易讀 如果名字需要表達復雜 或者光靠幾個單詞說不清楚的意思 那么最好還是加一段文檔注釋吧 (code complete里面也有推薦這樣的方式)
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:
Go沒有提供setter和getter的支持 但是只要你愿意 你來寫也無妨 而且經常建議你這么做 但是在函數名里并不需要帶個Get 如果有一個字段是owner 這個getter的名字可以直接定義為Owner 不要起GetOwner這樣的名字 看著別扭 首字母大寫作為可被導出的標識有點醒目哈 和其它的區別開 如果需要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 the -er suffix:?Reader,?Writer,?Formatter?etc.
習慣上 只包含一個方法的接口命名時 在結尾加上er作為后綴 例如:Reader Writer Formatter等等
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?notToString.
使用這個規則命名的例子很多 Read Write Close Flush String等等有它們典型的申明特征和含義 相比之下 如果你的自定義類型實現了大家都認可的類型方法 給它定義相同的名字和申明 例如 把你的類型轉換成string類型 給你的轉換函數起名為String 而不是ToString
MixedCaps
Finally, the convention in Go is to use?MixedCaps?or?mixedCaps?rather than underscores to write multiword names.
最后 Go使用駱駝式命名法 不用下劃線的方式
Semicolons
Like C, Go's formal grammar uses semicolons to terminate statements; unlike C, those semicolons do not appear in the source. Instead the lexer uses a simple rule to insert semicolons automatically as it scans, so the input text is mostly free of them.
和C一樣 Go使用分號結束語句 但是也有和C不同的放 在Go代碼里通常看不到分號 詞法分析器在分析源代碼時 使用簡易的規則來自動地插入分號
The rule is this. If the last token before a newline is an identifier (which includes words like?int?and?float64), a basic literal such as a number or string constant, or one of the tokens
如果在換行符前的一個token是一個標識符(int float64之流), 數字或者字符串常量,亦或是以下幾個token:
break continue fallthrough return ++ -- ) }the lexer always inserts a semicolon after the token. This could be summarized as, “if the newline comes after a token that could end a statement, insert a semicolon”.
詞法分析器就在這個token后面加上一個分號?
A semicolon can also be omitted immediately before a closing brace, so a statement such as
緊接在閉括號后的分號可以省略 就像下面這個例子:
go func() { for { dst <- <-src } }()needs no semicolons. Idiomatic Go programs have semicolons only in places such as?for?loop clauses, to separate the initializer, condition, and continuation elements. They are also necessary to separate multiple statements on a line, should you write code that way.
通常Go程序中使用分號的地方只有for循環 為了區分初始值 條件和后續的元素 如果同一行有多個語句 那么也需要使用分號 但還是一行一句吧?
One caveat. You should never put the opening brace of a control structure (if,?for,?switch, or?select) on the next line. If you do, a semicolon will be inserted before the brace, which could cause unwanted effects. Write them like this
提醒一點 絕對不要把起始括號放在下一行(if for switch select語句中的括號) 如果你這樣做了 詞法分析器會插一個分號在括號前面 下面這個寫法是正確的
if i < f() {g() }not like this 下面這個是錯誤的寫法
if i < f() // wrong! { // wrong!g() }轉載于:https://my.oschina.net/pengfeix/blog/108062
總結
以上是生活随笔為你收集整理的[翻译] effective go 之 Names Semicolons的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 梦到黑白无常是什么意思
- 下一篇: 女人梦到着大火是什么预兆