英文:
How to coerce an extended builtin type back to a builtin
问题
我正在尝试将扩展的内置类型强制转换回其原始的内置类型,以便在数学运算中使用它。
以下是一个示例,说明了我的问题。valueType1
扩展了字符串类型,valueType2
扩展了整数类型。
我得到了以下错误信息:
不可能的类型断言:int 未实现 Value 接口(缺少 DoThing 方法)
给定一个接口 Value
的数组,有没有办法确定传递的 Value
是否为整数,并将其强制转换回整数类型以进行实际的数学运算?
将强制转换改为 if w, ok := interface{}(v).(int); ok {
可以成功编译,但不起作用。
注意 - 对于这个示例,我完全可以添加一个单独的方法 func (v valueType2) GetValue() int
,并针对特定的 valueType2
类型进行类型转换。实际上的问题是,特定的非接口类型位于不同的包中且未导出。只有 Value
接口是导出的,而且我无法访问更改该包。
英文:
I am trying to coerce an extended builtin type back to its original builtin type for purposes of using it for Mathematical operation.
Below is a toy example of what I'm trying to do that illustrates my problem. valueType1
extends string and valueType2
extends int.
I'm given the error
> impossible type assertion: int does not implement Value (missing DoThing method)
Given an array of interface Value
, is there any way to determine if the passed Value
is an integer and then cast it back as such for actual math purposes?
Changing the coercion to if w, ok := interface{}(v).(int); ok {
compiles successfully but does not work.
Note - With this toy example, I could absolutely add a separate method func (v valueType2) GetValue() int
and type coerce or cast against the specific valueType2
type. The problem in actuality is that the specific non-interface types are in a different package and not exported. Only the Value
interface is exported, and I don't have access to change said package.
package main
import "fmt"
type Value interface {
DoThing()
}
type valueType1 string
func (v valueType1) DoThing() {
fmt.Println(v, "is a pretty sweet string")
}
type valueType2 int
func (v valueType2) DoThing() {
fmt.Println(v, "is a pretty sweet int")
}
func main() {
var x valueType1 = "foo"
var y valueType2 = 10
z := []Value{x, y}
for _, v := range z {
if w, ok := v.(int); ok {
fmt.Println(w)
}
}
}
答案1
得分: 2
你可以使用reflect
包来确定类型的kind。一旦你知道了类型的kind,你可以使用相应的getter(在你的情况下是(reflect.Value).Int()
)来获取内置类型的实例。
请注意,由于Int()
返回一个int64
值,而你需要一个int
值,所以你还需要进行显式转换。
if rv := reflect.ValueOf(v); rv.Kind() == reflect.Int {
w := int(rv.Int())
fmt.Printf("%v type=%T", w, w)
}
英文:
You could use the reflect
package to determine the kind of a type. Once you know the kind you can use the corresponding getter (in your case (reflect.Value).Int()
) to get an instance of the value in the builtin type.
Note that, since Int()
returns an int64
value and you need an int
value, additionally you will need to do an explicit conversion.
if rv := reflect.ValueOf(v); rv.Kind() == reflect.Int {
w := int(rv.Int())
fmt.Printf("%v type=%T", w, w)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论