go語言筆記——指針,和C用法以及本質一樣,但不支持指針的+-運算!


4.4.2 值類型和引用類型

所有像 int、float、bool 和 string 這些基本類型都屬於值類型,使用這些類型的變量直接指向存在內存中的值。

Go 語言的取地址符是 &,放到一個變量前使用就會返回相應變量的內存地址。

示例 4.22 string_pointer.go

package main
import "fmt" func main() { s := "good bye" var p *string = &s *p = "ciao" fmt.Printf("Here is the pointer p: %p\n", p) // prints address fmt.Printf("Here is the string *p: %s\n", *p) // prints string fmt.Printf("Here is the string s: %s\n", s) // prints same string }

輸出:

Here is the pointer p: 0x2540820
Here is the string *p: ciao
Here is the string s: ciao

通過對 *p 賦另一個值來更改“對象”,這樣 s 也會隨之更改。

內存示意圖如下:

 

 

傳遞指針給函數不但可以節省內存(因為沒有復制變量的值),而且賦予了函數直接修改外部變量的能力,所以被修改的變量不再需要使用 return 返回。如下的例子,reply 是一個指向 int 變量的指針,通過這個指針,我們在函數內修改了這個 int 變量的數值。

 

示例 6.6 side_effect.go

 

package main

import ( "fmt" ) // this function changes reply: func Multiply(a, b int, reply *int) { *reply = a * b } func main() { n := 0 reply := &n Multiply(10, 5, reply) fmt.Println("Multiply:", *reply) // Multiply: 50 }

 

在 Go 語言中,指針(第 4.9 節)屬於引用類型,其它的引用類型還包括 slices(第 7 章),maps(第 8 章)和 channel(第 13 章)。被引用的變量會存儲在堆中,以便進行垃圾回收,且比棧擁有更大的內存空間。

 在函數調用時,像切片(slice)、字典(map)、接口(interface)、通道(channel)這樣的引用類型都是默認使用引用傳遞(即使沒有顯式的指出指針)

 

4.4.5 init 函數

變量除了可以在全局聲明中初始化,也可以在 init 函數中初始化。這是一類非常特殊的函數,它不能夠被人為調用,而是在每個包完成初始化后自動執行,並且執行優先級比 main 函數高。

每一個源文件都可以包含一個或多個 init 函數。初始化總是以單線程執行,並且按照包的依賴關系順序執行。

一個可能的用途是在開始執行程序之前對數據進行檢驗或修復,以保證程序狀態的正確性。

示例 4.6 init.go:

package trans

import "math" var Pi float64 func init() { Pi = 4 * math.Atan(1) // init() function computes Pi }

在它的 init 函數中計算變量 Pi 的初始值。

示例 4.7 user_init.go 中導入了包 trans(在相同的路徑中)並且使用到了變量 Pi:

package main

import ( "fmt" "./trans" ) var twoPi = 2 * trans.Pi func main() { fmt.Printf("2*Pi = %g\n", twoPi) // 2*Pi = 6.283185307179586 }

init 函數也經常被用在當一個程序開始之前調用后台執行的 goroutine,如下面這個例子當中的 backend()

func init() { // setup preparations go backend() }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM