这是个bug吧?


#1
fun test(int: Int?): Int {
   int?.let { return int }
}

fun test(str: String?):String {
   str?.let { return str }
}

Kotlin 1.3 版本能通过编译,1.2版本无法通过编译


#2

int?.let {
这段代码已经判断不为空,理论上是没问题的


#3

感觉应该是BUG 我在AS上这样写可以编译通过 在IDEA上这样就编译不通过


#4

你在AS上用的Kotlin1.3版本,IDEA上面用的Kotlin1.2或更旧版本,是吧?


#5

你再想想,如果传入的参数是null,那程序会怎么跑


#6

int默认返回0,string默认返回null,如果获取string的length就会报错

@org.junit.Test
fun run(){
println(test(null).length)
}

private fun test(str: String?):String {
str?.let { return it }
}


#7

AS和IDEA都是用的1.3的版本


#8

正常来说应该编译不了吧?


#9

测试了,确实是个bug


#10

Kotlin 1.2 里 let 的代码如下:
public inline fun <T, R> T.let(block: (T) -> R ): R = block(this)

Kotlin 1.3 里 let 的代码如下:
public inline fun <T, R> T.let(block: (T) -> R ): R {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
return block(this)
}

在 1.3 版本里,新增 contract 确保了 let 一定会被执行一次,所以在编译的时候不会报错
“A ‘return’ expression required in a function with a block body (’{…}’)”

另外,在 1.3 版本里,这段代码如果传入参数为 null 的时候,返回值是 0


#11

并不是 bug,在 kotlin 1.3 版本里面,let 函数使用了 constract,编译器认为执行到 let { } 里面的代码的时候,str 已经不为 null,因此可以通过编译,而 1.2 版本没有此特性。

原来能编译,后来不能编译,才是 bug。

原来不能编译,后来能编译,不是 bug,是新特性。


#12

i?let{ return it }
从语义来说{}代码块在null的时候肯定不能被执行,所以这个例子整个函数有的分支没有return,应该编译不通过才对。
本来1.2中是合理的,但1.3的合约测试特效有bug导致这种情况可以被编译,此外,其实1.3的合约特性中其他bug还有不少,估计也是要过几个版本合约特性才能稳定。


#13

i?.let{…}
i后面有个问号,所以代码块还是不一定会被执行…所以这里确实是bug


#14

fun test(int: Int?): Int {
int?.let { return int }
return 1
}

fun testt(str: String?):String {
str?.let { return str }
return “jsd”
}


#15

张知识
三点水


京ICP备16022265号-2 Kotlin China 2017 - 2018