接收转换映射函数发送到 `List<>.mapNotNull()`
Receive transformation map function to send into `List<>.mapNotNull()`
我正在尝试编写一个类似 transform
的函数,它接收一个将在 mapNotNull 内部使用的函数,但我找不到实现它的方法。
例子
val items: List<String?> = listOf(null, "cosa")
fun transform(transformer: (String) -> String?) {
items.mapNotNull(transformer) // <-------------------------------------- THIS DOES NOT COMPILE
}
fun main() {
val items: List<String?> = listOf(null, "cosa")
val transformer: (String) -> String? = {
null
}
val map = transform(transformer)
print(map)
}
您可以在此处查看其工作原理:play.kotlinlang
如何声明 fun transform
的参数才能在 mapNotNull
中传递它?
您有一个可为空字符串的列表。
mapNotNull
将变换函数应用于列表中的每个元素,然后检查此函数的结果是否为空。所以在这种情况下,它在 transformer
函数中传递了一个可为空的字符串,而该函数肯定不能是 (String) -> String?
类型,因为这里的参数是一个不可为空的字符串。
您应该将转换器函数声明为 (String?) -> String?
,或者在调用 mapNotNull
:
之前从列表中删除空值
items.filterNotNull().mapNotNull(transformer)
另一种选择是将 transformer
包装到 lambda 函数中,然后再将其传递给 mapNotNull
并在那里处理空元素,例如:
items.mapNotNull { e -> e?.let(transformer) }
这仅在元素不为空时才将 transformer
函数应用于元素。
mapNotNull
函数定义为:
public inline fun <T, R : Any> Iterable<T>.mapNotNull(transform: (T) -> R?): List<R>
换句话说,transform
lambda 的参数类型是 T
,其中 T
是正在操作的 Iterable
的类型。在你的例子中,你的迭代是 List
类型 String?
.
因此,您需要将转换器声明为 (String?) -> String?
类型,并且只有该转换的非空结果才会包含在结果中。
为了更新您在 play.kotlinlang 上提供的代码,进行一些额外的修改以使类型声明更加地道——请注意,尽管有些奇怪,但我大部分都保留了代码原样使用附加 transform
函数:
val items = listOf<String?>(null, "cosa")
fun transform (transformer: (String?) -> String?): List<String> {
return items.mapNotNull(transformer)
}
fun main() {
val items = listOf<String?>(null, "cosa")
val transformer: (String?) -> String? = {
// this of course means the output of transform will always be empty
null
}
val map = transform(transformer)
print(map)
}
我正在尝试编写一个类似 transform
的函数,它接收一个将在 mapNotNull 内部使用的函数,但我找不到实现它的方法。
例子
val items: List<String?> = listOf(null, "cosa")
fun transform(transformer: (String) -> String?) {
items.mapNotNull(transformer) // <-------------------------------------- THIS DOES NOT COMPILE
}
fun main() {
val items: List<String?> = listOf(null, "cosa")
val transformer: (String) -> String? = {
null
}
val map = transform(transformer)
print(map)
}
您可以在此处查看其工作原理:play.kotlinlang
如何声明 fun transform
的参数才能在 mapNotNull
中传递它?
您有一个可为空字符串的列表。
mapNotNull
将变换函数应用于列表中的每个元素,然后检查此函数的结果是否为空。所以在这种情况下,它在 transformer
函数中传递了一个可为空的字符串,而该函数肯定不能是 (String) -> String?
类型,因为这里的参数是一个不可为空的字符串。
您应该将转换器函数声明为 (String?) -> String?
,或者在调用 mapNotNull
:
items.filterNotNull().mapNotNull(transformer)
另一种选择是将 transformer
包装到 lambda 函数中,然后再将其传递给 mapNotNull
并在那里处理空元素,例如:
items.mapNotNull { e -> e?.let(transformer) }
这仅在元素不为空时才将 transformer
函数应用于元素。
mapNotNull
函数定义为:
public inline fun <T, R : Any> Iterable<T>.mapNotNull(transform: (T) -> R?): List<R>
换句话说,transform
lambda 的参数类型是 T
,其中 T
是正在操作的 Iterable
的类型。在你的例子中,你的迭代是 List
类型 String?
.
因此,您需要将转换器声明为 (String?) -> String?
类型,并且只有该转换的非空结果才会包含在结果中。
为了更新您在 play.kotlinlang 上提供的代码,进行一些额外的修改以使类型声明更加地道——请注意,尽管有些奇怪,但我大部分都保留了代码原样使用附加 transform
函数:
val items = listOf<String?>(null, "cosa")
fun transform (transformer: (String?) -> String?): List<String> {
return items.mapNotNull(transformer)
}
fun main() {
val items = listOf<String?>(null, "cosa")
val transformer: (String?) -> String? = {
// this of course means the output of transform will always be empty
null
}
val map = transform(transformer)
print(map)
}