@Controller
    o := odserver.Default()
    o.Start("/main").
    Target("/test/").Get(HelloServer).Post(HelloServer).Delete(HelloServer).And().
        Target("/test2").Get(HelloServer2)
    o.Start("/{test}/main/").Target("/number/{number}").
        Get(HelloServer3).Post(HelloServer4)

    http.ListenAndServe(":8080",o)
func HelloServer3(c *odserver.Context) {

    fmt.Fprint(c.Rw, c.Params)
}
\w*/{test}/main/number/{number}/\w*/main/number/\w*
o.Start("/main").
Target("/test/").Get(HelloServer).Post(HelloServer).Delete(HelloServer).And().
Target("/test2").Get(HelloServer2)
HandlerObject
type FuncObject struct {
    params []string
//对应编写的接口,IHandlerFunc只是个空接口
    f      IHandlerFunc
    exist  bool
    *httpConfig
}
//方法函数映射,0代表GET方法下的接口
type methodFuncs []FuncObject
/**
    关键struct,代表每个实体的请求
 */
type HandlerObject struct {
    *Router
    //对应占位符的参数
    params    []string
    //对该请求的http配置
    *httpConfig
    //请求路径 即start+target的路径
    path        string
    startPath   string
//方法函数映射
    methodFuncs methodFuncs
}
HandlerObjectRouterRoutermap[string]*HandlerObject
func NewRouter() *Router {
    return &Router{
        handler:   make(map[string]*HandlerObject),
        regexpMap: make(map[*regexp.Regexp]*HandlerObject),
    }
}

type Router struct {
    handler
    regexpMap
}
regexpMap
func (r *Router) doUrlMapping(url string, method int) (*HandlerObject,bool) {
    ch := make(chan *HandlerObject)
    //精准匹配
    go func() {
        if ho, ok := r.handler[url]; ok {
            ch <- ho
        }
    }()
    //正则匹配
    go func() {
        for k, v := range r.regexpMap {
            if k.MatchString(url) {
                pathArray := strings.Split(url, "/")[1:]
                regexpArray := strings.Split(k.String(), "/")[1:]
                if len(pathArray) == len(regexpArray) {
                  //设置参数
                    paramsNum := 0
                    for i := 0; i < len(pathArray); i++ {
                        if matcher.IsPattern(regexpArray[i]) {
                            v.params[paramsNum] = pathArray[i]
                            paramsNum++
                        }
                    }
                    v.params = v.params[:paramsNum]
                }
                ch <- v
            }
        }
    }()
    select {
    case ho := <-ch:
        {
            return ho,true
        }
    case <-time.After(2e6):
        {
            return &HandlerObject{},false
        }
    }
}

注册接口的代码如下

func (r *Router) Start(url string) *HandlerObject {
    return NewHandlerObject(r, AddSlash(url))
}

func (ho *HandlerObject) And() *HandlerObject {
    if ho.Router == nil || ho.startPath == "" {
        panic("ho.Router is nil or startPath is unknown,maybe u should use Start()")
    }
    return NewHandlerObject(ho.Router, ho.startPath)
}

func (ho *HandlerObject) Target(url string) *HandlerObject {
    //设置完整的路径
    if ho.startPath == "/" {
        ho.path = ho.startPath + DeleteSlash(url)
    } else {
        if strings.HasSuffix(ho.startPath, "/") {
            url = DeleteSlash(url)
        } else {
            url = AddSlash(url)
        }
        ho.path = ho.startPath + url
    }
    //尝试将url转换成正则表达式,如果没有占位符,则转换不成功
    pattern, ok := matcher.ToPattern(ho.path)
    if ok {
        ho.path = pattern
        re, err := regexp.Compile(pattern)
        if err != nil {
            panic("error compile pattern:" + pattern)
        }
        ho.Router.regexpMap[re] = ho
    } else {
        ho.handler[ho.path] = ho
    }
    return ho
}
func AddSlash(s string) string {
    if !strings.HasPrefix(s, "/") {
        s = "/" + s
    }
    return s
}

func DeleteSlash(s string) string {
    if strings.HasPrefix(s, "/") {
        array := strings.SplitN(s, "/", 2)
        s = array[1]
    }
    return s
}

func (ho *HandlerObject) Get(f IHandlerFunc) *HandlerObject {
    if ho.methodFuncs[GET].exist {
        panic("GetFunc has existed")
    }

    ho.methodFuncs[GET] = NewFuncObject(f)
    return ho
}
ContextRequestresponseWriterRequestresponseWriter
type Context struct {
    Req    Request
    Rw     responseWriter
    //对应restful的参数值
    Params []string
}

    源码路径:https://gitee.com/1995zzf/go-oneday
    路漫漫其修远兮,客官点个赞呗