用 Bitmap 與 AST 做一個配置化時長系統
“
本文通過編故事的方式講解 bitmap&AST 的一個應用場景。這個故事發生在一個網絡遊戲公司裏面,主要登場人物
左邊:導師,名字不重要
右邊:實習生,三多
三多在一家遊戲公司做實習生,一天下午他正在划水,被導師叫了過去:
三多心裏罵娘,但是一想到自己下個月又得交房租了,還是滿含淚水打開了需求文檔,需求文檔大概的意思如下:
三多開始一邊薅頭髮,一邊設計系統,幹到晚上 12 點,搞出了第一版系統架構圖:
其中 DB 表的 schema 爲:
於是三多第二天給導師看設計:
於是三多重新設計了技術方案:
三多把技術方案設計好後,就開始寫代碼,然後項目上線,一切順利,直到幾天後...
三多導師隨便抄起傢伙畫了個圖然後丟給三多讓他去實現:
於是三多實現了這套時長系統,由於系統能力非常靈活,老闆讓 PM 配置了一些非常複雜的時長表達式,被玩家們賜予了親切的稱號:耍猴公司~
下面這段代碼是個 AST 的最小 demo,有興趣的讀者可以看看:
package main
import (
"fmt"
"reflect"
"strconv"
"strings"
)
const (
Number = 0
Operator = 1
)
type Node struct {
Type int
Value string
Left *Node
Right *Node
}
// input: 1 + 4 - 2
// result:
// -
// / \
// + 2
// / \
// 1 4
func getAst(expr string) *Node {
operator := make(map[string]int)
operator["+"] = Operator
operator["-"] = Operator
nodeList := make([]Node, 0)
var root *Node
expr = strings.Trim(expr, " ")
words := strings.Split(expr, " ")
for _, word := range words {
var node Node
if _, ok := operator[word]; ok {
node.Type = Operator
} else {
node.Type = Number
}
node.Value = word
nodeList = append(nodeList, node)
}
for i := 0; i < len(nodeList); i++ {
if root == nil {
root = &nodeList[i]
continue
}
switch nodeList[i].Type {
case Operator:
nodeList[i].Left = root
root = &nodeList[i]
case Number:
root.Right = &nodeList[i]
}
}
return root
}
func getResult(node *Node) string {
switch node.Type {
case Number:
return node.Value
case Operator:
return calc(getResult(node.Left), getResult(node.Right), node.Value)
}
return ""
}
func calc(left, right string, operator string) string {
leftVal, _ := TransToInt(left)
rightVal, _ := TransToInt(right)
val := 0
switch operator {
case "+":
val = leftVal + rightVal
case "-":
val = leftVal - rightVal
}
return TransToString(val)
}
func main() {
expr := `1 + 4 - 2 + 100 - 20 + 12 `
//expr := ` 1 + 4 `
ast := getAst(expr)
result := getResult(ast)
fmt.Println(result)
}
func TransToString(data interface{}) (res string) {
val := reflect.ValueOf(data)
return strconv.FormatInt(val.Int(), 10)
}
func TransToInt(data interface{}) (res int, err error) {
return strconv.Atoi(strings.TrimSpace(data.(string)))
}
歡迎加我的個人微信:709834997。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/th5HgpibwZkRlj1EzxmMTw