2021-10-22
創(chuàng)新互聯(lián)公司是一家專業(yè)提供新市企業(yè)網(wǎng)站建設(shè),專注與成都網(wǎng)站設(shè)計、網(wǎng)站建設(shè)、HTML5、小程序制作等業(yè)務(wù)。10年已為新市眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)站制作公司優(yōu)惠進(jìn)行中。
每一個變量(常量、類型或函數(shù))在程序中都有一定的作用范圍。稱之為作用域。
Go語言在編譯時會檢查每一個變量是否使用過,未使用過的變量就會編譯錯誤。
根據(jù)變量定義位置的不同,可以分為以下三個類型:
在函數(shù)體內(nèi)被聲明的變量稱之為局部變量,作用在函數(shù)體內(nèi),函數(shù)的參數(shù)和返回值變量都屬于局部變量。局部變量不會一直存在,在函數(shù)被調(diào)用時存在,函數(shù)調(diào)用結(jié)束后變量就會被銷毀,即生命周期。
例子:其中a、b均為局部變量,只會在main函數(shù)內(nèi)有效
在函數(shù)體外被聲明的變量稱之為全局變量,作用于所有源文件。不包含這個全局變量的源文件需要使用"import"關(guān)鍵字引入全局變量所在的源文件之后才能使用這個全局變量。
全局變量聲明必須以 var 關(guān)鍵字開頭,如果想要在外部包中使用全局變量的首字母必須大寫。
例如:global為全局在main2和main函數(shù)中都能使用
函數(shù)名后面的小括號里定義的變量, 用于接受來自調(diào)用函數(shù)的參數(shù)。用于接收調(diào)用該函數(shù)時傳入的參數(shù)。
例如:下面的例子中,第十七行a、b為sum函數(shù)定義的形參,用于傳入main函數(shù)中的AF、BF
變量名=
$變量名
/etc/profile == /etc/bashrc 全局生效
~/.bashrc == ~/.bash_profile 指定用戶生效
當(dāng)在全局和用戶文件中同時配置同一個別名或變量時,用戶文件中的優(yōu)先
export 環(huán)境變量=xxx
修改 /etc/profile 文件,增加變量會對Linux下所有用戶有效,并且是“永久的”。
修改 ~/.bash_profile 文件,增加變量會對當(dāng)前用戶有效,并且是“永久的”。
使用export定義變量,該變量只在當(dāng)前的shell(BASH)或其子shell(BASH)下是有效的,shell關(guān)閉了,變量也就失效了,再打開新shell時就沒有這個變量,需要使用的話還需要重新定義。
alias 別名名稱='命令信息'
參考永久設(shè)置變量,編輯 /etc/profile 、 ~/.bash_profile 等文件
1.unalias 別名名稱
2.\別名
3.到命令的絕對路徑下執(zhí)行,如 /usr/bin/ls
大家經(jīng)常用"=="來比較兩個變量是否相等。但是golang中的"=="有很多細(xì)節(jié)的地方,跟php是不一樣的。很多時候不能直接用"=="來比較,編譯器會直接報錯。
golang中基本類型的比較規(guī)則和復(fù)合類型的不一致,先介紹下golang的變量類型:
golang中的基本類型
比較的兩個變量類型必須相等。而且,golang沒有隱式類型轉(zhuǎn)換,比較的兩個變量必須類型完全一樣,類型別名也不行。如果要比較,先做類型轉(zhuǎn)換再比較。
復(fù)合類型是逐個字段,逐個元素比較的。需要注意的是, array 或者struct中每個元素必須要是可比較的,如果某個array的元素 or struct的成員不能比較(比如是后面介紹的slice,map等),則此復(fù)合類型也不能比較。
逐個成員比較類型和值。每個對應(yīng)成員的比較遵循基本類型變量的比較規(guī)則。
但是如果struct中有不可比較的成員類型時:
可以看到,struct中有slice這種不可比較的成員時,整個struct都不能做比較,即使沒有對slice那個成員賦值(slice默認(rèn)值為nil)
slice和map的比較規(guī)則比較奇怪,我們先說普通的變量引用類型val和channel的比較規(guī)則。
引用類型變量存儲的是某個變量的內(nèi)存地址。所以引用類型變量的比較,判斷的是這兩個引用類型存儲的是不是同一個變量。
上面看起來比較廢話,但是得理解引用類型的含義。不然對判斷規(guī)則還是不清楚。
slice類型不可比較,只能與零值nil做比較。
關(guān)于slice類型不可比較的原因,后面會專門寫文章做討論。
map類型和slice一樣,不能比較,只能與nil做比較。
接口類型的變量,包含該接口變量存儲的值和值的類型兩部分組成,分別稱為接口的動態(tài)類型和動態(tài)值。 只有動態(tài)類型和動態(tài)值都相同時,兩個接口變量才相同:
而且接口的動態(tài)類型必須要是可比較的,如果不能比較(比如slice,map),則運(yùn)行時會報panic。因為編譯器在編譯時無法獲取接口的動態(tài)類型,所以編譯能通過,但是運(yùn)行時直接panic:
golang的func作為一等公民,也是一種類型,而且不可比較
上面說過,map和slice是不可比較類型,但是有沒有特殊的方法來對slice和map做比較呢,有
reflect.DeepEqual函數(shù)可以用來比較兩個任意類型的變量
對map類型做比較:
對slice類型做比較:
對struct類型做比較:
可以發(fā)現(xiàn),只要變量的類型和值相同的話,reflect.DeepEqual比較的結(jié)果就為true
直接看用例:
結(jié)果為:
1, golang的類型再定義和類型別名
2,golang的slice和map為什么不可以比較
1,
2,
3,
局部變量
在函數(shù)體內(nèi)聲明的變量稱之為局部變量,它們的作用域只在函數(shù)體內(nèi),參數(shù)和返回值變量也是局部變量。
以下實例中 main() 函數(shù)使用了局部變量 a, b, c:
package main
import "fmt"
func main() {
/* 聲明局部變量 */
var a, b, c int
/* 初始化參數(shù) */
a = 10
b = 20
c = a + b
fmt.Printf ("結(jié)果: a = %d, b = %d and c = %d\n", a, b, c)
}
以上實例執(zhí)行輸出結(jié)果為:
結(jié)果: a = 10, b = 20 and c = 30
全局變量
在函數(shù)體外聲明的變量稱之為全局變量,全局變量可以在整個包甚至外部包(被導(dǎo)出后)使用。
全局變量可以在任何函數(shù)中使用,以下實例演示了如何使用全局變量:
package main
import "fmt"
/* 聲明全局變量 */
var g int
func main() {
/* 聲明局部變量 */
var a, b int
/* 初始化參數(shù) */
a = 10
b = 20
g = a + b
fmt.Printf("結(jié)果: a = %d, b = %d and g = %d\n", a, b, g)
}
以上實例執(zhí)行輸出結(jié)果為:
結(jié)果: a = 10, b = 20 and g = 30
Go 語言程序中全局變量與局部變量名稱可以相同,但是函數(shù)內(nèi)的局部變量會被優(yōu)先考慮。實例如下:
package main
import "fmt"
/* 聲明全局變量 */
var g int = 20
func main() {
/* 聲明局部變量 */
var g int = 10
fmt.Printf ("結(jié)果: g = %d\n", g)
}
以上實例執(zhí)行輸出結(jié)果為:
結(jié)果: g = 10