2020年3月10日 星期二

golang inner func() 讓code變優雅變精巧


原始 for loop裡在進入時會進行許多的資料判別是否可以往下運行。程式看起來非常的冗長
func (a *ArbTriangular) stg() {
    var (
        askDetph   map[string]db.Order10Depth
        lastTicker map[string]db.LastTicker
    )
    // ...
    // ...
    // ...
    for _, st := range *a.sTriangular {
        if st.isTrading {
            continue
        }
        if _, b := askDetph[st.a]; !b {
            continue
        }
        if _, b := askDetph[st.b]; !b {
            continue
        }
        if _, b := askDetph[st.c]; !b {
            continue
        }
        if _, b := lastTicker[st.a]; !b {
            continue
        }
        if _, b := lastTicker[st.b]; !b {
            continue
        }
        if _, b := lastTicker[st.c]; !b {
            continue
        }
        // ...
        // ...
        // ...
    }
}

進行一次的重構,for loop 看起來好多了,但是冗長的if判別看起來還是不夠優雅
func (a *ArbTriangular) stg() {
    var (
        askDetph map[string]db.Order10Depth
        bidDetph map[string]db.Order10Depth
    )
    checkData := func(st SymboleTriangular) (b bool) {
        if st.isTrading {
            return
        }
        if _, b = askDetph[st.a]; !b {
            return
        }
        if _, b = askDetph[st.b]; !b {
            return
        }
        if _, b = askDetph[st.c]; !b {
            return
        }
        if _, b = bidDetph[st.a]; !b {
            return
        }
        if _, b = bidDetph[st.b]; !b {
            return
        }
        if _, b = bidDetph[st.c]; !b {
            return
        }
        b = true
        return
    }
    //...
    //...
    //...
    for _, st := range *a.sTriangular {
        if !checkData(st) {
            continue
        }
        //...
        //...
        //...
    }
}

進行第二次的重構,這樣的成果優雅又精簡巧
func (a *ArbTriangular) stg() {
    var (
        askDetph map[string]db.Order10Depth
        bidDetph map[string]db.Order10Depth

        existAsk = func(s string) (b bool) {
            _, b = askDetph[s]
            return
        }
        existBid = func(s string) (b bool) {
            _, b = bidDetph[s]
            return
        }
        checkData = func(st SymboleTriangular) bool {
            if st.isTrading ||
                !existAsk(st.a) || !existAsk(st.b) || !existAsk(st.c) ||
                !existBid(st.a) || !existBid(st.b) || !existBid(st.c) {
                return false
            }
            return true
        }
    )
    //...
    //...
    //...
    for _, st := range *a.sTriangular {
        if !checkData(st) {
            continue
        }
        //...
        //...
        //...
    }
}

沒有留言:

張貼留言