• 如何优雅地处理泛型问题 at 2020年04月21日

    大致如下,一些边缘 case 检查(obj 不是指针)这边忽略了

    func parse(ss string, obj interface{}) {
        var (
            v = reflect.ValueOf(obj).Elem()
            f = v.FieldByName("Age")
        )
    
        if f.CanSet() {
            f.SetString(ss)
        }
    }
    

    一种是比较传统的办法,用接口挡一下。但是字段太多的时候会很蠢……

    type nameSetable interface{ SetName(string) }
    type ageSetable interface{ SetAge(string) }
    type gradeSetable interface{ SetGrade(string) }
    
    type student struct {
        Name  string `xlsxCol:"student name"`
        Age   string `xlsxCol:"student age"`
        Grade string `xlsxCol:"student grate"`
    }
    
    var _ nameSetable = &student{}
    var _ ageSetable = &student{}
    var _ gradeSetable = &student{}
    
    func (s *student) SetName(ss string)  { s.Name = ss }
    func (s *student) SetAge(ss string)   { s.Age = ss }
    func (s *student) SetGrade(ss string) { s.Grade = ss }
    
    type teacher struct {
        Name string `xlsxCol:"teacher name"`
        Age  string `xlsxCol:"teacher age"`
    }
    
    var _ nameSetable = &teacher{}
    var _ ageSetable = &teacher{}
    
    func (s *teacher) SetName(ss string) { s.Name = ss }
    func (s *teacher) SetAge(ss string)  { s.Age = ss }
    
    func parse(ss string, obj interface{}) {
        if s, ok := obj.(nameSetable); ok {
            s.SetName(ss)
        }
    
        if s, ok := obj.(ageSetable); ok {
            s.SetAge(ss)
        }
    
        if s, ok := obj.(gradeSetable); ok {
            s.SetGrade(ss)
        }
    }
    

    🤮