Go 中空接口的最佳实践?

2023-12-08

我正在学习空接口。我发现虽然在 Stackoverflow 上有很多关于空接口的含义及其工作方式的解释,但关于何时/为何使用它们、何时避免、考虑因素是什么以及如何使用它们的最佳实践信息却很少。选择使用它们的优点和缺点。

在 Go 聊天室中,我读过一些关于最好避免使用空接口的讨论,但没有适当的参数。其他人自豪地回应说,他们的代码设计中空接口为零。

我最感兴趣的是库和框架的使用(旨在被其他人重用/扩展)。

现在我正在阅读带有相关库的框架代码库,其中许多位置都充满了空接口。其中一些让我感到困惑,我想知道是否所有用法都是有道理的。就像框架提供“用户管理”之类的东西AppConfiguration and UserPreferences都是空接口。而在代码的进一步部分(靠近数据库层),用户的电子邮件在技术上被视为用户首选项。接口定义更具体不是更好吗?


在 Go 聊天室中,我读过一些关于最好避免使用空接口的讨论,但没有适当的参数。其他人自豪地回应说,他们的代码设计中空接口为零。

最大的问题是你失去了所有的打字功能;例如,假设我有一个函数,我想对各种类型的数字进行操作,所以我写:

func AddOne(n interface{}) int64 {
    switch nn := n.(type) {
        case int:
            return nn + 1
        case int8:
            return nn + 1
        // ... etc...
    }
}

但是如果我将 0.42 (float64) 传递给这个函数,或者字符串呢?"asd"?如果该函数接受 int64 (func AddOne(n int64) int64)然后我们会收到关于此的警告在编译时,但与interface{}你不会得到任何东西,因为一切都是有效的。

你能做的最好的事情就是在运行时处理这个问题,或者panic()或者返回一个错误;这显然比编译时错误更不清楚。

这是迄今为止最大的缺点。


我得看看那些细节AppConfiguration and UserPreferences特别是函数,但使用空接口有一些充分的理由;例如,当您想要接受某些自定义结构,然后使用反射根据某些外部数据在结构上设置值时。这本质上就是诸如encoding/json这样做,但它也常用于解析一些配置文件等。

这听起来像AppConfiguration and UserPreferences可能适合这一点,因为库/框架不知道您的应用程序配置需要哪些设置,或者有哪些用户首选项。但就像我说的,没有细节很难确定。

另一个用例是当您确实想要接受多种类型时;将参数传递给 SQL 查询是一个常见的示例,或者fmt.Printf().


一般来说,避免interface{}可能是最好的,但如果您发现自己为此竭尽全力,那么最好只使用interface{}并忍受缺乏打字的情况。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Go 中空接口的最佳实践? 的相关文章