Home >Backend Development >Golang >Convert private dynamic type from interface {}

Convert private dynamic type from interface {}

WBOY
WBOYforward
2024-02-06 09:15:111017browse

Convert private dynamic type from interface {}

Question content

I am trying to use the go-sqlmock package to test a sql query where one of the parameters is gosnowflake .array (essentially a wrapper around slices). Usually something like this would require me to create a value converter, which I've included:

func (opt arrayConverterOption[T]) ConvertValue(v any) (driver.Value, error) {
    casted, ok := v.(*[]T)
    if ok {
        Expect(*casted).Should(HaveLen(len(opt.Expected)))
        for i, c := range *casted {
            Expect(c).Should(Equal(opt.Expected[i]))
        }
    } else {
        fmt.Printf("Type: %T\n", v)
        return v, nil
    }

    return "TEST_RESULT", nil
}

Now, this function is called for each parameter submitted to the query. I use this to test that the values ​​in a slice are correct, or pass parameters if not. The problem I'm having is that when I create arrayconverteroption[string] and give it a gosnowflake.array(["a", "b", "c"]) as parameter , the type assertion fails because gosnowflake.array returns an internal dynamic type *stringarray, which is defined as *[]string.

So you can see my dilemma here. On one hand, I can't convert v because it is interface{} and I can't alias v because the internal type is not *[]string , but *stringarray. So, what should I do here?


Correct answer


I haven't found a way to do this without causing reflection. However, upon reflection, I did:

var casted []T
var ok bool

value := reflect.ValueOf(v)
if value.Kind() == reflect.Pointer {
    if inner := value.Elem(); inner.Kind() == reflect.Slice {
        r := inner.Convert(reflect.TypeOf([]T{})).Interface()
        casted, ok = r.([]T)
    }
}

So this code specifically checks for any pointer to a slice, which is my dynamic type. It then uses reflection to convert the inner object to the slice type I expect. After that, I call interface() on the result to get the interface{} from the reflected value and then convert it to []t. That's it. If not, then I'm not using one of these dynamic type slices and I can handle the type normally.

The above is the detailed content of Convert private dynamic type from interface {}. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete