Future技術(shù)
Future是一個(gè)很有用的技術(shù),我們常常使用Future來(lái)操作線程。我們可以在使用線程的時(shí)候,可以創(chuàng)建一個(gè)線程,返回Future,之后可以通過(guò)它等待結(jié)果。 但是在協(xié)程環(huán)境下的Future可以更加徹底,輸入?yún)?shù)同樣可以是Future的。
調(diào)用一個(gè)函數(shù)的時(shí)候,往往是參數(shù)已經(jīng)準(zhǔn)備好了。調(diào)用協(xié)程的時(shí)候也同樣如此。但是如果我們將傳入的參 數(shù)設(shè)為通道,這樣我們就可以在不準(zhǔn)備好參數(shù)的情況下調(diào)用函數(shù)。這樣的設(shè)計(jì)可以提供很大的自由度和并發(fā)度。函數(shù)調(diào)用和函數(shù)參數(shù)準(zhǔn)備這兩個(gè)過(guò)程可以完全解耦。 下面舉一個(gè)用該技術(shù)訪問(wèn)數(shù)據(jù)庫(kù)的例子。
//一個(gè)查詢結(jié)構(gòu)體
typequery struct {
//參數(shù)Channel
sql chan string
//結(jié)果Channel
result chan string
}
//執(zhí)行Query
funcexecQuery(q query) {
//啟動(dòng)協(xié)程
go func() {
//獲取輸入
sql := <-q.sql
//訪問(wèn)數(shù)據(jù)庫(kù),輸出結(jié)果通道
q.result <- "get" + sql
}()
}
funcmain() {
//初始化Query
q :=
query{make(chan string, 1),make(chan string, 1)}
//執(zhí)行Query,注意執(zhí)行的時(shí)候無(wú)需準(zhǔn)備參數(shù)
execQuery(q)
//準(zhǔn)備參數(shù)
q.sql <- "select * fromtable"
//獲取結(jié)果
fmt.Println(<-q.result)
}
上面利用Future技術(shù),不單讓結(jié)果在Future獲得,參數(shù)也是在Future獲取。準(zhǔn)備好參數(shù)后,自動(dòng)執(zhí)行。Future和生成器的區(qū)別在 于,F(xiàn)uture返回一個(gè)結(jié)果,而生成器可以重復(fù)調(diào)用。還有一個(gè)值得注意的地方,就是將參數(shù)Channel和結(jié)果Channel定義在一個(gè)結(jié)構(gòu)體里面作為 參數(shù),而不是返回結(jié)果Channel。這樣做可以增加聚合度,好處就是可以和多路復(fù)用技術(shù)結(jié)合起來(lái)使用。
Future技術(shù)可以和各個(gè)其他技術(shù)組合起來(lái)用。可以通過(guò)多路復(fù)用技術(shù),監(jiān)聽多個(gè)結(jié)果Channel,當(dāng)有結(jié)果后,自動(dòng)返回。也可以和生成器組合使用,生 成器不斷生產(chǎn)數(shù)據(jù),F(xiàn)uture技術(shù)逐個(gè)處理數(shù)據(jù)。Future技術(shù)自身還可以首尾相連,形成一個(gè)并發(fā)的pipe filter。這個(gè)pipe filter可以用于讀寫數(shù)據(jù)流,操作數(shù)據(jù)流。
Future是一個(gè)非常強(qiáng)大的技術(shù)手段。可以在調(diào)用的時(shí)候不關(guān)心數(shù)據(jù)是否準(zhǔn)備好,返回值是否計(jì)算好的問(wèn)題。讓程序中的組件在準(zhǔn)備好數(shù)據(jù)的時(shí)候自動(dòng)跑起來(lái)。