關(guān)于golang類型推斷和變量重聲明詳解
類型推斷是一種編程語(yǔ)言在編譯期自動(dòng)解釋表達(dá)式類型的能力。
1.Go語(yǔ)言的類型推斷可以帶來(lái)哪些好處?
在寫代碼時(shí),我們通過(guò)使用Go語(yǔ)言的類型推斷會(huì)節(jié)省敲擊次數(shù),而節(jié)省下來(lái)的鍵盤敲擊次數(shù)幾乎可以忽略不記。但它真正的好處,往往會(huì)體現(xiàn)在我們寫代碼之后的那些事情上,比如代碼重構(gòu)。
我們依然通過(guò)調(diào)用一個(gè)函數(shù)在聲明name變量的同時(shí)為它賦值,但是這個(gè)函數(shù)不是flag.String,而是由我們自己定義的某個(gè)函數(shù),比如叫g(shù)etTheFlag。
package main import ( "flag" "fmt" ) func main() { var name = getTheFlag() flag.Parse() fmt.Printf("Hello, %v!\n", *name) } func getTheFlag() *string { return flag.String("name", "everyone", "The greeting object.") }
我們可以用getTheFlag函數(shù)包裹(或者說(shuō)包裝)那個(gè)對(duì)flag.String函數(shù)的調(diào)用,并把其結(jié)果直接作為getTheFlag函數(shù)的結(jié)果,結(jié)果的類型是*string。
這樣一來(lái),var name =右邊的表達(dá)式,可以變?yōu)獒槍?duì)getTheFlag函數(shù)的調(diào)用表達(dá)式了。這實(shí)際上是對(duì)“聲明并賦值name變量的那行代碼”的重構(gòu)。
我們通常把不改變某個(gè)程序與外界的任何交互方式和規(guī)則,而只改變其內(nèi)部實(shí)現(xiàn)”的代碼修改方式,叫做對(duì)該程序的重構(gòu)。重構(gòu)的對(duì)象可以是一行代碼、一個(gè)函數(shù)、一個(gè)功能模塊,甚至一個(gè)軟件系統(tǒng)。
你會(huì)發(fā)現(xiàn),你可以隨意改變getTheFlag函數(shù)的內(nèi)部實(shí)現(xiàn),及其返回結(jié)果的類型,而不用修改main函數(shù)中的任何代碼。
這個(gè)命令源碼文件依然可以通過(guò)編譯,并且構(gòu)建和運(yùn)行也都不會(huì)有問(wèn)題。也許你能感覺(jué)得到,這是一個(gè)關(guān)于程序靈活性的質(zhì)變。
我們不顯式地指定變量name的類型,使得它可以被賦予任何類型的值。也就是說(shuō),變量name的類型可以在其初始化時(shí),由其他程序動(dòng)態(tài)地確定。
在你改變getTheFlag函數(shù)的結(jié)果類型之后,Go 語(yǔ)言的編譯器會(huì)在你再次構(gòu)建該程序的時(shí)候,自動(dòng)地更新變量name的類型。
Go 語(yǔ)言是靜態(tài)類型的,所以一旦在初始化變量時(shí)確定了它的類型,之后就不可能再改變。這就避免了在后面維護(hù)程序時(shí)的一些問(wèn)題。另外,請(qǐng)記住,這種類型的確定是在編譯期完成的,因此不會(huì)對(duì)程序的運(yùn)行效率產(chǎn)生任何影響。
Go語(yǔ)言的類型推斷可以帶來(lái)哪些好處?
回答:Go 語(yǔ)言的類型推斷可以明顯提升程序的靈活性,使得代碼重構(gòu)變得更加容易,同時(shí)又不會(huì)給代碼的維護(hù)帶來(lái)額外負(fù)擔(dān)(實(shí)際上,它恰恰可以避免散彈式的代碼修改),更不會(huì)損失程序的運(yùn)行效率。
2.變量的重聲明是什么意思?
涉及到短變量聲明。通過(guò)使用它,我們可以對(duì)同一個(gè)代碼塊中的變量進(jìn)行重聲明。
在 Go 語(yǔ)言中,代碼塊一般就是一個(gè)由花括號(hào)括起來(lái)的區(qū)域,里面可以包含表達(dá)式和語(yǔ)句。Go 語(yǔ)言本身以及我們編寫的代碼共同形成了一個(gè)非常大的代碼塊,也叫全域代碼塊。這主要體現(xiàn)在,只要是公開的全局變量,都可以被任何代碼所使用。相對(duì)小一些的代碼塊是代碼包,一個(gè)代碼包可以包含許多子代碼包,所以這樣的代
碼塊也可以很大。接下來(lái),每個(gè)源碼文件也都是一個(gè)代碼塊,每個(gè)函數(shù)也是一個(gè)代碼塊,每個(gè)if語(yǔ)句、for語(yǔ)句、switch語(yǔ)句和select語(yǔ)句都是一個(gè)代碼塊。甚至,switch或select語(yǔ)句中的case子句也都是獨(dú)立的代碼塊。走個(gè)極端,我就在main函數(shù)中寫一對(duì)緊挨著的花括號(hào)算不算一個(gè)代碼塊?當(dāng)然也算,這甚至還有個(gè)名詞,叫“空代碼塊”。
變量重聲明的前提條件:
- 由于變量的類型在其初始化時(shí)就已經(jīng)確定了,所以對(duì)它再次聲明時(shí)賦予的類型必須與其
原本的類型相同,否則會(huì)產(chǎn)生編譯錯(cuò)誤。 - 變量的重聲明只可能發(fā)生在某一個(gè)代碼塊中。如果與當(dāng)前的變量重名的是外層代碼塊中
的變量,那么就是另外一種含義了。 - 變量的重聲明只有在使用短變量聲明時(shí)才會(huì)發(fā)生,否則也無(wú)法通過(guò)編譯。如果要在此處
聲明全新的變量,那么就應(yīng)該使用包含關(guān)鍵字var的聲明語(yǔ)句,但是這時(shí)就不能與同一個(gè)
代碼塊中的任何變量有重名了 。 - 被“聲明并賦值”的變量必須是多個(gè),并且其中至少有一個(gè)是新的變量。這時(shí)我們才可
以說(shuō)對(duì)其中的舊變量進(jìn)行了重聲明。
這樣來(lái)看,變量重聲明其實(shí)算是一個(gè)語(yǔ)法糖(或者叫便利措施)。它允許我們?cè)谑褂枚套兞柯暶鲿r(shí)不用理會(huì)被賦值的多個(gè)變量中是否包含舊變量??梢韵胂?,如果不這樣會(huì)多寫不少代碼。
var err error n, err := io.WriteString(os.Stdout, "Hello, everyone!\n")
我使用短變量聲明對(duì)新變量n和舊變量err進(jìn)行了“聲明并賦值”,這時(shí)也是對(duì)后者的重聲明。
到此這篇關(guān)于關(guān)于golang類型推斷和變量重聲明詳解的文章就介紹到這了,更多相關(guān)golang類型推斷和變量重聲明內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
教你利用Golang可選參數(shù)實(shí)現(xiàn)可選模式
本文討論Golang函數(shù)可選參數(shù)及函數(shù)類型,以及如何利用可選函數(shù)類型實(shí)現(xiàn)可選模式。同時(shí)通過(guò)構(gòu)造函數(shù)作為示例,實(shí)現(xiàn)強(qiáng)大帶可選參數(shù)的構(gòu)造函數(shù),讓代碼更直觀、靈活、支持?jǐn)U展2023-01-01一文帶你使用golang手?jǐn)]一個(gè)websocket中間件
這篇文章主要為大家詳細(xì)介紹了如何使用golang手?jǐn)]一個(gè)websocket中間件,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,感興趣的小伙伴可以參考一下2023-12-12Go語(yǔ)言實(shí)現(xiàn)開發(fā)一個(gè)簡(jiǎn)單的gRPC Demo
這篇文章主要為大家詳細(xì)介紹了如何利用Go語(yǔ)言實(shí)現(xiàn)開發(fā)一個(gè)簡(jiǎn)單的gRPC Demo,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起了解一下2023-07-07