获取 interface{} 的值而不需要访问类型。

huangapple go评论73阅读模式
英文:

Get value of interface{ } without having access to type

问题

如何将x的值作为[]interface{}获取?

func main() {

    var x interface{} = SomeFunc()
    
    fmt.Println(x) // 这将打印出 [1 2]。

    val := x.([]interface{}) // 这样做是行不通的,因为`[]interface{}`与`a`是不同的类型

}

func SomeFunc() interface{} {
    // 一些我无法访问的类型
	type a []interface{}

	var someArray a = make([]interface{}, 0)
	someArray = append(someArray, 1)
	someArray = append(someArray, 2)
	return someArray
}

你可以使用类型断言来将x的值转换为[]interface{}类型。在这个例子中,x的类型是interface{},而不是[]interface{},所以直接将其转换为[]interface{}是不可行的。你可以使用以下代码来进行类型断言:

val := x.([]interface{})

这将把x的值转换为[]interface{}类型,并将结果赋给val变量。

英文:

How can I get the value of x as []interface{} ?

func main() {

    var x interface{} = SomeFunc()
    
    fmt.Println(x) // this prints [1 2].

    val := x.([]interface{}) // this will not work because '[]interface{}' is different type than 'a'

}

func SomeFunc() interface{} {
    // some type I dont have access to
	type a []interface{}

	var someArray a = make([]interface{}, 0)
	someArray = append(someArray, 1)
	someArray = append(someArray, 2)
	return someArray
}

答案1

得分: 2

类型断言只适用于接口值中存储的确切(相同)具体类型,无法对“相似”类型进行类型断言(例如具有相同基础类型的类型)。

在你的情况下,你想要的是获取一个可转换为已知类型的值(例如,将类型为a的值转换为类型为[]interface{}的值)。如上所述,使用类型断言是不可能的。

最简单的方法是导入包,该包包含具体类型的定义(并对该类型的值进行类型断言)。如果它没有被导出或者不可访问,你唯一的选择就是使用反射。你可以使用Value.Convert()将一个值转换为另一个类型的值,即你可以进行类型断言的类型的值。要检查值是否实际可转换,可以使用Value.CanConvert()

y := reflect.ValueOf(x).Convert(reflect.TypeOf([]interface{}{})).Interface()

val := y.([]interface{})
fmt.Printf("%T %v\n", val, val)

这将输出(在Go Playground上尝试):

[1 2]
[]interface {} [1 2]
英文:

Type asserting a concrete type works only for the exact (identical) concrete type stored in an interface value, you can't type assert "similar" types (e.g. types having the same underlying type).

In your case what you want is get a value that is convertible to a known type (e.g. a value of type a convertible to a value of type []interface{}). As said above, this is not possible with type assertion.

The easiest is to import the package that holds the definition of the concrete type (and type assert a value of that type). If it's not exported or not accessible, your only option is using reflection. You may use Value.Convert() to convert a value to a value of another type, a value of a type you can type assert. To check if the value is actually convertible, you may use Value.CanConvert().

y := reflect.ValueOf(x).Convert(reflect.TypeOf([]interface{}{})).Interface()

val := y.([]interface{})
fmt.Printf("%T %v\n", val, val)

This will output (try it on the Go Playground):

[1 2]
[]interface {} [1 2]

huangapple
  • 本文由 发表于 2022年4月17日 15:22:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/71900027.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定