Home  >  Article  >  Backend Development  >  Why can't Go cast interfaces that implement generics?

Why can't Go cast interfaces that implement generics?

WBOY
WBOYforward
2024-02-05 21:27:03546browse

为什么 Go 不能强制转换实现泛型的接口?

Question content

I was trying to explore Go's type system and have fun writing a small side project, but ended up running into a weird Condition.

When an interface can take a type in which it is used in a function, and a struct implements the interface, the interface is contained in a map of interface and I cannot convert it back to the implementation when retrieving it. Why? how? What's wrong?

package main

import (
    "context"
    "fmt"
)

type State struct {
    Data string
}

type InterfaceFuncs[T any] interface {
    Init(ctx context.Context,
        stateGetter func() T,
        stateMutator func(mutateFunc func(T) T)) error
}

type ConfigWrap[T any] struct {
    InterFuncs InterfaceFuncs[T]
}

type Controller[T any] struct {
    mapinterfaces map[string]ConfigWrap[T]
}

func New[T any](initialState T) *Controller[T] {
    return &Controller[T]{
        mapinterfaces: make(map[string]ConfigWrap[T]),
    }
}

func (c *Controller[T]) RegisterFuncs(pid string, config ConfigWrap[T]) error {
    c.mapinterfaces[pid] = config
    return nil
}

func (c *Controller[T]) InterFuncs(pid string) (*InterfaceFuncs[T], error) {

    var pp ConfigWrap[T]
    var exists bool

    if pp, exists = c.mapinterfaces[pid]; exists {
        return &pp.InterFuncs, nil
    }

    return nil, fmt.Errorf("InterFuncs not found")
}

func main() {

    ctrl := New[State](State{})

    ctrl.RegisterFuncs("something", ConfigWrap[State]{
        InterFuncs: &ImpltProcFuncs{
            Data: "get me back!!!!",
        },
    })

    // why can't we cast it back to ImpltProcFuncs
    getback, _ := ctrl.InterFuncs("something")

    // I tried to put it as interface but doesn't works either
    //// doesn't work
    switch value := any(getback).(type) {
    case ImpltProcFuncs:
        fmt.Println("working", value)
    default:
        fmt.Println("nothing")
    }

    //// doesn't work
    // tryme := any(getback).(ImpltProcFuncs) // panic: interface conversion: interface {} is *main.InterfaceFuncs[main.State], not main.ImpltProcFuncs
    // fmt.Println("please", tryme.Data)

    //// doesn't work
    // tryme := getback.(ImpltProcFuncs)

    //// doesn't work
    // switch value := getback.(type) {
    // case ImpltProcFuncs:
    //     fmt.Println("working", value)
    // }
}

type ImpltProcFuncs struct {
    Data string
}

func (p *ImpltProcFuncs) Init(
    ctx context.Context,
    stateGetter func() State,
    stateMutator func(mutateFunc func(State) State)) error {
    return nil
}

How to return ImpltProcFuncs as a variable to get Data?

What did I miss?

I think Go is capable of returning anything from interface.


Correct answer


Well, after digging deeper, you can use Bing thanks to ChatGPT...

if impl, ok := (*getback).(*ImpltProcFuncs); ok {
        fmt.Println("working", impl.Data)
    } else {
        fmt.Println("not working")
    }

When executed, it outputs "working get me back!!!!"

The above is the detailed content of Why can't Go cast interfaces that implement generics?. 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