Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Apakah parameter fungsi penghias Golang?

Apakah parameter fungsi penghias Golang?

WBOY
WBOYke hadapan
2024-02-08 23:09:391436semak imbas

Golang 装饰器函数的哪些参数

editor php Baicao akan memperkenalkan kepada anda parameter fungsi penghias Golang. Di Golang, fungsi penghias ialah fungsi khas yang boleh digunakan untuk membungkus fungsi lain dan menambah fungsi tambahan padanya. Fungsi penghias biasanya mempunyai tiga parameter: fungsi asal, parameter fungsi penghias dan nilai pulangan. Fungsi asal ialah fungsi yang perlu dihias Parameter fungsi penghias boleh daripada apa-apa jenis dan boleh digunakan untuk menghantar parameter tambahan kepada fungsi penghias biasanya merupakan fungsi yang menggantikan pelaksanaan asal fungsi. Melalui parameter ini, kami boleh melaksanakan pelbagai mod penghias fleksibel, menambah fungsi berbeza pada fungsi dan meningkatkan kebolehgunaan semula dan kebolehskalaan kod.

Kandungan soalan

Saya ingin menggunakan setter pada beberapa kaedah adminapi, seperti update. Untuk melakukan ini, saya mencipta jenis kaedah yang boleh dipadankan dengan kaedah lain.

Perlukah saya menggunakan antara muka dan bukannya func type?

type adminapi struct {
}

type toadminctx func(ctx context.context, req interface{}) (interface{}, error)

func (a adminapi) adminm2msetter(s toadminctx) toadminctx {
    return func(ctx context.context, arg interface{}) (interface{}, error) {
        m2mprincipal, _ := a.getm2mprincipal(ctx)
        ctxm2m := extlib.setprincipal(ctx, m2mprincipal)
        return s(ctxm2m, arg)
    }
}

func (a adminapi) update(ctx context.context, req *reqtype) (resptype, error) {}
updateWithAdminCtx := a.adminAPI.AdminM2MSetter(s.adminAPI.Update)
// ERROR => cannot use s.adminAPI.Update (value of type func(ctx 
// context.Context, req *ReqType) (RespType, error)) as grpcAdmin.ToGetAdminCtx value in 
// argument to s.adminAPI.AdminM2MSetter

_, err := updateWithAdminCtx(ctx context.Context, req *ReqType)

Penyelesaian

Saya rasa ralat yang anda perolehi adalah jelas:

a.adminapi.adminm2msetter(s.adminapi.update)

Hubungi sekarang

func (a adminapi) adminm2msetter(s toadminctx) toadminctx {

Masuk s.adminapi.update 作为参数,预计类型为 toadminctx. Takrifan anda untuk jenis ini ialah:

type toadminctx func(ctx context.context, req interface{}) (interface{}, error)

Tetapi parameter kedua bagi fungsi update 函数的第二个参数是 *reqtype,其第一个返回值是 resptype 值,因此 update 不是 toadminctxtoadminctx 函数类型是可以使用上下文和字面上的任何类型调用的函数。您的 update 函数不能保证在 toadminctx anda ialah *reqtype dan nilai pulangan pertamanya ialah nilai resptype, jadi

bukan toadminctx . Jenis fungsi toadminctx ialah fungsi yang boleh dipanggil menggunakan konteks dan secara harfiah sebarang jenis. Fungsi

anda tidak dijamin berfungsi dalam semua kes di mana fungsi toadminctx boleh. ctx

Apa yang anda cari ialah cara untuk "membungkus" sebarang fungsi, menambah beberapa kerja pada parameter

(mungkin menetapkan beberapa nilai), dan kemudian meneruskan panggilan. Sebelum pergi 1.19 kami melakukan ini dengan menambah beberapa jenis pembalut seperti ini: update

type wrapper struct {
    updatereqtype *reqtype
    anothertype *reqtype2 // for some other call you want to wrap
}

Tukar semua fungsi berkaitan seperti

fungsi untuk mengambil jenis hujah pembalut:

func (a adminapi) update(ctx context.context, req wrapper) (resp, error) {
    realreq := req.updatereqtype // get the actual request used here
}

Jenis respons akan dibalut dan/atau digabungkan dengan sama. adminm2msetter

Sekarang go menyokong generik dan ia sangat berguna dalam kes ini, mari tukar fungsi

menjadi seperti ini: update

func adminm2msetter[t any, r any](s func(context.context, t) (r, error)) func(context.context, t) (r, error) {
    return func (ctx context.context, arg t) (r, error) {
        m2mprincipal, _ := a.getm2mprincipal(ctx)
        ctxm2m := extlib.setprincipal(ctx, m2mprincipal)
        return s(ctxm2m, arg)
    }
}

Dengan cara ini, kita hanya perlu mentakrifkan fungsi ini sekali, dan sebaliknya bergantung pada pengkompil untuk menjana fungsi yang dibuat khusus untuk semua jenis yang kita perlukan. Untuk fungsi

, kami melakukan perkara berikut: update 函数使用的特定类型替换通用 tr 类型。因为我真的不知道你想以这种方式包装什么函数,所以我使用了 t any, r any

a.adminapi.adminm2msetter[*reqtype, resptype](s.adminapi.update)

Pada asasnya menggantikan jenis t dan r generik dengan jenis khusus yang digunakan oleh fungsi

. Oleh kerana saya tidak benar-benar tahu fungsi apa yang anda mahu bungkus dengan cara ini, saya menggunakan t any, r any, tetapi memandangkan saya nampaknya anda cuba membungkus beberapa jenis pengendali permintaan , jadi anda boleh membuat kekangan anda sendiri: [t any, r any] 替换为 [t requests, r responses]

type Requests interface {
    *ReqType1 | *ReqType2 | *ReqType3 // and so on
}
type Responses interface {
    Resp1 | Resp2 | Resp3
}

Hanya tambah 🎜🎜

Atas ialah kandungan terperinci Apakah parameter fungsi penghias Golang?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:stackoverflow.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam