go 设计模式 解释器模式
package main
import (
"fmt"
"regexp"
"strconv"
)
type Address struct {
City string
}
type User struct {
Id int
Name string
Age int
}
func main() {
var users = []*User{
{Id: 102, Name: "shenyi", Age: 20},
{Id: 103, Name: "shenyi", Age: 19},
}
fmt.Println("%v", NewUserFilter("age > 19").Filter(users))
}
type UserFilter struct {
Expr IExpr
}
type IExpr interface {
Interpret(*User) bool
}
type AgeExpr struct {
operator string
value int
}
func (this *AgeExpr) Interpret(user *User) bool {
switch this.operator {
case ">":
return user.Age > this.value
case "<":
return user.Age < this.value
case ">=":
return user.Age >= this.value
case "<=":
return user.Age <= this.value
default:
return user.Age == this.value
}
}
func (this *UserFilter) Filter(users []*User) []*User {
ret := make([]*User, 0)
for _, user := range users {
if this.Expr.Interpret(user) {
ret = append(ret, user)
}
}
return users
}
func NewUserFilter(rule string) *UserFilter {
list := regexp.MustCompile("\\s+").Split(rule, -1)
if len(list) != 3 {
panic("error rule")
}
if list[0] == "age" {
operator := list[1]
value, err := strconv.Atoi(list[2])
if err != nil {
panic("error rule value")
}
return &UserFilter{
Expr: &AgeExpr{operator: operator, value: value},
}
}
panic("found no expr")
}