Go:接口实现验证的艺术,深入理解 `var _ Interface = ( Struct)(nil)` 用法_var _ interface = ()(nil)(3)

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

使用 var _ Interface = (*Struct)(nil) 的技巧

这种技巧的核心是Go语言的类型转换规则和编译时的类型检查。通过声明一个未使用的全局变量,我们可以在编译期间强制进行类型检查,从而确保我们的类型确实实现了指定的接口。这里的 _ 是一个特殊的标识符,表示这个变量我们不会在代码中直接使用,而 (*Struct)(nil) 则是一个指向结构体类型 Structnil 指针。
在这里插入图片描述

深入解析 var _ Interface = (*Struct)(nil)

这个表达式包含几个部分,每个部分都有其特定的意义:

  • var _ 声明了一个变量,但使用 _ 表示我们不会在代码中使用这个变量。
  • Interface 指明了我们期望的接口类型。
  • = (*Struct)(nil) 创建了一个 nil 指针,这个指针的类型是指向我们希望验证的结构体 Struct 的指针,并且这个表达式将 nil 指针转换为了 Interface 类型。

通过这个声明,如果 Struct 没有实现 Interface 的所有方法,Go编译器会在编译时抛出错误。这种方式不需要运行任何额外的测试代码,也不会引入运行时开销,它仅仅是利用了Go语言的类型系统来确保类型安全。

实践中的应用

这种技巧尤其适合大型项目和库的开发,在这些项目中,接口广泛使用,且经常需要确保新的类型正确实现了特定的接口。通过在代码库中广泛应用这种模式,可以显著提高代码的健壮性和可维护性。

结论

var _ Interface = (*Struct)(nil) 这种用法虽然简单,但它体现了Go语言设计的深思熟虑和对开发者友好的考虑。通过充分利用这一技巧,我们可以在编译时就确保类型的正确性,减少运行时的错误。在软件开发的艺术中,这种精确的工艺和对细节的关注是构建高质量软件产品不可或缺的。
让我们用这种技巧继续编织Go语言的艺术,构建更加健壮、可靠的软件系统。

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

  • 14
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
改进代码func TracingList(ctx *gin.Context) { resp := models.Response{ Code: 0, Msg: "success", } t, _ := strconv.Atoi(ctx.Query("t")) label, _ := strconv.Atoi(ctx.Query("label")) page, _ := strconv.Atoi(ctx.DefaultQuery("page", "1")) pageSize, _ := strconv.Atoi(ctx.DefaultQuery("pageSize", "10")) code := ctx.Query("code") //设施类型 if len(code) == 0 { resp.Code = 400 resp.Msg = "请输入code值" ctx.JSON(400, resp) return } type Total struct { gorm.Model Type int16 Source int16 Explanation string Label int16 FacilityID string } db := common.DB.Session(&gorm.Session{}) if t < 0 || t > 5 { var req interface{} switch t { case 0: req = []*Total{} case 1: req = []*models.Flaw{} case 2: req = []*models.Issue{} case 3: req = []*models.Record{} case 4: req = []*models.Quality{} case 5: req = []*models.Inspection{} } //查询并分页 if t < 1 || t > 5 { res := db.Scopes(models.Paginate(page, pageSize)).Where("facility_id=?", code).Find(&req) if res.RowsAffected == 0 { resp.Code = 400 resp.Msg = "记录不存在" ctx.JSON(400, resp) return } } else { res := db.Scopes(models.Paginate(page, pageSize)).Raw("SELECT * FROM flaws WHERE facility_id = ? "+ "UNION SELECT * FROM issues WHERE facility_id = ? "+ "UNION SELECT * FROM records WHERE facility_id = ? "+ "UNION SELECT * FROM qualities WHERE facility_id = ? "+ "UNION SELECT * FROM inspections WHERE facility_id = ?", "code", "code", "code", "code", "code").Find(&req) if res.RowsAffected == 0 { resp.Code = 400 resp.Msg = "记录不存在" ctx.JSON(400, resp) return } } resp.Data = req ctx.JSON(200, resp) } else if label < 1 || label > 4 { var req []*Total res := db.Scopes(models.Paginate(page, pageSize)).Raw("SELECT * FROM flaws WHERE label = ? "+ "UNION SELECT * FROM issues WHERE label = ? "+ "UNION SELECT * FROM records WHERE label = ? "+ "UNION SELECT * FROM qualities WHERE label = ? "+ "UNION SELECT * FROM inspections WHERE label = ?", "label", "label", "label", "label", "label").Find(&req) if res.RowsAffected == 0 { resp.Code = 400 resp.Msg = "记录不存在" ctx.JSON(400, resp) return } resp.Data = req ctx.JSON(200, resp) } else { ctx.JSON(400, models.Response{ Code: 400, Msg: "参数有误", }) return } }
05-26
以下是改进的代码: ```go func TracingList(ctx *gin.Context) { resp := models.Response{ Code: 0, Msg: "success", } code := ctx.Query("code") if len(code) == 0 { resp.Code = 400 resp.Msg = "请输入code值" ctx.JSON(400, resp) return } t, err := strconv.Atoi(ctx.Query("t")) if err != nil || t < 0 || t > 5 { resp.Code = 400 resp.Msg = "无效的参数t" ctx.JSON(400, resp) return } label, err := strconv.Atoi(ctx.Query("label")) if err != nil || label < 1 || label > 4 { resp.Code = 400 resp.Msg = "无效的参数label" ctx.JSON(400, resp) return } page, err := strconv.Atoi(ctx.DefaultQuery("page", "1")) if err != nil || page < 1 { resp.Code = 400 resp.Msg = "无效的参数page" ctx.JSON(400, resp) return } pageSize, err := strconv.Atoi(ctx.DefaultQuery("pageSize", "10")) if err != nil || pageSize < 1 { resp.Code = 400 resp.Msg = "无效的参数pageSize" ctx.JSON(400, resp) return } var req interface{} switch t { case 0: req = []*Total{} case 1: req = []*models.Flaw{} case 2: req = []*models.Issue{} case 3: req = []*models.Record{} case 4: req = []*models.Quality{} case 5: req = []*models.Inspection{} } db := common.DB.Session(&gorm.Session{}) res := db.Scopes(models.Paginate(page, pageSize)).Where("facility_id=?", code) if t >= 1 && t <= 5 { res = res.Table("flaws").Where("facility_id=?", code). Or("facility_id=?", code). Or("facility_id=?", code). Or("facility_id=?", code). Or("facility_id=?", code) } res.Find(req) if res.RowsAffected == 0 { resp.Code = 400 resp.Msg = "记录不存在" ctx.JSON(400, resp) return } resp.Data = req ctx.JSON(200, resp) } ``` 主要改进包括: 1. 对输入的参数进行了有效性检查,如 t、label、page 和 pageSize 都需要为正整数,code 不能为空。 2. 使用了 Go 语言内置的错误处理机制,当参数无效时,返回错误信息。 3. 将 SQL 查询语句拆分为两段,根据 t 的值判断使用哪一段,避免了使用 Raw() 方法的安全隐患。 4. 代码结构更加清晰,易于阅读和维护。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值