【问题标题】:Lambda argument should be moved out of parentheses应将 Lambda 参数移出括号
【发布时间】:2020-05-12 22:00:08
【问题描述】:

IntelliJ 提出以下投诉:

Lambda 参数应移出括号

val profile = loadProfiles()
profile.sortedWith(Comparator({ profile1, profile2 ->
                if (profile1.age > profile2.age) return@Comparator 1
                if (profile1.age < profile2.age) return@Comparator -1
                return@Comparator 0
            }))

data class Developer(var age: Int)

fun loadProfiles(): List<Developer> {
    val listOfNumber = listOf<Developer>(Developer(2), Developer(5), Developer(3))

    return listOfNumber
}

我应该如何格式化以上内容以消除投诉?此外,排序代码不会排序。是什么导致了问题?

【问题讨论】:

  • 您可能还对profile.sortedBy { it.age } 感兴趣...另请注意,它不是对基础列表进行排序,而是返回一个新的排序列表。
  • ...我的意思是:Alt + Enter 或点击灯泡让 Intellij 为您解决该问题...

标签: kotlin


【解决方案1】:

这个警告是因为在 Kotlin 中 lambda 参数可以(并且实际上应该)在括号之外。

看这个:

fun onClick(action: () -> Unit) { ... }

当你使用这样的功能时,你可以使用:

view.onClick({ toast(it.toString())} )
view.onClick() { toast(it.toString()) }
view.onClick { toast(it.toString()) }

所有这些形式都是正确的(编译器不会失败),但在 Kotlin Style Guide 你会发现以下语句:

如果调用采用单个 lambda,则应将其传递到外部 尽可能使用括号。

@见https://kotlinlang.org/docs/reference/coding-conventions.html#lambda-formatting

这就是 IntelliJ 显示警告的原因。您可以按 Alt+Enter 并且 IntelliJ 应该显示正确的解决方案,或者只是将 lambda 移出括号。如果 lambda 只是参数,也请删除括号。

什么时候 lambda 必须在括号中?仅当它不是函数中的最后一个参数时。

【讨论】:

    【解决方案2】:

    sortedWith():返回根据排序的所有元素的列表 指定[比较器]

    所以要对profile 列表进行排序,您必须将sortedWith() 返回的列表分配给profile(也将其声明从val 更改为var

    var profile = loadProfiles()
    profile = profile.sortedWith(Comparator { profile1, profile2 ->
        if (profile1.age > profile2.age) return@Comparator 1
        if (profile1.age < profile2.age) return@Comparator -1
        return@Comparator 0
    })
    
    profile.forEach { println(it.age) }
    

    val profile = loadProfiles().sortedWith(Comparator { profile1, profile2 ->
        if (profile1.age > profile2.age) return@Comparator 1
        if (profile1.age < profile2.age) return@Comparator -1
        return@Comparator 0
    })
    

    对于警告:按 Alt+Enter 并让 InteliJ 进行更改。

    【讨论】:

      【解决方案3】:

      至于你眼前的问题,你只需要这样写:

      profile.sortedWith(Comparator { profile1, profile2 ->
                  if (profile1.age > profile2.age) return@Comparator 1
                  if (profile1.age < profile2.age) return@Comparator -1
                  return@Comparator 0
              }
      )
      

      但是,代码仍然有几层不必要的冗长。这里有一些方法可以使它更简洁、更易读。

      1. 删除return 声明:

        profile.sortedWith(Comparator { profile1, profile2 ->
            if (profile1.age > profile2.age) 1
            else if (profile1.age < profile2.age) -1
            else 0
        })
        
      2. 使用when 而不是if-else 级联:

        profile.sortedWith(Comparator { profile1, profile2 ->
            when {
                profile1.age > profile2.age -> 1
                profile1.age < profile2.age -> -1
                else -> 0
            }
        })
        
      3. 使用Int.compareTo:

        profile.sortedWith(Comparator { profile1, profile2 ->
            profile1.age.compareTo(profile2.age) 
        }
        
      4. 使用compareBy:

        profile.sortedWith(compareBy(Profile::age))
        
      5. 当你只需要sortedBy时,不要使用通用的sortedWith

        profile.sortedBy(Profile::age)
        

      【讨论】:

      • 或更好(我认为).sortedBy { it.age }
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-01-25
      • 1970-01-01
      • 1970-01-01
      • 2020-05-10
      • 1970-01-01
      • 2011-12-16
      • 1970-01-01
      相关资源
      最近更新 更多