Go语言运行时检查变量类型的方法
我有几个像这样声明的 C 函数,
CURLcode curl_wrapper_easy_setopt_long(CURL* curl, CURLoption option, long param);
CURLcode curl_wrapper_easy_setopt_str(CURL* curl, CURLoption option, char* param);
我想将它们公开为像这样的一个 Go 函数
func (e *Easy)SetOption(option Option, param interface{})
,所以我需要能够在运行时检查 param 类型。我该如何做到这一点,这是个好主意吗(如果不是,在这种情况下什么是好的做法)?
I have few C functions declared like this
CURLcode curl_wrapper_easy_setopt_long(CURL* curl, CURLoption option, long param);
CURLcode curl_wrapper_easy_setopt_str(CURL* curl, CURLoption option, char* param);
I would like to expose those as one Go function like this
func (e *Easy)SetOption(option Option, param interface{})
so I need to be able to check param type at runtime. How do I do that and is this good idea (if not what is good practice in this case)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
quux00的答案只讲述了比较基本类型。
如果您需要比较您定义的类型,则不应使用
reflect.TypeOf(xxx)
。相反,请使用reflect.TypeOf(xxx).Kind()。类型有两类:
这是一个完整的示例:
输出将是:
如您所见,reflect。 TypeOf(xxx) 返回您可能想要使用的直接类型,而
reflect.TypeOf(xxx).Kind()
返回基本类型。结论如下。如果需要与基本类型进行比较,请使用reflect.TypeOf(xxx).Kind();如果需要与自定义类型进行比较,请使用reflect.TypeOf(xxx)。
quux00's answer only tells about comparing basic types.
If you need to compare types you defined, you shouldn't use
reflect.TypeOf(xxx)
. Instead, usereflect.TypeOf(xxx).Kind()
.There are two categories of types:
Here is a full example:
The output would be:
As you can see,
reflect.TypeOf(xxx)
returns the direct types which you might want to use, whilereflect.TypeOf(xxx).Kind()
returns the basic types.Here's the conclusion. If you need to compare with basic types, use
reflect.TypeOf(xxx).Kind()
; and if you need to compare with self-defined types, usereflect.TypeOf(xxx)
.还有另一种方法可以断言 @MewX 评论的“直接类型(您直接定义的类型)”类型的变量类型。
它是通过直接在比较中实例化类型来实现的。
deck{}
创建该类型的一个空实例,在本例中是一个空的string
切片,并且比较有效。There's yet another way to assert a variable type of the kind "direct types (the types you defined directly)" as @MewX commented.
It is by instantiating the type directly in the comparison.
The
deck{}
creates an empty instance of the type, in this case, an empty slice ofstring
and the comparison works.有什么问题吗?
等等
What's wrong with
and so on?
Go 似乎有专门用于此目的的特殊形式的 switch(称为 type switch):
It seems that Go have special form of switch dedicate to this (it is called type switch):
@Darius 的答案是最惯用的(而且可能更高效)方法。一个限制是您要检查的类型必须是
interface{}
类型。如果您使用具体类型,它将失败。在运行时确定某些内容的类型(包括具体类型)的另一种方法是使用 Go
reflect
包。将TypeOf(x).Kind()
链接在一起,您可以获得reflect.Kind
值,该值是uint
类型:http://golang.org/pkg/reflect/#Kind然后,您可以检查 switch 块之外的类型,如下所示:
打印出:
再次,这个可能不是首选的方法,但了解其他选择是很有好处的。
The answer by @Darius is the most idiomatic (and probably more performant) method. One limitation is that the type you are checking has to be of type
interface{}
. If you use a concrete type it will fail.An alternative way to determine the type of something at run-time, including concrete types, is to use the Go
reflect
package. ChainingTypeOf(x).Kind()
together you can get areflect.Kind
value which is auint
type: http://golang.org/pkg/reflect/#KindYou can then do checks for types outside of a switch block, like so:
Which prints outs:
Again, this is probably not the preferred way to do it, but it's good to know alternative options.
请参阅此处的类型断言:
http://golang.org/ref/spec#Type_assertions
我会仅断言合理的类型(字符串、uint64)等,并使其尽可能宽松,最后执行到本机类型的转换。
See type assertions here:
http://golang.org/ref/spec#Type_assertions
I'd assert a sensible type (string, uint64) etc only and keep it as loose as possible, performing a conversion to the native type last.