You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Kotlin无法推断函数参数与返回类型的原因及Lambda示例代码编译问题解析

Hey there! Let's unpack your questions clearly, starting with the core type inference issue, then diving into your code examples.

Why can't Kotlin infer function parameter and return types in some cases?

Kotlin's type inference is smart, but it needs context to work its magic. When you assign a lambda to a variable without giving the variable an explicit type, the compiler hits a roadblock: it needs to know the lambda's parameter types to validate the code inside the lambda (like calling viewModel.updatePeople(it)), but without a target type or explicit parameter annotations, there's no way to figure out what it should be.

Think of it this way: if viewModel.updatePeople had multiple overloads (say, one taking an Int and another taking a String), how would the compiler know which one you mean? It can't—so it throws an error instead of guessing. This is a deliberate choice to avoid ambiguous code.

Breaking down your code snippets

Let's go through each example to see why some compile and others don't:

  • Code A: val onPeopleChanged: (Int) -> Unit = { viewModel.updatePeople(it) }
    You've explicitly told the compiler that onPeopleChanged is a function that takes an Int and returns Unit. This gives the lambda a clear "target type"—so the compiler knows it must be an Int. It can then confirm that viewModel.updatePeople accepts an Int, and since updatePeople returns Unit, everything lines up. No ambiguity, so it compiles perfectly.

  • Code B: val onPeopleChanged = { viewModel.updatePeople(it) }
    Without an explicit type for onPeopleChanged, the compiler has no clues about what it is. Is it an Int? A String? Something else? There's no context to answer that, so it can't validate whether viewModel.updatePeople(it) is a valid call. Hence, the compilation error.

  • Code C: val onPeopleChanged = {it -> viewModel.updatePeople(it) }
    This is just Code B with the parameter named explicitly instead of using the implicit it. The problem is still the same: you haven't told the compiler what type it is. Naming the parameter doesn't give any type information, so the compiler still can't resolve the ambiguity, leading to a failure.

  • Code D: val onPeopleChanged = {it:Int -> viewModel.updatePeople(it) }
    Here, you've annotated the lambda parameter it as an Int. Now the compiler knows exactly what type the lambda takes. It can check that viewModel.updatePeople accepts an Int, and since the lambda's body returns Unit (the return type of updatePeople), it can automatically infer that the lambda's type is (Int) -> Unit. That's why this code compiles without issues.

内容的提问来源于stack exchange,提问作者HelloCW

火山引擎 最新活动