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.
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)
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
不是 toadminctx
。 toadminctx
函数类型是可以使用上下文和字面上的任何类型调用的函数。您的 update
函数不能保证在 toadminctx
anda ialah *reqtype
dan nilai pulangan pertamanya ialah nilai resptype
, jadi
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
(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 }
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
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) } }
, kami melakukan perkara berikut: update
函数使用的特定类型替换通用 t
和 r
类型。因为我真的不知道你想以这种方式包装什么函数,所以我使用了 t any, r any
a.adminapi.adminm2msetter[*reqtype, resptype](s.adminapi.update)
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 }
Atas ialah kandungan terperinci Apakah parameter fungsi penghias Golang?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!