如何避免对具有不同功能的相同模式进行 go lint 重复?
how to avoid go lint duplication for same pattern with different function?
我在重构代码时遇到困难,因为 lint 检测到模式重复但功能不同。
代码是这样的,它是为带有protobuf定义的grpc实现的
func (svc *UserService) CreateUser(ctx context.Context, req *pb.CreateUserRequest) (*pb.CreateUserResponse, error) {
err := svc.validateCreateUser(req)
if err != nil {
return nil, err
}
user, err := svc.repo.CreateUser(ctx, req)
if err != nil {
return nil, err
}
return user, nil
}
func (svc *UserService) UpdateUser(ctx context.Context, req *pb.UpdateUserRequest) (*pb.UpdateUserResponse, error) {
err := svc.validateUpdateUser(req)
if err != nil {
return nil, err
}
user, err := svc.repo.UpdateUser(ctx, req)
if err != nil {
return nil, err
}
return user, nil
}
提前致谢。
我不知道如何避免重复,因为函数也有不同的参数类型。
并非所有 lint 问题都必须修复
如果您认为它会牺牲可读性,请添加 // nolint
但是……您可以使用泛型重构它们的代码
func [T, V any] someNameToBeDefined(
ctx context.Context,
target T,
validator func(T) error,
executor func(context.Context, T) (V, error),
) (V, error){
if err := validator(target); err!= nil { … }
return executor(ctx, target)
}
func (svc *UserService) CreateUser(
ctx context.Context,
req *pb.CreateUserRequest,
) (*pb.CreateUserResponse, error) {
return someNameToBeDefined(ctx,
req,
svc.validateCreateUser,
svc.repo.CreateUser,
)
}
如果您认为这是可读的,请继续。
但这也许不是正确的方法。
例如,您的存储库可以在 create/update 之前验证请求。
这是一种比使用泛型和函数指针恕我直言更具可读性的方法
我在重构代码时遇到困难,因为 lint 检测到模式重复但功能不同。
代码是这样的,它是为带有protobuf定义的grpc实现的
func (svc *UserService) CreateUser(ctx context.Context, req *pb.CreateUserRequest) (*pb.CreateUserResponse, error) {
err := svc.validateCreateUser(req)
if err != nil {
return nil, err
}
user, err := svc.repo.CreateUser(ctx, req)
if err != nil {
return nil, err
}
return user, nil
}
func (svc *UserService) UpdateUser(ctx context.Context, req *pb.UpdateUserRequest) (*pb.UpdateUserResponse, error) {
err := svc.validateUpdateUser(req)
if err != nil {
return nil, err
}
user, err := svc.repo.UpdateUser(ctx, req)
if err != nil {
return nil, err
}
return user, nil
}
提前致谢。
我不知道如何避免重复,因为函数也有不同的参数类型。
并非所有 lint 问题都必须修复
如果您认为它会牺牲可读性,请添加 // nolint
但是……您可以使用泛型重构它们的代码
func [T, V any] someNameToBeDefined(
ctx context.Context,
target T,
validator func(T) error,
executor func(context.Context, T) (V, error),
) (V, error){
if err := validator(target); err!= nil { … }
return executor(ctx, target)
}
func (svc *UserService) CreateUser(
ctx context.Context,
req *pb.CreateUserRequest,
) (*pb.CreateUserResponse, error) {
return someNameToBeDefined(ctx,
req,
svc.validateCreateUser,
svc.repo.CreateUser,
)
}
如果您认为这是可读的,请继续。
但这也许不是正确的方法。
例如,您的存储库可以在 create/update 之前验证请求。
这是一种比使用泛型和函数指针恕我直言更具可读性的方法