为了账号安全,请及时绑定邮箱和手机立即绑定

如何在1.18中使用golang泛型来简化代码片段?

如何在1.18中使用golang泛型来简化代码片段?

Go
慕桂英546537 2022-11-23 16:04:20
我一直在使用 2 个由OpenAPI 生成器在单独的包中生成的 SDK,它们共享在不同包中重复的相同代码foo,bar:package foo// there's the exact same piece of code under another package bar// GenericOpenAPIError Provides access to the body, error and model on returned errors.type GenericOpenAPIError struct {    ...    model interface{}}// Model returns the unpacked model of the errorfunc (e GenericOpenAPIError) Model() interface{} {    return e.model}// Failure Provides information about problems encountered while performing an operation.type Failure struct {    // List of errors which caused this operation to fail    Errors []Error `json:"errors"`}// GetErrors returns the Errors field valuefunc (o *Failure) GetErrors() []Error {...}// Error Describes a particular error encountered while performing an operation.type Error struct {    ...    // A human-readable explanation specific to this occurrence of the problem.    Detail *string `json:"detail,omitempty"`    ...}另外,有一个应用程序,我在其中使用了两个 SDK:,并从错误列表foo中bar提取了第一个错误,我在其中尝试将错误转换为每个 SDK 的错误类型,因此必须复制代码。1.18有没有一种方法可以使用支持泛型的方法来简化它?
查看完整描述

1 回答

?
Cats萌萌

TA贡献1805条经验 获得超9个赞

您可以更改mainErrorModel为struct with no pointer带有类型断言,然后将该结构更改为struct with pointer,最后您可以再次更改为Failure带有类型断言的类型接口。


这是例子。


// You can edit this code!

// Click here and start typing.

package main


import (

    "fmt"

)


type GenericOpenAPIError interface {

    Model() any

}


type Failure interface {

    GetErrors() string

}


type GenericOpenAPI struct {

    model any

}


func (g *GenericOpenAPI) Model() any {

    return g.model

}


func (g *GenericOpenAPI) Error() string {

    return "goae error"

}


type A struct {

    b string

}


func (a *A) GetErrors() string {

    return a.b

}


type B struct {

    c string

}


func (b *B) GetErrors() string {

    return b.c

}


type GetErrores interface {

    A | B

}


func getErrorMessage[T GetErrores](err error) string {

    if mainError, ok1 := err.(GenericOpenAPIError); ok1 {

        var mainErrorModel = mainError.Model()

        if t, ok := mainErrorModel.(T); ok {

            if f, ok := any(&t).(Failure); ok { // must change &t to any then type assert to Failure to tell app that there is a method GetErrors()

                return f.GetErrors()

            }

        }

    }

    return err.Error()

}


func main() {

    var err any


    err = &GenericOpenAPI{A{b: "this is error a"}}


    e, ok := err.(error)

    if !ok {

        panic("not ok!")

    }


    fmt.Println(getErrorMessage[A](e))


    // change model to B

    err = &GenericOpenAPI{B{c: "this is error b"}}


    e, ok = err.(error)

    if !ok {

        panic("not ok!")

    }


    fmt.Println(getErrorMessage[B](e))

}


查看完整回答
反对 回复 2022-11-23
  • 1 回答
  • 0 关注
  • 100 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信