更新於 2024/09/02閱讀時間約 3 分鐘

Golang - Design Pattern #26: 延遲評估模式 (Lazy Evaluation)

raw-image
🕰️ 資源節省的智慧 💡

嗨,大家好!今天我們來聊聊什麼是延遲評估模式,它的好處是啥,還有在 Go 裡面是怎麼玩的。


Go的方式


🧮 複雜費時的計算

假如你有個計算超級吃力的功能,但真的只想跑一次,怎麼辦呢?


package main

import (
"fmt"
"sync"
"time"
)

type ComplexCalculation struct {
result int
once sync.Once
}

func (c *ComplexCalculation) calculate() int {
fmt.Println("開始一個複雜的計算...") // 玩玩的模擬一下
time.Sleep(3 * time.Second)
fmt.Println("計算完成啦!")
return 42
}

func (c *ComplexCalculation) Value() int {
c.once.Do(func() {
c.result = c.calculate()
})
return c.result
}

func main() {
calc := &ComplexCalculation{}

fmt.Println("結果:", calc.Value()) // 第一次會真的計算
fmt.Println("結果:", calc.Value()) // 第二次就直接拿答案囉!
}

這小段程式碼就是顯示如何利用 sync.Once 確保重型的計算只跑一次。


📌 複雜的資源初始化

再來個例子!假設你要從一個遙遠的資料庫拉取大量資料。


package main

import (
"fmt"
"sync"
"time"
)

type LargeDataSet struct {
data []int
once sync.Once
}

func (ds *LargeDataSet) loadData() {
fmt.Println("從遠端資料庫拉取資料中...") // 又來模擬
time.Sleep(4 * time.Second)
ds.data = []int{1, 2, 3, 4, 5}
fmt.Println("資料拉取完畢!")
}

func (ds *LargeDataSet) Data() []int {
ds.once.Do(ds.loadData)
return ds.data
}

func main() {
dataSet := &LargeDataSet{}

fmt.Println("資料:", dataSet.Data()) // 第一次會真的拉資料
fmt.Println("資料:", dataSet.Data()) // 第二次直接拿現成的
}

這段程式碼教我們如何只拉取一次大量的資料,後面都直接使用。


結論 🌟

好啦,今天的學習就到這裡!總的來說,sync.Once 在 Go 中真的是個小寶貝,特別是當你想要確保某些重型操作只執行一次時。它不僅能幫你節省資源,還能確保在多執行緒的環境下都安全無虞。如果你的應用需要高效能和靈活性,那絕對不能錯過這個模式!希望你們喜歡今天的分享,下次再見~



感謝

謝謝大家看完這篇,如果您喜歡我的文章,歡迎 小額贊助我 ^^

分享至
成為作者繼續創作的動力吧!
© 2024 vocus All rights reserved.