91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Go通過不變性優化程序的方法是什么

發布時間:2022-08-24 16:35:06 來源:億速云 閱讀:123 作者:iii 欄目:開發技術

這篇文章主要介紹“Go通過不變性優化程序的方法是什么”,在日常操作中,相信很多人在Go通過不變性優化程序的方法是什么問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Go通過不變性優化程序的方法是什么”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

減少對全局或外部狀態的依賴

當我們使用相同的參數,執行相同的函數兩次,我們的預期,應該得到相同的結果。但是當我們的函數中依賴外部狀態或全局變量時,函數可能會輸出不同的結果。我們最好避免這種情況。

函數的參數總是給定的,那我們調用,總是可以返回相同的函數。如果您有一個共享全局變量用于函數內部的某些內容,請考慮將該變量作為參數傳遞,而不是直接函數內部使用它。

這可以讓您的函數返回值更加可預測,并且更加易于測試,整個代碼的可讀性也會得到提高,因為調用者會知道,哪些值會影響函數的行為,參數的作用不就是會影響返回值的嗎?

讓我們看一個例子。

package main
import (
   "fmt"
   "math/rand"
   "time"
)
var randNum int
func main() {
   s1 := rand.NewSource(time.Now().UnixNano())
   r1 := rand.New(s1)
   randNum = r1.Intn(100)
   fmt.Println(Add(1, 1))
}
func Add(a, b int) int {
   return a + b + randNum
}

Add 函數中使用了全局變量 randNum 作為計算的一部分,從函數簽名中并沒有體現這一點。更好的方法是,全局變量 randNum 應該作為參數傳遞,如下所示。

func Add(a, b, randNum int) int {
   return a + b + randNum
}

這樣更具有可預測性,而且我們如果需要修改入參,影響的作用域也僅在 Add 函數中。

僅導出結構體的函數,而不是成員變量

我們知道,Go 結構體中的成員變量,如果首字母為大寫,那么該成員變量對外可見(這是編譯器決定的)。回到我們的博客,僅導出結構體函數,而不是成員變量,目的是希望成員變量的數據被保護,保證成員變量的有效的狀態!因為這可以讓您的代碼更加可靠,您不必維護每個修改該成員變量的操作,因為這些操作都將無效。

舉一個例子

ackage main
import (
	"fmt"
)
type AK47 struct {
	bullet int
}
func NewAK47(bullet int) AK47 {
	return AK47{bullet: bullet}
}
func (a AK47) GetBullet() int {
	return a.bullet
}
func (a AK47) SetBullet(bullet int) {
	a.bullet = bullet
}
func main() {
	ak47 := NewAK47(30)
	fmt.Println(ak47.GetBullet())
	ak47.SetBullet(20)
	fmt.Println(ak47.GetBullet())
}

我們定義了一個結構體 AK47,這把槍有一個成員變量 bullet 子彈數,它是非導出字段,我們還定義了一個構造函數 NewAK47 和一個 GetBullet 函數。

一旦創建了 AK47,就無法更改它的成員變量 bullet 了。此時您可能會有疑惑,如果我們需要修改成員變量呢?別急,您可以試試下面的方法。

在函數中使用復制值,而不是使用指針

在上一個副標題中,我們提到了一個概念,在創建結構體后永遠不要更改它。然而在實際中,我們經常需要修改結構體中的成員變量。

我們在使用不變性的同時,仍然可以維護實例化結構體的多個狀態,這并不意味著我們打破了結構體創建后不要更改它,我們更改的是它的副本,也就是復制后的結構體。復制后的結構體?難道我們需要去實現很多復制結構體每個字段的函數嗎?

當然不,我們可以利用 Go 的特性,在調用函數時,入參是復制值的行為。對于需要修改結構體中成員變量的操作,我們可以創建一個函數,該函數接收結構體為參數,并且返回一個修改后的結構體副本。

我們可以在不改變調用方結構體的情況下,修改該副本的任何內容,這意味著對于原結構體沒有任何副作用,并且該結構體的值仍然是可預測的。

不知道您有沒有用過 Go 標準庫的 Slice 切片,其中的 append 函數就使用了這個方法。讓我們接著用 AK47 來實現這個方法

代碼如下

package main
import (
	"fmt"
)
type AK47 struct {
	bullet int
}
func NewAK47(bullet int) AK47 {
	return AK47{bullet: bullet}
}
func (a AK47) GetBullet() int {
	return a.bullet
}
func (a AK47) AddBullet(ak47 AK47) AK47 {
	newAK47 := NewAK47(a.GetBullet() + ak47.GetBullet())
	return newAK47
}
func main() {
	ak47 := NewAK47(30)
	add := NewAK47(20)
	fmt.Println(ak47.GetBullet())
	ak47 = ak47.AddBullet(add)
	fmt.Println(ak47.GetBullet())
}

如您所見,我們通過 AddBullet 函數增加槍的子彈,但實際上并沒有更改傳入的結構體中的任何成員變量。最后,返回了一個帶有更新字段的新 AK47 結構體。

與復制值相比,指針更有優勢,尤其是當您的結構體成員變量、內容非常大時時,這種方法,通過復制的方式修改數據,可能會導致性能問題。

到此,關于“Go通過不變性優化程序的方法是什么”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

go
AI

仙桃市| 桓台县| 衡阳市| 固原市| 富锦市| 寻甸| 鄯善县| 榆林市| 米易县| 玉环县| 额敏县| 昌图县| 慈利县| 兴业县| 博乐市| 芮城县| 抚远县| 泗水县| 嘉祥县| 江永县| 玉山县| 东明县| 建瓯市| 友谊县| 晋州市| 定西市| 肃北| 成武县| 大石桥市| 卓资县| 阳山县| 济阳县| 威远县| 盘锦市| 西乡县| 天台县| 平远县| 青海省| 本溪市| 邹城市| 德阳市|