首页 > 解决方案 > 使用 kotlin 进行函数式编程 - 避免使用 var

问题描述

我正在使用 kotlin 和函数式编程来开发一个 api。我真的不知道我是否在这里使用这里违反了任何 FP 规则。我有一个以下函数,它为我提供了 customerNumber 和一堆其他字段。

data class CustomerInfo(val customerNumber:String?=null,val accountNumber:String?=null,val email:String?=null)

我有很多条件的功能,但所有领域的条件都是相同的

fun getCustomerInfo(someDto:SomeDto,someOtherDto:SomeOtherDto,oneMoreDto:OneMoreDto):CustomerInfo
{
    var customerNumber = someDto.id
    var accountNo = someDto.accountNumber
    var email = someDto.email
    
    if(someCondition())
    { 
        customerNumber=   someOtherDto.id
        accountNo = someOtherDto.accountNo
        email = someOtherDto.email
    }else if(someOtherConditiion)
    {
        customerNumber=   oneMoreDto.id
        accountNo = oneMoreDto.accountNo
        email = oneMoreDto.email
    }
    //and many more conditions like this 
    return CustomerInfo(customerNumber,accountNo,email)
}

在函数中使用var是错误的吗?如何在不使用 var 的情况下编写此函数?我知道一旦条件满足,我每次都可以直接返回 dto,但我想在 10 个条件下使用相同的 dto?任何帮助将不胜感激

标签: kotlinfunctional-programmingpurely-functional

解决方案


使用 技术上没有任何问题var,因为您处于函数的本地范围内。

但是您可以避免大量样板代码,例如:

fun getCustomerInfo(someDto:SomeDto,someOtherDto:SomeOtherDto,oneMoreDto:OneMoreDto):CustomerInfo
{
  return when {
    someCondition() -> CustomerInfo(someOtherDto.id, someOtherDto.accountNumber, someOtherDto.email)
    someOtherConditiion() -> CustomerInfo(oneMoreDto.id, oneMoreDto.accountNumber, oneMoreDto.email)
    else -> CustomerInfo(someDto.id, someDto.accountNumber, someDto.email)
  }
}

如果生成了所有(不同的)DTO,则可以考虑为它们创建映射器扩展函数:

// top-level functions
fun SomeDto.toConsumerInfo(): CustomerInfo = ConsumerInfor(id, accountNumber, email)
fun SomeOtherDto.toConsumerInfo(): CustomerInfo = ConsumerInfor(id, accountNumber, email)
fun OneMoreDto.toConsumerInfo(): CustomerInfo = ConsumerInfor(id, accountNumber, email)
// and more for other DTO's you want to map

然后你可以像这样使用它们:

fun getCustomerInfo(someDto:SomeDto,someOtherDto:SomeOtherDto,oneMoreDto:OneMoreDto):CustomerInfo {
  return when {
    someCondition() -> someOtherDto.toConsumerInfo()
    someOtherConditiion() -> oneMoreDto.toConsumerInfo()
    else -> someDto.toConsumerInfo()
  }

推荐阅读