1. 程式人生 > >GO語言規範-宣告及作用域

GO語言規範-宣告及作用域

文章目錄

塊是指在相匹配的花括號內的,可能為空的一系列宣告和語句。
在原始碼中除了顯式的塊,還有隱式的塊:

  • 全域性塊:涵蓋了所有Go原始碼文字
  • 包塊:涵蓋了一個包的所有Go原始碼文字
  • 檔案塊:涵蓋了在一個檔案內所有Go原始碼文字
  • 每個for、if、switch語句都視為它自身的隱式塊
  • switch、select語句的每個條件都是一個隱式塊
    塊可以巢狀並影響作用域。

宣告及作用域

宣告就是繫結一個非空標識 符到常量、型別、變數、函式、標籤或包。程式中的每個識別符號都必須先宣告。識別符號不能在同一個塊中兩次宣告,識別符號不能在檔案塊和包塊中同時宣告。
空識別符號(“_”)可以像其他的識別符號一樣在宣告中使用,但它不是一個繫結,所以也不是被宣告的。在包塊中,識別符號init只能用於init函式的宣告,與空識別符號一樣也不是一個繫結。

識別符號的作用域是一個被宣告的識別符號所表示的常量、型別、變數、函式、標籤或包在原始碼文字中的延伸。

Go使用塊作為詞法作用域分析:

  1. 預定義識別符號的作用域是全域性塊
  2. 在頂層(所有函式之外)宣告的識別符號所表示的常量、型別、變數、函式(除了方法)的作用域是包塊
  3. 在含有import宣告的檔案裡,被匯入的包的包名的作用域是檔案塊
  4. 表示方法接收者、函式引數或結果變數的識別符號,其作用域是函式體
  5. 函式中宣告的常量或變數識別符號的作用域開始於它宣告之時,結束於包含它的最內層的塊的末尾。
  6. 函式中宣告的型別識別符號的作用域開始於它宣告之時,結束於包含它的最內層的塊的末尾。

在塊中已經宣告的識別符號,在內層塊中可以被重新宣告一個識別符號,內層宣告的識別符號的作用域只在內層塊的範圍內。
package子句並不是一個宣告,其包名也不會出現在任何作用域。其目的是標識檔案屬於同一個包,並指定了在import宣告中的預設包名。

標籤作用域

標籤由標籤語句宣告,用於break、continue、goto語句。定義一個標籤卻不使用是錯誤的。與其他的識別符號不同,標籤不是塊作用域的,不要讓非標籤識別符號與標籤有衝突。標籤的作用域是函式體,但不包括巢狀的函式的函式體。

匯出識別符號

匯出識別符號允許其他的包訪問它。滿足以下條件的識別符號就是匯出的

  1. 識別符號名稱的第一個字母是大寫字母(Unicode中的“Lu”類),並且
  2. 識別符號是在包塊中宣告的,或者是一個欄位名或方法名。

識別符號的唯一性

兩個識別符號如果拼寫不同,那就是不同的;如果它們在不同的包裡並且沒有匯出它們也是不同的。

型別宣告

型別宣告就是將一個稱為型別名的識別符號繫結到一個型別上。型別宣告有兩種形式:別名和型別定義

別名

將一個識別符號繫結到一個型別上

type(
  nodeList = []*Node	// nodList與[]*Node是同一個型別
  Polar = ploar      // Polar與polar代表的是同一個型別
)

型別定義

在基礎型別或操作符之上創造一個新的型別,並將一個識別符號繫結到新型別上。
新的型別被稱為被定義的型別。與別的型別,包括創建出它的型別,都不一樣。

type (
  Point struct{x,y float32} // Point和struct{x,y float32}是兩個不同的型別
  polar Point  // polar和Point也是兩個不同型別
)
type Block interface{
	BlockSize() int
	Encrypt(src, dst []byte)
	Decrypt(src, dst []byte)
}

被定義的型別可以有相關聯的方法。它不繼承給定型別的方法,但介面型別的方法集和組合型別的元素依然保留。

// Mutex是一個有兩個方法(Lock和Unlock)的資料型別
type Mutex struct{/*Mutex的欄位*/}
func (*Mutex)Lock(){/*Lock的實現*/}
func (*Mutex)Unlock(){/*Unlock的實現*/}

// NewMutex與Mutex有相同的元件但方法集是空的
type NewMutex Mutex
// PtrMutex的方法集是空的
type PtrMutex *Mutex
// PrintableMutex具有Lock和Unlock方法,因為是從欄位Mutex中提升的。
PrintableMutex struct{
    Mutex
}

// MyBlock是一個介面型別,與Block有一樣的方法集
type MyBlock Block

變數宣告

變數宣告建立一個或多個變數,並將相應的識別符號繫結到它們,然後賦給型別和初值。

var i int
var U,V,W float64
var k = 0
var x,y float32= -1, -2
var (
  i int
  u, v, s=2.0, 3.0, "bar"
)
var _, found = entries[name] // 對映查詢,只關心結果值found

短變數宣告

i, j := 0, 10
f := func() int { return 7 }
ch := make(chan int)
r, w := os.Pipe(fd)  // os.Pipe() returns two values
_, y, _ := coord(p)  // coord() returns three values; only interested in y coordinate

與常規變數宣告不同的是,短變數宣告可以對變數重新宣告,前提是在同一個塊中(如果塊是函式體,也可以在引數列表)型別不變,並且含有一個新的非空變數。即是說變數的重宣告只能出現在多變數短宣告中。重新宣告並不引入新的變數,只是給原來的變數賦了一個新值。
短變數宣告只能在函式中出現。在諸如if、for、switch語句的初始化中,可用於宣告本地臨時變數。

函式宣告

方法宣告