Golang 中的动态铸造

Dynamic casting in Golang

所以...我正在为我使用 Gin 框架的想法创建一个 RESTful API,我遇到了以下问题 - 假设我有以下端点:

/a/:id/*action /b/:id/*action /c/:id/*action 因此,很明显,当我不执行任何操作时,我想 return 给定 ID 的数据。意思是,我除了查询一些数据并对其进行 returning 之外什么也没做,这意味着功能基本相同,只有 returned 数据不同。

这是我的示例代码 -

   func GetBusiness(c *gin.Context) {                                                                                                                                                                                     
       businessID, err := strconv.Atoi(c.Param("id"))                                                                                                                                                                                  
       if businessID == 0 || err != nil {                                                                                                                                                                                               
           c.JSON(http.StatusBadRequest, gin.H{"success": false, "errorMessage": "Missing ID"})                                                                                                                                         
       }                                                                                                                                                                                                                                 
       business := &Business{}                                                                                                                                                                                                           
       business, err = business.Get(businessID)                                                                                                                                                                                         
       if err != nil {                                                                                                                                                                                                                  
           c.JSON(http.StatusBadRequest, gin.H{"success": false, "errorMessage": "Business not found"})                                                                                                                                
       }                                                                                                                                                                                                                                
      c.JSON(http.StatusOK, business)                                                                                                                                                                                                   
   }   

所以,显然,企业可以成为用户或其他任何东西。所以,在这个长篇大论之后,我想问你们的问题是,在这种情况下我该如何防止代码重复?我已经尝试过使用接口,但我仍然在为 Go 的 OO 性质而苦苦挣扎,所以我真的很感激任何帮助。

提前致谢!

您可以采取一些措施来减少代码重复,但不幸的是,您总是会在 go 中编写一些样板文件,因为它是明确的错误处理并且缺乏面向对象的特性。 (这不一定是坏事!)。

所以我目前唯一的建议是将通用功能放在中间件处理程序中并稍微重组您的代码,例如:

parseIdMiddleware := func(c *gin.Context) {
  id, err := strconv.Atoi(c.Param("id"))
  if businessID == 0 || err != nil {
    c.AbortWithError(http.StatusBadRequest, errors.New("Missing ID"))
    return
  }
  c.Set("id", id)
}
...
gin.Use(gin.ErrorLogger(), parseIdMiddleware)

并将您的处理程序重写为

func GetBusiness(c *gin.Context) {
  id := c.MustGet("id").(int)
  business, err := store.GetBusiness(id)
  if err != nil {
    c.AbortWithError(http.StatusBadRequest, err)
    return // don't forget this!
  }
  c.JSON(http.StatusOK, business)
}

和往常一样,阅读别人的代码!我推荐https://github.com/drone/drone。这应该可以让您很好地了解如何构建代码。