2017年11月12日 星期日

Redux in go

剛才利用一點時間寫了一個Go版本的Redux
https://github.com/dannypsnl/redux
發現一些有趣的設計議題
我們先看到一個標準Redux程式(JS版本)
function counter(state = 0, action) {
  switch (action.type) {
  case 'INCREMENT':
    return state + 1
  case 'DECREMENT':
    return state - 1
  default:
    return state
  }
}

let store = createStore(counter)
store.dispatch({ type: 'INCREMENT' })
Redux設計思想是藉由回傳新的狀態取代改變手上的狀態來進行狀態管理
我們來看看Go版本(現在的實現)
func counter(state interface{}, act redux.Action) interface{} {
    switch act.Type {
    case "INC":
        return state.(int)+1
    case "DEC":
        return state.(int)-1
    default:
        return state
    }
}

func main() {
    store := redux.NewStore(counter)
    store.Dispatch(redux.SendAction("INC"))

    fmt.Printf("Now state is %v\n", store.GetState())
}
在API上我沒有特別設計,所以我發現兩個問題
第一,不能有型別,有點尷尬對吧
沒有型別我們就要非常小心的確保我們在做什麼,以避免錯誤的轉型
第二,我們沒有辦法設定初始值,這下就有趣了,目前我是先強制給0才能運作,這當然是不對的,下一步應該會調整這部份的API,當然還是會盡量保持與Redux本身相同

至於第一個問題,其實只是麻煩而已,只要回到定義Reducer的地方,我們還是能夠取得正確的型別資訊,當然如果Go擁有泛型,我們今天就不用這麼麻煩了
關於泛型,我覺得重點在於它在參數之前完成計算,就是最重要的特點
如果獲得泛型,確實能夠解決我們現在遇上的麻煩,如何匹配不同型別的state
但是也會帶來別的麻煩,當然這又是另一個故事了...

沒有留言:

張貼留言