咱们好,之前项目预备升级到kotlin插件最新版别,所以对于kotlin1.5.0及以上特性进行了一番了解,发现kotlin官方为了进步部分注解的运用体验,做了不少的优化工作,这儿就带咱们了解下这些注解,希望能帮助你进一步提升对Kotlin的认知。

一. @BuilderInference注解根本认知

这个注解咱们可能有些生疏,但在日常开发中肯定运用过用其实现的扩展函数,比方buildList{}构建调集:

优化@BuilderInference注解,Kotlin高版本下了这些“毒手”!

咱们一般这样运用:

优化@BuilderInference注解,Kotlin高版本下了这些“毒手”!

能够看到buildList{}运用时不必显现指定办法泛型类型就完成了主动揣度,靠的便是@BuilderInference注解,接下来咱们详细的讲一讲。

二. @BuilderInference注解根本运用

咱们先看一段官方源码解说:

优化@BuilderInference注解,Kotlin高版本下了这些“毒手”!

简略来说,这个注解便是帮助编译器从办法函数类型的参数调用中揣度真正的泛型类型,这句话说起来比较绕,比方下面这个比如:

class BuildAction<T> {
    var sth : T? = null
    fun action(t: T){
        sth = t
    }
}
fun <T> test100(@BuilderInference block: BuildAction<T>.() -> Unit): T? {
    val sth = BuildAction<T>()
    sth.block()
    return sth.sth
}

当咱们运用test100()办法时,能够不需求传递详细的泛型类型,而是编译器直接从函数类型参数block的接收者BuildAction办法的调用中直接揣度该类型

优化@BuilderInference注解,Kotlin高版本下了这些“毒手”!

能够看到,上面的截图中不显现指定泛型类型就揣度出了test100()办法的泛型为StringbuildList{}构建调集同样是这个原理,能够说@BuilderInference注解非常的好用。

可是该注解在1.5.30及以下有个约束

优化@BuilderInference注解,Kotlin高版本下了这些“毒手”!

也便是说,在办法函数类型block中:你只能经过调用办法显现传入对应的泛型类型参数才干揣度办法类型,而无法经过调用的办法的返回值来揣度函数类型,说起来仍是绕口,咱们直接举个比如,先给上面的BuildAction类直接添加一个返回值为泛型类型的办法:

class BuildAction<T> {
    //...
    fun obtain(): T {
        return sth!!
    }
}

然后咱们持续调用下test100()办法:

优化@BuilderInference注解,Kotlin高版本下了这些“毒手”!

直接就进行报错了,即无法经过调用办法并显现声明办法的返回值来揣度test100函数的泛型类型,这对咱们日常的运用仍是不太便利的。

终究kotlin1.5.30出手了

三. kotlin1.5.30增强@BuilderInference注解功用

优化@BuilderInference注解,Kotlin高版本下了这些“毒手”!

只需求添加一个compile option:-Xunrestricted-builder-inference, 或许在kotlinOption中添加一个装备字段: -language-version 1.6,都能免除上面的约束,这儿咱们运用第一种:

  1. 首先在build.gradle脚本中添加下面的装备:

优化@BuilderInference注解,Kotlin高版本下了这些“毒手”!

  1. 持续测验下上面的代码看下还会不会报错;

优化@BuilderInference注解,Kotlin高版本下了这些“毒手”!

能够看到不报错了,而且正确揣度出了test100办法的泛型类型为String

经过这么一波优化,@BuilderInference注解愈加强壮、愈加便利了,可是咱们不觉得揣度办法泛型类型为啥每次都要写这么一个注解,多麻烦,编译器就不能主动帮助咱们这种辨认运用场景并进行办法泛型类型揣度吗?

kotlin1.6.0出手了,下面咱们讲讲这个版别做了啥优化。

四. kotlin1.6.0去除@BuilderInference显现声明

先上一波官方截图:

优化@BuilderInference注解,Kotlin高版本下了这些“毒手”!

这段话咱们需求关注的有两点:

  1. 当项目kotlin插件升级到1.6.0及以上版别,揣度函数泛型类型(即上面解说的经过函数类型内的办法返回值类型揣度)不必添加-Xunrestricted-builder-inference这个compiler option,编译器默许启动该特性;
  2. 新增-Xenable-builder-inference这个compiler option,以后根据办法函数类型参数揣度办法泛型类型就不必再添加@BuilderInference注解了

接下来咱们稍微改造下上面的比如测验下:

  1. 调整build.gradle中compiler option装备:

优化@BuilderInference注解,Kotlin高版本下了这些“毒手”!

  1. 改造下上面的test100()办法,去除@BuilderInference注解:

优化@BuilderInference注解,Kotlin高版本下了这些“毒手”!

  1. 调用test100()测验:

优化@BuilderInference注解,Kotlin高版本下了这些“毒手”!

没有进行任何的报错,完美解决了@BuilderInference注解需求显现声明的问题。

五. 总结

经过上面的解说,核心点首要如下:

  1. 1.5.30及以下经过-Xunrestricted-builder-inference这个compiler option增强@BuilderInference注解功用,实现经过办法函数类型参数中内部所调用的办法返回值类型来揣度办法泛型类型;

  2. 1.6.0及以上,默许实现-Xunrestricted-builder-inference对应增强的功用,无需显现声明这个compiler option,而且经过声明-Xenable-builder-inference这个compiler option,不必再显现声明@BuilderInference注解了;

谢谢咱们观看。


本文正在参加「金石计划」