Pie*_*nry 4 functional-programming kotlin java-stream
我试图将对象列表映射到另一种类型的对象列表,然后过滤列表,然后映射到第三种类型的列表,就像我在Java 8+中链接流一样(我更改了类和变量名称,使其更有意义,但结构与我的代码相同):
val results: List<AccountDto> = listOfPersons
.map { person -> getPersonAccount(person) }
.filter { account ->
if(validateAccount(account)){ // validateAccount is a function with boolean return type
// do something here like logging
return true
}
// do something else...
return false
}
.map { account ->
toDto(account) // returns an AccountDto
}
Run Code Online (Sandbox Code Playgroud)
我在过滤器lambda中的return true和return false语句上遇到编译器错误:
Error:(217, 32) Kotlin: The boolean literal does not conform to the expected type List<AccountDto>
Run Code Online (Sandbox Code Playgroud)
如果我对过滤谓词使用匿名函数,它编译很好:
.filter (fun(account):Boolean{
if(validateAccount(account)){
// do something here like logging
return true
}
// do something else...
return false
})
Run Code Online (Sandbox Code Playgroud)
为什么类型推断在这种情况下失败?
有可能以某种方式让它只用一个lambda吗?
HTN*_*TNW 11
return从最近的封闭函数或匿名函数(即表单fun(a1: T1, ..., an: TN): TR = ...)返回.助记符是不合格return的上升到最近的fun.lambda不是匿名函数,因此return它实际上是从包含整个map/ filterexpression 的函数返回的.您可以使用带标签的退货:
val results: List<AccountDto> = listOfPersons
.map(::getPersonAccount)
.filter { account ->
if(validateAccount(account)){
// etc.
return@filter true
}
// etc.
return@filter false
}
.map(::toDto)
Run Code Online (Sandbox Code Playgroud)
lambda表达式使用传递给它的函数隐式标记,因此您不需要显式添加标签.如果您希望拥有它,您可以:
val results: List<AccountDto> = listOfPersons
.map(::getPersonAccount)
.filter lam@{ account ->
if(validateAccount(account)){
// etc.
return@lam true
}
// etc.
return@lam false
}
.map(::toDto)
Run Code Online (Sandbox Code Playgroud)
但是if/ else它本身就是一个表达式,所以只需要没有returns 就足够了.
val results: List<AccountDto> = listOfPersons
.map(::getPersonAccount)
.filter { account ->
if(validateAccount(account)) {
// etc.
true
} else {
// etc.
false
}
}
.map(::toDto)
Run Code Online (Sandbox Code Playgroud)