dongyin8991 2018-02-13 14:42
浏览 53
已采纳

排序具有公共字段的不同结构的最佳解决方案

I have struct types like

type A struct {
    Name string
    CreatedAt time.Time
    ...
}

type B struct {
    Title string
    CreatedAt time.Time
    ...
}

type C struct {
    Message string
    CreatedAt time.Time
    ...
} 

And a generic slice

var result []interface{}

containing A, B and C elements (and more to come in the future)

I want to sort that slice by 'CreatedAt'.

What is the best solution ? I want to avoid checking types or casting...

  • 写回答

1条回答 默认 最新

  • dongpian6319 2018-02-13 15:04
    关注

    The only way that you can have a slice containing both of these types anyway is that the slice contains some interface that is implemented by both types (including interface{}).

    You will probably want to use the sort package and implement sort.Interface on your slice. The solution gets a little verbose, but makes good sense:

    type Creation interface {
        GetCreated() time.Time
    }
    
    type A struct {
        Name      string
        CreatedAt time.Time
    }
    
    func (a *A) GetCreated() time.Time {
        return a.CreatedAt
    }
    
    func (a *A) String() string {
        return a.Name
    }
    
    type B struct {
        Title     string
        CreatedAt time.Time
    }
    
    func (b *B) GetCreated() time.Time {
        return b.CreatedAt
    }
    
    func (b *B) String() string {
        return b.Title
    }
    
    type AorB []Creation
    
    func (x AorB) Len() int {
        return len(x)
    }
    
    func (x AorB) Less(i, j int) bool {
        // to change the sort order, use After instead of Before
        return x[i].GetCreated().Before(x[j].GetCreated())
    }
    
    func (x AorB) Swap(i, j int) {
        x[i], x[j] = x[j], x[i]
    }
    
    func main() {
        a := &A{"A", time.Now()}
        time.Sleep(1 * time.Second)
        b := &B{"B", time.Now()}
        aOrB := AorB{b, a}
    
        fmt.Println(aOrB)
        // [B A]
    
        sort.Stable(aOrB)
    
        fmt.Println(aOrB)
        // [A B]
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?