如何将扩展的内置类型强制转换回内置类型?

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

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)
}

huangapple
  • 本文由 发表于 2021年10月15日 05:04:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/69577329.html
匿名

发表评论

匿名网友

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

确定