Go中空接口的最佳做法? [英] Best practices for empty interfaces in Go?

查看:71
本文介绍了Go中空接口的最佳做法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习有关空接口的信息.我发现尽管有很多解释(关于Stackoverflow),也有关于空接口的含义以及它们如何工作的解释,但是关于何时/为什么使用它们,何时避免使用,注意事项是什么以及什么的最佳实践的信息很少.选择使用它们的利弊.

I am learning about empty interfaces. I find that while there are many explanations—also on Stackoverflow—on meaning of an empty interface and how they work, there's very little information on best-practices on when / why to use them, when to avoid, what the considerations are, and the pros and cons of chosing to use them.

在Go聊天室中,我阅读了一些有关如何避免使用空接口(最好没有适当参数)的最佳讨论.其他人自豪地回答他们在代码设计中有零个空接口.

In Go chatrooms I've read some talk about best to avoid using empty interfaces where possible, but without the proper arguments. Others proudly responding they had zero empty interfaces in their code design.

我对使用库和框架(打算被其他人重用/扩展)最感兴趣.

I am most interested in use for libraries and frameworks (intended to be reused / extended by others).

现在,我正在阅读带有相关库的框架代码库,该库在许多地方都充满了emtpy接口.其中一些使我感到困惑,我想知道是否所有使用都应得到保证.就像框架提供用户管理"一样, AppConfiguration UserPreferences 之类的东西都是空接口.在代码中(靠近db层)更进一步的情况下,技术上将用户的电子邮件视为用户首选项.在接口定义中更具体会更好吗?

Right now I am reading a framework codebase with related libraries, that is full of emtpy interfaces in many locations. Some of this confuses me, and I wonder if all usages are warranted. Like the framework offers 'user management' and things like AppConfiguration and UserPreferences are empty interfaces. This while further on in the code (near the db layer) the user's email is technically treated as a user preference. Wouldn't it be better to be more specific in the interface definition?

推荐答案

在Go聊天室中,我阅读了一些有关如何避免使用空接口(最好没有适当参数)的最佳讨论.其他人自豪地回答他们在代码设计中有零个空接口.

In Go chatrooms I've read some talk about best to avoid using empty interfaces where possible, but without the proper arguments. Others proudly responding they had zero empty interfaces in their code design.

最大的问题是您丢失了所有键入内容;例如,假设我有一个要对各种类型的数字进行运算的函数,因此我写:

The biggest problem is that you lose all typing; for example let's say I have a function that I want to operate on various types of numbers, so I write:

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 {}因为一切都是有效的,您什么也不会得到.

But what if I pass 0.42 (float64) to this function, or the string "asd"? If the function would accept an int64 (func AddOne(n int64) int64) then we would get a warning about this at compile time, but with interface{} you won't get anything since everything is valid.

您能做的最好的事情就是在运行时处理该问题,并要么panic()要么返回一个错误.显然,它比编译时错误要清晰得多.

The best you can do is handle this at run-time and either panic() or return an error; which is obviously a lot less clear than a compile-time error.

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

This is by far the biggest downside.

我必须特别查看那些 AppConfiguration UserPreferences 函数的详细信息,但是使用空接口有一些很好的理由;例如,当您要接受一些自定义结构,然后使用反射基于某些外部数据在该结构上设置值时.本质上,这是诸如 encoding/json 之类的程序包所做的事情,但是它也通常用于解析某些配置文件,等等.

I'd have to see the details of those AppConfiguration and UserPreferences functions in particular, but there are some good reasons for using empty interfaces; for example when you want to accept some custom struct and then use reflection to set values on the struct based on some external data. This is essentially what packages such as encoding/json do, but it's also commonly used for parsing some config files, and so forth.

听起来像 AppConfiguration UserPreferences 可能适合此设置,因为库/框架不知道您的应用程序配置需要哪些设置,或那里的用户偏好设置是.但是就像我说的那样,很难确定没有细节.

It sounds like AppConfiguration and UserPreferences may fit this, because the library/framework doesn't know what settings you need for your app's configuration, or what user preferences there are. But like I said, it's hard to be sure without details.

另一个用例是当您真的想接受各种各样的类型时;将参数传递给SQL查询是一个常见的示例,即 fmt.Printf().

Another use case is when you really want to accept a wide variety of types; passing parameters to SQL queries is a common example, or fmt.Printf().

通常,最好避免使用 interface {} ,但是如果您发现这样做会弯腰,那么最好使用 interface {} 和没有打字就住了.

In general, avoiding interface{} is probably best, but if you find yourself bending over backwards for doing so then it's probably best to just use interface{} and live with the lack of typing.

这篇关于Go中空接口的最佳做法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆