第二個(gè)程序,空間都沒(méi)有分配就初始化賦值,這根本就是在給系統(tǒng)添亂嘛。
創(chuàng)新互聯(lián)公司-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價(jià)比鳳縣網(wǎng)站開(kāi)發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫(kù),直接使用。一站式鳳縣網(wǎng)站制作公司更省心,省錢(qián),快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋鳳縣地區(qū)。費(fèi)用合理售后完善,十余年實(shí)體公司更值得信賴。
本文介紹一些Go語(yǔ)言的基礎(chǔ)語(yǔ)法。
先來(lái)看一個(gè)簡(jiǎn)單的go語(yǔ)言代碼:
go語(yǔ)言的注釋方法:
代碼執(zhí)行結(jié)果:
下面來(lái)進(jìn)一步介紹go的基礎(chǔ)語(yǔ)法。
go語(yǔ)言中格式化輸出可以使用 fmt 和 log 這兩個(gè)標(biāo)準(zhǔn)庫(kù),
常用方法:
示例代碼:
執(zhí)行結(jié)果:
更多格式化方法可以訪問(wèn)中的fmt包。
log包實(shí)現(xiàn)了簡(jiǎn)單的日志服務(wù),也提供了一些格式化輸出的方法。
執(zhí)行結(jié)果:
下面來(lái)介紹一下go的數(shù)據(jù)類型
下表列出了go語(yǔ)言的數(shù)據(jù)類型:
int、float、bool、string、數(shù)組和struct屬于值類型,這些類型的變量直接指向存在內(nèi)存中的值;slice、map、chan、pointer等是引用類型,存儲(chǔ)的是一個(gè)地址,這個(gè)地址存儲(chǔ)最終的值。
常量是在程序編譯時(shí)就確定下來(lái)的值,程序運(yùn)行時(shí)無(wú)法改變。
執(zhí)行結(jié)果:
執(zhí)行結(jié)果:
Go 語(yǔ)言的運(yùn)算符主要包括算術(shù)運(yùn)算符、關(guān)系運(yùn)算符、邏輯運(yùn)算符、位運(yùn)算符、賦值運(yùn)算符以及指針相關(guān)運(yùn)算符。
算術(shù)運(yùn)算符:
關(guān)系運(yùn)算符:
邏輯運(yùn)算符:
位運(yùn)算符:
賦值運(yùn)算符:
指針相關(guān)運(yùn)算符:
下面介紹一下go語(yǔ)言中的if語(yǔ)句和switch語(yǔ)句。另外還有一種控制語(yǔ)句叫select語(yǔ)句,通常與通道聯(lián)用,這里不做介紹。
if語(yǔ)法格式如下:
if ... else :
else if:
示例代碼:
語(yǔ)法格式:
另外,添加 fallthrough 會(huì)強(qiáng)制執(zhí)行后面的 case 語(yǔ)句,不管下一條case語(yǔ)句是否為true。
示例代碼:
執(zhí)行結(jié)果:
下面介紹幾種循環(huán)語(yǔ)句:
執(zhí)行結(jié)果:
執(zhí)行結(jié)果:
也可以通過(guò)標(biāo)記退出循環(huán):
--THE END--
如果該函數(shù)會(huì)修改receiver,此時(shí)一定要用指針
如果receiver是 struct 并且包含互斥類型 sync.Mutex ,或者是類似的同步變量,receiver必須是指針,這樣可以避免對(duì)象拷貝
如果receiver是較大的 struct 或者 array ,使用指針則更加高效。多大才算大?假設(shè)struct內(nèi)所有成員都要作為函數(shù)變量傳進(jìn)去,如果覺(jué)得這時(shí)數(shù)據(jù)太多,就是struct太大
如果receiver是 struct , array 或者 slice ,并且其中某個(gè)element指向了某個(gè)可變量,則這個(gè)時(shí)候receiver選指針會(huì)使代碼的意圖更加明顯
如果receiver使較小的 struct 或者 array ,并且其變量都是些不變量、常量,例如 time.Time ,value receiver更加適合,因?yàn)関alue receiver可以減少需要回收的垃圾量。
于c語(yǔ)言相同,go中也有指針和結(jié)構(gòu)體的概念。指針表示變量的內(nèi)存地址,結(jié)構(gòu)體用來(lái)存儲(chǔ)同一類型的數(shù)據(jù)。
定義一個(gè)指針變量,將變量a的地址賦給指針變量p。這樣,指針變量p也就指向了變量a所在的內(nèi)容空間。
new 函數(shù)返回一個(gè)指針變量
fmt.scan() 就是傳入一個(gè)指針變量。
兩種方法都可以使用。
以上簡(jiǎn)要介紹了go語(yǔ)言中的指針和結(jié)構(gòu)體。
熟悉C語(yǔ)言的同學(xué)都知道,查看一個(gè)變量的地址在處理指針的相關(guān)問(wèn)題的時(shí)候直觀重要,在C中直接取地址符 即可。那么在Go語(yǔ)言中如何查看一個(gè)變量的地址,我們使用unsafe.Pointer() 函數(shù)來(lái)查看一個(gè)變量的內(nèi)存地址。
舉例:
type Vertex struct {
X, Y float64
}
func (v Vertex) sqrt() float64 {
return math.Sqrt(v.X * v.X + v.Y * v.Y)
}
func (v Vertex) scale(f float64) { //帶 號(hào) 和不帶*號(hào)的區(qū)別 可以從內(nèi)存地址來(lái)看出
fmt.printf("=======", unsafe.Pointer(v))//v 本身就是指針 存儲(chǔ)的就是地址 不用取地址
v.X = x.X * f
v.Y = v.Y * f
}
func main() {
v := Vertex{3, 4}
fmt.printf("=======", unsafe.Pointer(v))
v.scale(10)
fmt.Println(v.sqrt())
}
//帶 號(hào) 打印的結(jié)果 ====== -%!(EXTRA unsafe.Pointer=0xc00006e070)======%!(EXTRA unsafe.Pointer=0xc00006e070) 相同
//不帶 號(hào) 打印的結(jié)果 ======%!(EXTRA unsafe.Pointer=0xc000094060)======%!(EXTRA unsafe.Pointer=0xc000094090) 不同
去掉*號(hào) 在scale()方法中要對(duì) v 進(jìn)行取地址操作
tips: *號(hào),可以指向指針類型內(nèi)存地址上的值,號(hào),可以獲取值類型的內(nèi)存地址
每一個(gè)變量都有內(nèi)存地址,可以通過(guò)變量來(lái)操作內(nèi)存地址中的值,即內(nèi)存的大小
go語(yǔ)言中獲取變量的內(nèi)存地址方法:通過(guò) 符號(hào)可以獲取變量的地址
定義:普通變量存儲(chǔ)的是對(duì)應(yīng)類型的值,這些類型就叫值類型
變量b,在內(nèi)存中的地址為:0x1040a124,在這個(gè)內(nèi)存地址上存儲(chǔ)的值為:156
定義:指針類型的變量存儲(chǔ)的是?個(gè)地址,所以?叫指針類型或引?類型
b 是值類型,它指向的是內(nèi)存地址上的值
a是指針類型,它指向的是b的內(nèi)存地址
指針類型定義,語(yǔ)法: var 變量名 *類型
指針類型在定義完成后,默認(rèn)為空地址,即空指針(nil)
在定義好指針變量后,可以通過(guò)***** 符號(hào)可以獲取指針變量指向的變量
在這里的 *a 等價(jià)于 b,通過(guò)修改 *a ,最終修改的是值類型b的值
這里a,d是值類型,b,c是指針類型
d就相當(dāng)于把a(bǔ)內(nèi)存地址上值,在內(nèi)存中從新開(kāi)辟了一塊空間存儲(chǔ),d和a互不影響
b,c相當(dāng)于指向了a的內(nèi)存地址,當(dāng)使用*號(hào)引用出內(nèi)存地址上的變量上,修改值得,a的值也會(huì)跟著改變