英文:
How to determine an interface{} value's "real" type?
问题
我还没有找到一个好的使用interface{}
类型的资源。例如
package main
import "fmt"
func weirdFunc(i int) interface{} {
if i == 0 {
return "zero"
}
return i
}
func main() {
var i = 5
var w = weirdFunc(5)
// 这个例子可以工作!
if tmp, ok := w.(int); ok {
i += tmp
}
fmt.Println("i =", i)
}
你知道有关使用Go的interface{}
的好介绍吗?
具体问题:
- 如何获取w的“真实”类型?
- 有没有办法获取类型的字符串表示?
- 有没有办法使用类型的字符串表示来转换一个值?
英文:
I have not found a good resource for using interface{}
types. For example
package main
import "fmt"
func weirdFunc(i int) interface{} {
if i == 0 {
return "zero"
}
return i
}
func main() {
var i = 5
var w = weirdFunc(5)
// this example works!
if tmp, ok := w.(int); ok {
i += tmp
}
fmt.Println("i =", i)
}
Do you know of a good introduction to using Go's interface{}
?
specific questions:
- how do I get the "real" Type of w?
- is there any way to get the string representation of a type?
- is there any way to use the string representation of a type to
convert a value?
答案1
得分: 166
你也可以使用类型开关:
switch v := myInterface.(type) {
case int:
// v 在这里是一个整数,所以可以进行 v + 1 等操作。
fmt.Printf("整数: %v", v)
case float64:
// v 在这里是一个浮点数,所以可以进行 v + 1.0 等操作。
fmt.Printf("浮点数: %v", v)
case string:
// v 在这里是一个字符串,所以可以进行 v + " Yeah!" 等操作。
fmt.Printf("字符串: %v", v)
default:
// 在这里我感觉很笨。 ;)
fmt.Printf("我不知道,去问 stackoverflow 吧。")
}
英文:
You also can do type switches:
switch v := myInterface.(type) {
case int:
// v is an int here, so e.g. v + 1 is possible.
fmt.Printf("Integer: %v", v)
case float64:
// v is a float64 here, so e.g. v + 1.0 is possible.
fmt.Printf("Float64: %v", v)
case string:
// v is a string here, so e.g. v + " Yeah!" is possible.
fmt.Printf("String: %v", v)
default:
// And here I'm feeling dumb. ;)
fmt.Printf("I don't know, ask stackoverflow.")
}
答案2
得分: 120
你的示例确实有效。这是一个简化版本。
package main
import "fmt"
func weird(i int) interface{} {
if i < 0 {
return "negative"
}
return i
}
func main() {
var i = 42
if w, ok := weird(7).(int); ok {
i += w
}
if w, ok := weird(-100).(int); ok {
i += w
}
fmt.Println("i =", i)
}
输出:
i = 49
它使用了类型断言。
英文:
Your example does work. Here's a simplified version.
package main
import "fmt"
func weird(i int) interface{} {
if i < 0 {
return "negative"
}
return i
}
func main() {
var i = 42
if w, ok := weird(7).(int); ok {
i += w
}
if w, ok := weird(-100).(int); ok {
i += w
}
fmt.Println("i =", i)
}
Output:
i = 49
It uses Type assertions.
答案3
得分: 65
你可以使用反射(reflect.TypeOf()
)来获取某个东西的类型,而它所返回的值(Type
)有一个字符串表示形式(String
方法),你可以打印出来。
英文:
You can use reflection (reflect.TypeOf()
) to get the type of something, and the value it gives (Type
) has a string representation (String
method) that you can print.
答案4
得分: 18
这是一个使用switch和反射解码通用映射的示例,所以如果不匹配类型,使用反射来找出类型,然后在下次添加类型。
var data map[string]interface {}
...
for k, v := range data {
fmt.Printf("pair:%s\t%s\n", k, v)
switch t := v.(type) {
case int:
fmt.Printf("Integer: %v\n", t)
case float64:
fmt.Printf("Float64: %v\n", t)
case string:
fmt.Printf("String: %v\n", t)
case bool:
fmt.Printf("Bool: %v\n", t)
case []interface {}:
for i,n := range t {
fmt.Printf("Item: %v= %v\n", i, n)
}
default:
var r = reflect.TypeOf(t)
fmt.Printf("Other:%v\n", r)
}
}
英文:
Here is an example of decoding a generic map using both switch and reflection, so if you don't match the type, use reflection to figure it out and then add the type in next time.
var data map[string]interface {}
...
for k, v := range data {
fmt.Printf("pair:%s\t%s\n", k, v)
switch t := v.(type) {
case int:
fmt.Printf("Integer: %v\n", t)
case float64:
fmt.Printf("Float64: %v\n", t)
case string:
fmt.Printf("String: %v\n", t)
case bool:
fmt.Printf("Bool: %v\n", t)
case []interface {}:
for i,n := range t {
fmt.Printf("Item: %v= %v\n", i, n)
}
default:
var r = reflect.TypeOf(t)
fmt.Printf("Other:%v\n", r)
}
}
答案5
得分: 9
有多种方法可以获得类型的字符串表示。开关语句也可以用于用户定义的类型:
var user interface{}
user = User{name: "Eugene"}
// .(type) 只能在开关语句内部使用
switch v := user.(type) {
case int:
// 内置类型也可以(int、float64、string等)
fmt.Printf("整数: %v", v)
case User:
// 用户定义的类型也可以
fmt.Printf("这是一个用户:%s\n", user.(User).name)
}
// 你可以使用反射来获取 *reflect.rtype
userType := reflect.TypeOf(user)
fmt.Printf("%+v\n", userType)
// 你也可以使用 %T 来获取字符串值
fmt.Printf("%T", user)
// 甚至可以将其转换为字符串
userTypeAsString := fmt.Sprintf("%T", user)
if userTypeAsString == "main.User" {
fmt.Printf("\n这绝对是一个用户")
}
Playground链接:https://play.golang.org/p/VDeNDUd9uK6
英文:
There are multiple ways to get a string representation of a type. Switches can also be used with user types:
var user interface{}
user = User{name: "Eugene"}
// .(type) can only be used inside a switch
switch v := user.(type) {
case int:
// Built-in types are possible (int, float64, string, etc.)
fmt.Printf("Integer: %v", v)
case User:
// User defined types work as well
fmt.Printf("It's a user: %s\n", user.(User).name)
}
// You can use reflection to get *reflect.rtype
userType := reflect.TypeOf(user)
fmt.Printf("%+v\n", userType)
// You can also use %T to get a string value
fmt.Printf("%T", user)
// You can even get it into a string
userTypeAsString := fmt.Sprintf("%T", user)
if userTypeAsString == "main.User" {
fmt.Printf("\nIt's definitely a user")
}
Link to a playground: https://play.golang.org/p/VDeNDUd9uK6
答案6
得分: 8
类型切换也可以与反射一起使用:
var str = "hello!"
var obj = reflect.ValueOf(&str)
switch obj.Elem().Interface().(type) {
case string:
log.Println("obj包含一个指向字符串的指针")
default:
log.Println("obj包含其他内容")
}
英文:
Type switches can also be used with reflection stuff:
var str = "hello!"
var obj = reflect.ValueOf(&str)
switch obj.Elem().Interface().(type) {
case string:
log.Println("obj contains a pointer to a string")
default:
log.Println("obj contains something else")
}
答案7
得分: 3
我将提供一种方法,根据传递给本地类型接收器的反射类型参数来返回一个布尔值(因为我找不到类似的东西)。
首先,我们声明一个匿名类型 reflect.Value:
type AnonymousType reflect.Value
然后,我们为我们的本地类型 AnonymousType 添加一个构建器,该构建器可以接受任何潜在类型(作为接口):
func ToAnonymousType(obj interface{}) AnonymousType {
return AnonymousType(reflect.ValueOf(obj))
}
然后,我们为我们的 AnonymousType 结构添加一个针对 reflect.Kind 进行断言的函数:
func (a AnonymousType) IsA(typeToAssert reflect.Kind) bool {
return typeToAssert == reflect.Value(a).Kind()
}
这样我们就可以调用以下代码:
var f float64 = 3.4
anon := ToAnonymousType(f)
if anon.IsA(reflect.String) {
fmt.Println("Its A String!")
} else if anon.IsA(reflect.Float32) {
fmt.Println("Its A Float32!")
} else if anon.IsA(reflect.Float64) {
fmt.Println("Its A Float64!")
} else {
fmt.Println("Failed")
}
可以在这里看到更长、可工作的版本:https://play.golang.org/p/EIAp0z62B7
英文:
I'm going to offer up a way to return a boolean based on passing an argument of a reflection Kinds to a local type receiver (because I couldn't find anything like this).
First, we declare our anonymous type of type reflect.Value:
type AnonymousType reflect.Value
Then we add a builder for our local type AnonymousType which can take in any potential type (as an interface):
func ToAnonymousType(obj interface{}) AnonymousType {
return AnonymousType(reflect.ValueOf(obj))
}
Then we add a function for our AnonymousType struct which asserts against a reflect.Kind:
func (a AnonymousType) IsA(typeToAssert reflect.Kind) bool {
return typeToAssert == reflect.Value(a).Kind()
}
This allows us to call the following:
var f float64 = 3.4
anon := ToAnonymousType(f)
if anon.IsA(reflect.String) {
fmt.Println("Its A String!")
} else if anon.IsA(reflect.Float32) {
fmt.Println("Its A Float32!")
} else if anon.IsA(reflect.Float64) {
fmt.Println("Its A Float64!")
} else {
fmt.Println("Failed")
}
Can see a longer, working version here:https://play.golang.org/p/EIAp0z62B7
答案8
得分: 3
func typeofobject(x interface{}){
fmt.Println(reflect.TypeOf(x))
}
// Golang program to find the variable type
package main
// importing required packages
import (
"fmt"
)
// main function
func main() {
f := true
st := ""
a := 1
d := 1.0
arr := []string{"Go", "Is", "Fun"}
fmt.Printf("%T\n", f)
fmt.Printf("%T\n", st)
fmt.Printf("%T\n", a)
fmt.Printf("%T\n", d)
fmt.Printf("%T\n", arr)
}
func typeofobject(x interface{}){
fmt.Println(reflect.ValueOf(x).Kind())
}
source: geeks-for-geeks
英文:
You can use
- Printf("%T", interface{})
- reflect.TypeOf
- reflect.ValueOf(x).Kind()
-> reflect:
func typeofobject(x interface{}){
fmt.Println(reflect.TypeOf(x))
}
-> Printf()
// Golang program to find the variable type
package main
// importing required packages
import (
"fmt"
)
// main function
func main() {
f := true
st := ""
a := 1
d := 1.0
arr := []string{"Go", "Is", "Fun"}
fmt.Printf("%T\n", f)
fmt.Printf("%T\n", st)
fmt.Printf("%T\n", a)
fmt.Printf("%T\n", d)
fmt.Printf("%T\n", arr)
}
OUTPUT:
bool
string
int
float64
[]string
-> reflect.ValueOf(x).Kind())
func typeofobject(x interface{}){
fmt.Println(reflect.ValueOf(x).Kind())
}
source: geeks-for-geeks
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论