亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何在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 關注
  • 128 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號