1

我正在使用 vavrEither来控制我的应用程序的流程并且它工作得很好,直到我不必混合几个域......

首先,我有一个在域之间共享的接口。

public interface DomainError {
    String getCause();
}

成功也是如此,当我只想通知用户并且不需要返回特定对象时。

@RequiredArgsConstructor
@Getter
public class SuccessMessage {
    private final String message;
}

现在,每个域DomainError都是这样实现的

public enum UserError implements DomainError {
    USERNAME_ALREADY_EXISTS("Username already exists"),
    INVALID_EMAIL("Provided email address is invalid");

    private final String cause;
    UserError(String cause) {
        this.cause = cause;
    }
    @Override
    public String getCause() {
        return cause;
    }
}

类似地,它会寻找EmailError其中只有另一个值的内部。我现在有EmailFacade

public class EmailFacade {
    private final SendEmailUseCase sendEmail;
    private final CreateEmailUseCase createEmail;

    public Either<DomainError, SuccessMessage> sendUserVerificationEmail(UUID uuid, String receiver) {
        return sendEmail.send(createEmail.createUserVerificationEmail(uuid, receiver));
    }
}

它的一项服务返回

class SendEmailUseCase {
    Either<DomainError, SuccessMessage> send(EmailMessage message) {
        if(message == null) return Either.left(EmailError.EMPTY_MESSAGE);
        log.info(message.toString());
        return Either.right(new SuccessMessage("Email sent"));
    }
}

现在,我需要从处理用户注册的其他域调用它。

为了做到这一点,我写了这个方法

Either<DomainError, SuccessMessage> register(RegisterUserDto registerUserDto) {
        if(userRepository.findUser(registerUserDto.getUsername()).isPresent())
            return Either.left(UserError.USERNAME_ALREADY_EXISTS);
        Either<DomainError, User> userCreationResult = User.createUser(registerUserDto);
        return userCreationResult
            .map(user -> {
                userRepository.save(user.toDto());
                final UUID uuid = verificationTokenRepository.generateVerificationToken(user.getUsername());
                return emailFacade.sendUserVerificationEmail(uuid, user.getUsername());
            });
    }

我在这里做的事情很少,但相关部分是最后一个返回语句,以上所有内容都在工作。emailFacade.sendUserVerificationEmail()返回Either<DomainError, SuccessMessage>,与register()方法相同。但由于某种原因,我收到了这个错误

错误:(28、17)java:不兼容的类型:推理变量 U 具有不兼容的边界等式约束:com.johndoe.myapp.domain.SuccessMessage 下限:io.vavr.control.Either<com.johndoe.myapp.domain.DomainError,com.johndoe.myapp.domain.SuccessMessage>

我真的无法理解这里出了什么问题......

4

1 回答 1

1

方法map用于转换容器内的值。在您的情况下,它为您提供 User 的值,并期望您返回转换后的值。因此,如果您要返回Either<DomainError, User>,那么结果类型将是Either<DomainError, Either<DomainError, User>>,它不是方法签名所期望的返回类型。

如果您不想从函数中返回 Either,那么您应该flatMap改用它,这会将结果展平为Either<DomainError, User>

return userCreationResult
   .flatMap(user -> { //replace map with flatMap
        userRepository.save(user.toDto());
        final UUID uuid = verificationTokenRepository.generateVerificationToken(user.getUsername());
        return emailFacade.sendUserVerificationEmail(uuid, user.getUsername());
});
于 2019-08-05T12:29:26.933 回答