美文网首页
golang iris使用go:linkname添加自定义for

golang iris使用go:linkname添加自定义for

作者: darcyaf | 来源:发表于2020-03-26 13:59 被阅读0次

    在使用iris的时候
    我们有这么一个结构体

    type BannersCreateOrUpdate struct {
        Id            int               `json:"id" validate:"numeric"`
        Title         string            `json:"title" validate:"required"`
        StartTime     time.Time `json:"start_time" form:"start_time"`
    }
    

    我们有一个start_time的字段,如果前端希望传入2019-08-01 11:11:11时,如果使用c.Ctx.ReadForm(&p)的方式来获取,则获取不到正确的时间,报错如下schema: error converting value for "start_time". Details: parsing time "2019-08-01 11:11:11" as "2006-01-02T15:04:05Z07:00": cannot parse " 11:11:11" as "T"
    所以这里就会涉及到自定义解析器,类似json的做法.

    查看iris的源码,这里使用一个map来存储类型和Converter的map,解析时就通过这个来查找并调用对应的转换器,也提供了一个注册方法来添加转换器,不过由于被封装了formDecoder = NewDecoder(),小写的变量没法直接访问。

    type Converter func(string) reflect.Value
    
    // RegisterConverter registers a converter function for a custom type.
    func (d *Decoder) RegisterConverter(value interface{}, converterFunc Converter) {
        d.cache.registerConverter(value, converterFunc)
    }
    

    刚好可以直接go:linkname,强行获取formDecoder,从而添加注册器。

    • 需要引入_ "unsafe"
    • 添加注释,将schema下的formDecoder链接到这里.
      //go:linkname formDecoder github.com/iris-contrib/schema.formDecoder
    • StartTime的类型换成自定义的NormalTime类型
      实现源码:
    package common
    
    import (
        "github.com/iris-contrib/schema"
        _ "github.com/iris-contrib/schema"
        "reflect"
        "time"
        _ "unsafe"
    )
    
    //go:linkname formDecoder github.com/iris-contrib/schema.formDecoder
    //go:nosplit
    var formDecoder *schema.Decoder
    
    type NormalTime time.Time
    
    func (n NormalTime) Converter(s string) reflect.Value {
        if t, err := time.Parse("2006-01-02 15:04:05", s); err == nil {
            return reflect.ValueOf(NormalTime(t))
        }
        return reflect.Value{}
    }
    func RegisterNormalTimeDecoder() {
        var nt = NormalTime{}
        formDecoder.RegisterConverter(nt, nt.Converter)
    }
    

    最后在main.go中或者合适的地方调用RegisterNormalTimeDecoder()即可

    相关文章

      网友评论

          本文标题:golang iris使用go:linkname添加自定义for

          本文链接:https://www.haomeiwen.com/subject/mrzquhtx.html