我可以创建一个具有相同签名的功能吗?

时间:2019-11-21 19:04:10

标签: go go-reflect

我需要创建一个包装内部函数的函数,并且具有与内部函数完全相同的签名。我担心这是不可能的,因为Go不支持泛型,但是使用beforeEach(() => { TestBed.configureTestingModule({ imports: [HttpClientTestingModule], providers: [AcessoService] }); httpTestingController = TestBed.get(HttpTestingController); service = TestBed.get(AcessoService); }); afterEach(() => { httpTestingController.verify(); }); const profileInfo = { data: new Date('2019-11-21T10:00:03.07').toISOString(), desconhecido: false, id: 21214, ip: '444.444.44.44', nomeUsuario: 'rodrigo.spinelli', sucesso: true, usuarioId: 1414, usuarioNome: 'rodrigo abreu' }; const index = '1'; const itemsPage = '1'; const usuarioId = ''; const nomeUsuario = ''; const dataIni = new Date('2019-11-01T18:25:39.000Z').toISOString(); const dataFim = new Date('2019-11-30T18:25:39.000Z').toISOString(); const ip = ''; const sucesso = ''; const orderBy = ''; let Acessos; it('can load instance', () => { expect(service).toBeTruthy(); }); it('getDepartmentMapping() should return data', () => { service.getAcessos(index, itemsPage, '', '', dataIni, dataFim, '', '', '').subscribe(res => { Acessos = res.items; }); expect(Acessos).toEqual(profileInfo); }); }); 也许可以实现吗?以下是我想拥有的伪指令:

reflect

伪代码中充满了错误,但是想法是func myFunc(a int, b string) (string, error) { return string(a) + b, nil } func wrapInner(inner interface{}) interface{} { argTypes := argsOf(inner) returnTypes := returnsOf(inner) wrapper := func(args argTypes) returnTypes { // do something with inner's args modArgs := doSomething(args) ret := inner(modArgs) // do something with the return modRet := doSomething(ret) } return wrapper } wrapped := wrapInner(myFunc) val, err := wrapped(1, "b") 不了解wrapInner的签名。但是,它能够检查签名(也许使用inner?)并创建一个函数,该函数将逻辑添加到内部,并且具有与内部完全相同的签名。这可能吗?

1 个答案:

答案 0 :(得分:0)

您要实现的是中间件模式。通常使用接口来实现。您必须为要注释的每个功能手动实现中间件功能。

这里是一个例子:

package main

import (
    "fmt"
    "strconv"
)

type Service interface {
    myFunc(a int, b string) (string, error)
}

type implService struct{}

func (s implService) myFunc(a int, b string) (string, error) {
    return strconv.Itoa(a) + b, nil
}

type loggingMiddleware struct {
    next Service
}

func (s loggingMiddleware) myFunc(a int, b string) (string, error) {
    fmt.Println(a, b)
    return s.next.myFunc(a, b)
}

func main() {
    var myservice Service = &implService{}

    myservice = &loggingMiddleware{
        next: myservice,
    }
    result, err := myservice.myFunc(1, "a") // prints 1 a
    fmt.Println(result, err)                // prints 1a <nil>

}