Apakah parameter fungsi penghias Golang?

WBOY
Lepaskan: 2024-02-08 23:09:39
ke hadapan
1416 orang telah melayarinya

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) {}
Salin selepas log masuk
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)
Salin selepas log masuk

Penyelesaian

Saya rasa ralat yang anda perolehi adalah jelas:

a.adminapi.adminm2msetter(s.adminapi.update)
Salin selepas log masuk

Hubungi sekarang

func (a adminapi) adminm2msetter(s toadminctx) toadminctx {
Salin selepas log masuk

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

type toadminctx func(ctx context.context, req interface{}) (interface{}, error)
Salin selepas log masuk

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
}
Salin selepas log masuk

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
}
Salin selepas log masuk

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)
    }
}
Salin selepas log masuk

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)
Salin selepas log masuk

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
}
Salin selepas log masuk
Hanya tambah 🎜🎜

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

sumber:stackoverflow.com
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!