Kotlin重复调用函数至满足条件的代码编译问题咨询
问题解答
1. 是否能返回非空Puppy?
完全可以。invokeUntil的逻辑是循环调用代码块直到拿到符合条件的结果,只要我们在函数内部确保返回的结果必然非空且满足校验条件,编译器就能识别出返回值是Puppy而非Puppy?,不需要额外的显式转型。
2. 代码修正方案
以下是修正后的完整代码,完全满足无额外大括号、无显式类型转换/指定的要求:
data class Puppy(val name: String) // 修正后的invokeUntil函数 fun <T> invokeUntil(block: () -> T?, condition: (T) -> Boolean): T { while (true) { val result = block() // 同时校验非空和条件,确保返回的result是符合要求的非空T if (result != null && condition(result)) { return result } } } // 修正后的isNotNull判断器 val isNotNull: (Any) -> Boolean = { it != null } fun main() { val puppy: Puppy = invokeUntil( block = { if (Math.random() > 0.5) Puppy("Buddy") else null }, condition = isNotNull ) println(puppy.name) }
关键修改点说明
invokeUntil函数签名调整:- 让
block返回T?(允许临时返回空值),而condition接收非空的T作为参数,这样编译器能明确condition处理的是已通过非空校验的值,解决了类型推断不足的问题。 - 返回类型改为
T,因为函数内部只会返回经过result != null校验的结果,编译器能确认这个返回值绝对非空,解决了类型不匹配的问题。
- 让
isNotNull调整:- 定义为
(Any) -> Boolean类型的lambda,既能适配任意类型的非空判断,又能让编译器自动推断invokeUntil的泛型参数T为Puppy,不需要显式指定。
- 定义为
内容的提问来源于stack exchange,提问作者Gromov Anton
相关产品推荐
相关产品推荐

