[翻譯] effective go 之 Initialization

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

Initialization

Although it doesn't look superficially very different from initialization in C or C++, initialization in Go is more powerful. Complex structures can be built during initialization and the ordering issues between initialized objects in different packages are handled correctly.

從表面上看 Go的初始化和C/C++區別不大 但是Go更加給力 複雜的資料結構可以在初始化的時候建立起來 並且Go可以準確地處理不同包之間的對象初始化順序


Constants 常量初始化

Constants in Go are just that—constant. They are created at compile time, even when defined as locals in functions, and can only be numbers, strings or booleans. Because of the compile-time restriction, the expressions that define them must be constant expressions, evaluatable by the compiler. For instance, 1<<3 is a constant expression, while math.Sin(math.Pi/4) is not because the function call to math.Sin needs to happen at run time.

Go中的常量在編譯的時候建立 即使變數是定義在函數內的局部變數 也是在編譯過程中搞定 常量只可以是數字 字串 或者布爾值  受限於這個條件 常量運算式必須是可以被編譯器推匯出的 舉例來說1<<3 是常量運算式 而math.Sin(math.Pi/4)就不是常量運算式 因為這裡涉及到了函數調用 這個是在運行時才進行計算的

In Go, enumerated constants are created using the iota enumerator. Since iota can be part of an expression and expressions can be implicitly repeated, it is easy to build intricate sets of values.

Go中的枚舉常量 可以通過iota來建立 由於iota可以是運算式的一部分 而且運算式可以被重複 可以很容易地建立複雜的資料集 每一個const關鍵字出現時 iota會被重設為0 iota會在下一次引用時自動+1 當const賦值運算式相同時可省略之後的賦值運算式 下面的這個例子的賦值運算式就省略了 統一為 1<<(10*iota)

type ByteSize float64const (    _           = iota // ignore first value by assigning to blank identifier         KB ByteSize = 1 << (10 * iota)    MB    GB    TB    PB    EB    ZB    YB)


The ability to attach a method such as String to a type makes it possible for such values to format themselves automatically for printing, even as part of a general type.

Go中可以為大多數類型定義方法 比如為某個類型定義String方法 就可以輸出改類型的字串表達形式

func (b ByteSize) String() string {    switch {    case b >= YB:        return fmt.Sprintf("%.2fYB", b/YB)    case b >= ZB:        return fmt.Sprintf("%.2fZB", b/ZB)    case b >= EB:        return fmt.Sprintf("%.2fEB", b/EB)    case b >= PB:        return fmt.Sprintf("%.2fPB", b/PB)    case b >= TB:        return fmt.Sprintf("%.2fTB", b/TB)    case b >= GB:        return fmt.Sprintf("%.2fGB", b/GB)    case b >= MB:        return fmt.Sprintf("%.2fMB", b/MB)    case b >= KB:        return fmt.Sprintf("%.2fKB", b/KB)    }    return fmt.Sprintf("%.2fB", b)}

The expression YB prints as 1.00YB, while ByteSize(1e13) prints as 9.09TB.

通過這個函數 YB可以列印成1.00YB, 而ByteSize(1e13)則列印成9.09TB

Note that it's fine to call Sprintf and friends in the implementation of String methods, but beware of recurring into the String method through the nested Sprintf call using a string format (%s, %q, %v, %x or %X). The ByteSize implementation of String is safe because it calls Sprintf with %f.

在寫String函數的時候 可以調用Sprintf以及相關的輸出函數 但是要注意防止Sprintf使用格式化修飾符%s, %q, %v, %x, %X, 這裡ByteSize的String方法是安全的 因為只用了%f修飾符


Variables 變數初始化

Variables can be initialized just like constants but the initializer can be a general expression computed at run time.

變數可以想常量一樣被初始化 但是也可以通過一般的運算式 在運行時再對其初始化

var (    home   = os.Getenv("HOME")    user   = os.Getenv("USER")    goRoot = os.Getenv("GOROOT"))


The init function init初始化函數

Finally, each source file can define its own niladic init function to set up whatever state is required. (Actually each file can have multiple init functions.) And finally means finally: init is called after all the variable declarations in the package have evaluated their initializers, and those are evaluated only after all the imported packages have been initialized.

每個源檔案都可以定義自己的init初始化函數(可以有多個init函數)init會在所有包中 變數初始化完成後調用 這個概念可以和其它物件導向的建構函式做對比 最特徵化的子類 最後才被初始化 而父類最先被初始化

Besides initializations that cannot be expressed as declarations, a common use of init functions is to verify or repair correctness of the program state before real execution begins.

init的通常用在 程式真正執行前 驗證並且修複程式的狀態

func init() {    if user == "" {        log.Fatal("$USER not set")    }    if home == "" {        home = "/home/" + user    }    if goRoot == "" {        goRoot = home + "/go"    }    // goRoot may be overridden by --goroot flag on command line.    flag.StringVar(&goRoot, "goroot", goRoot, "Go root directory")}

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.