如何组合仅在参数类型上不同的两个函数

时间:2018-08-20 22:06:57

标签: go dry

所以我有这个看起来像这样的golang函数:

func addDaysListener(ch <-chan []entity.Day, db *sql.DB) {
    for days := range ch {
        if len(days) == 0 {
            continue
        }

        logger := logrus.WithFields(logrus.Fields{
            "ticker": days[0].Ticker(),
            "count":  len(days),
        })
        if err := update.InsertDays(db, days); err != nil {
            logger.Error(err)
        } else {
            logger.Info("Inserted Days")
        }
    }
}

我还有一个名为addMinutesListener()的函数,除了以下功能相同:

  • 它监听<-chan []entity.Minute
  • 它调用update.InsertMinutes()

entity.Dayentity.Minute都实现datum.Candle,尽管更新功能需要特定的类型。我想写这样的东西:

func addItemsListener(db *sql.DB, ch <-chan []datum.Candle, insertFunc func(*sql.DB, []datum.Candle) error) {
    for items := range ch {
        if len(items) == 0 {
            continue
        }

        logger := logrus.WithFields(logrus.Fields{
            "ticker": items[0].Ticker(),
            "count":  len(items),
        })
        if err := insertFunc(db, items); err != nil {
            logger.Error(err)
        } else {
            logger.Info("Inserted Days")
        }
    }
}

...除了update.InsertDaysupdate.InsertMinutes的函数签名都需要特定的类型,而不是泛型的类型之外,通道也是如此设置的。我可能会更改通道,但实际上并不能更改插入函数,因为它们确实需要正确的类型,因为它们将数据插入数据库,并且两者之间的字段(属性)差别很大。

我觉得对这个问题的正确答案可能更加险恶,这就是为什么我要问你,

对不起的标题,我感到抱歉;如果您有更好的主意,请随时发表评论。

1 个答案:

答案 0 :(得分:1)

使用类型assertions

func addDaysListener(ch <-chan []datum.Candle , db *sql.DB) {
    for days := range ch {
        if len(days) == 0 {
            continue
        }

        logger := logrus.WithFields(logrus.Fields{
           "ticker": days[0].Ticker(),
           "count":  len(days),
       })

     switch v:=days.(type){
       case  []entity.Day:
            if err := update.InsertDays(db,v); err != nil {
               logger.Error(err)
            } else {
               logger.Info("Inserted Days")
            }
       case  []entity.Minute:
            if err := update.InsertMinutes(db, v); err != nil {
               logger.Error(err)
            } else {
               logger.Info("Inserted Minutes")
            }

      }

   }
  }