Go语言 将“any”强制转换为基类型的切片

eqqqjvef  于 2023-08-01  发布在  Go
关注(0)|答案(1)|浏览(288)

我有一个类型本体,它看起来像:

type Base struct { ID: string }

type RecordA struct { Base, ... }
type RecordB struct { Base, ... }
type RecordC struct { Base, ... }
...

字符串
我正在写一个方法,它接受一个any参数,需要确定它是否是一个可以转换为Base的类型的切片,执行该转换,并返回它:

func (arg any) ([]Base, error) {
  // if any is a slice of a struct which can be cast to `Base`, return the cast slice
  // otherwise error
}


我可以将arg转换为任何特定的实现结构体作为数组类型,但我很难弄清楚如何在没有包含Base的所有“扩展”的大量switch的情况下做到这一点。

vpfxa7rd

vpfxa7rd1#

这是我能想到的一个好办法,不知道是否合适,欢迎交流。

package main

import (
    "fmt"
    "log"
)

type Base struct{ ID string }

func (b Base) GetBase() Base {
    return b
}

type RecordA struct {
    Base
    A string
}
type RecordB struct {
    Base
    B string
}

type RecordC struct {
    Base
    C string
}

type RecordD struct {
    D string
}

func (r RecordD) GetBase() Base {
    return Base{ID: r.D}
}

type baseGetter interface {
    GetBase() Base
}

func ToBaseSlice(arg any) ([]Base, error) {
    switch v := arg.(type) {
    case []any:
        var out []Base
        for _, i := range v {
            if g, ok := i.(baseGetter); ok {
                out = append(out, g.GetBase())
            }
        }
        if len(out) == 0 {
            return nil, fmt.Errorf("no element can be convert to Base")
        }
        return out, nil
    case baseGetter:
        return []Base{v.GetBase()}, nil
    }
    return nil, fmt.Errorf("can not convert to []Base")
}

func main() {
    out, err := ToBaseSlice([]any{
        RecordA{Base: Base{ID: "A"}},
        RecordB{Base: Base{ID: "B"}},
        RecordC{Base: Base{ID: "C"}},
        RecordD{D: "D"},
    })
    if err != nil {
        log.Println(err)
        return
    }
    log.Println(out)
}

字符串

相关问题