Home > Back-end >  How to coerce an extended builtin type back to a builtin
How to coerce an extended builtin type back to a builtin

Time:10-16

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)
}
  •  Tags:  
  • go
  • Related