Kotlin中如何优雅验证多属性非空并返回完整错误列表?
实现API模型到领域模型的全字段验证映射(返回所有错误)
给定全可空字段的API模型:
data class MyApiModel( val property1: Int?, val property2: String?, val property3: Boolean?, )
对应全必填字段的领域模型:
data class MyDomainModel( val property1: Int, val property2: String, val property3: Boolean, )
以及返回验证结果的容器类:
data class ModelMapperResult<T>( val value: T, val validationErrors: List<String>, )
原实现仅能返回首个验证错误,以下是满足全错误收集、安全无!!、易读易写的优化方案:
优化实现方案
带辅助函数的简洁版本
// 封装字段检查逻辑,复用性强 private fun <T> checkField(field: T?, errorMessage: String, errors: MutableList<String>): T? { return field ?: run { errors.add(errorMessage) null } } fun MyApiModel.toDomainModel(): ModelMapperResult<MyDomainModel?> { val validationErrors = mutableListOf<String>() // 逐个检查字段,收集所有空字段错误 val safeProperty1 = checkField(property1, "Missing property1", validationErrors) val safeProperty2 = checkField(property2, "Missing property2", validationErrors) val safeProperty3 = checkField(property3, "Missing property3", validationErrors) // 无错误时构建领域模型(智能转换保证安全) val domainModel = if (validationErrors.isEmpty()) { MyDomainModel( property1 = safeProperty1 as Int, property2 = safeProperty2 as String, property3 = safeProperty3 as Boolean ) } else { null } return ModelMapperResult(domainModel, validationErrors) }
无辅助函数的直白版本(适合简单场景)
fun MyApiModel.toDomainModel(): ModelMapperResult<MyDomainModel?> { val validationErrors = mutableListOf<String>() val safeProperty1 = property1 ?: run { validationErrors.add("Missing property1") null } val safeProperty2 = property2 ?: run { validationErrors.add("Missing property2") null } val safeProperty3 = property3 ?: run { validationErrors.add("Missing property3") null } val domainModel = if (validationErrors.isEmpty()) { MyDomainModel( property1 = safeProperty1 as Int, property2 = safeProperty2 as String, property3 = safeProperty3 as Boolean ) } else { null } return ModelMapperResult(domainModel, validationErrors) }
方案优势说明
- 全错误收集:遍历所有字段,将所有空字段的错误信息收集到列表中,而非遇到第一个错误就返回;
- 安全可靠:未使用
!!运算符,而是通过isEmpty()判断后使用智能转换as——当错误列表为空时,所有safeProperty必然非空,转换绝对安全; - 易用性强:辅助函数封装了重复的字段检查逻辑,新增字段时只需一行代码调用,代码简洁易读;
- 逻辑清晰:先完成所有验证,再根据验证结果决定是否构建领域模型,流程直观。
内容的提问来源于stack exchange,提问作者jjoelson
相关产品推荐
相关产品推荐

