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)
}
}
}
CodePudding user response:
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)
}