最近接手其他同學(xué)代碼,發(fā)現(xiàn)業(yè)務(wù)功能實(shí)現(xiàn)了迫横,但是對于在代碼上,利用channel來充當(dāng)回調(diào)函數(shù)酝碳,導(dǎo)致channel在整個(gè)代碼中傳遞來矾踱,傳遞去,看起來相當(dāng)痛苦疏哗,代碼維護(hù)性也比較糟糕呛讲。下面寫一些列子來說明這個(gè)情況。
示例1:利用channel充當(dāng)callback
package main
import (
"fmt"
"time"
)
func main() {
ch := make(chan int)
go handleMsg(ch)
for index := range ch {
fmt.Println(index)
}
}
func handleMsg(ch chan int) {
t := time.Tick(time.Second)
index := 0
for {
select {
case <-t:
ch <- index
index++
}
}
}
雖然看上去返奉,代碼沒啥大問題贝搁,這里有個(gè)潛在問題,利用channel的通信來發(fā)送數(shù)據(jù)芽偏,導(dǎo)致channel暴露在外部雷逆。接下來,我們看下示例2
示例2:隱藏內(nèi)部細(xì)節(jié)哮针,使用只讀channel
package main
import (
"fmt"
"time"
)
func main() {
for val := range handleMsg() {
fmt.Println("index", val)
}
}
func handleMsg() <-chan int {
ch := make(chan int)
t := time.Tick(time.Second * 1)
index := 0
go func(index int) {
for {
select {
case <-t:
ch <- index
index++
}
}
}(index)
return ch
}
看关面,經(jīng)過??上面代碼改造坦袍,是不是隱藏了channel的細(xì)節(jié)十厢,不產(chǎn)生channel的交互式調(diào)用關(guān)系,不要著急捂齐,我們看下面示例3??
示例3:函數(shù)做參數(shù)callback
package main
import (
"fmt"
"time"
)
func main() {
callBack := func(index int) {
fmt.Println("index:",index)
}
handleMsg(callBack)
}
func handleMsg(callBack func(index int)) {
t := time.Tick(time.Second)
index := 0
for {
select {
case <-t:
callBack(index)
index++
}
}
}
因?yàn)間olang的函數(shù)可以做參數(shù)傳遞蛮放,可以很好解決回調(diào)的問題,這樣沒有帶來channel使用的煩惱奠宜,似乎包颁,利用callback這個(gè)特性,使得在代碼上压真,看起來更加簡潔明了娩嚼。