实用 AI

可在线运行 AI 集合,涵盖 AI 文案生成、写作辅助、AI 绘图与照片修复、AI 配音、字幕生成、语音转录以及 AI 视频创作和数字人等多种 AI 服务

查看详情

Kotlin Contracts 契约机制

深入学习Kotlin基础知识
2022-07-07 10:47 · 阅读时长6分钟

Kotlin Contracts是kotlin 1.3推出的一个新特性,它主要作用是进一步提升kotlin编译器的智能转换(smartcasts)能力,先看看下面这个示例。

加载中...

这样很符合逻辑,其实这背后是kotlin编译器帮我们做了智能转换,但是并不是所有的情况编译器都能这样默默的处理了,比如说,我们把判空处理放在另外一个独立的方法中。

加载中...

仅仅是把功能封装成了一个单独的方法,之前的智能转换功能居然不生效了,这对于开发者来说很容易推断出s可以转换为String类型而不是String?,但是对于编译器来说却比较麻烦,为了增强这类场景kotlin编译器的智能转换能力,所以推出了Contracts机制。

我们将以上代码判断字符串的部分改为kotlin标准库中的扩展方法isNullOrBlank,则可以顺利编译通过。

加载中...
通过声明函数调用的结果与所传参数值之间的关系来改进智能转换分析

下面是isNullOrBlank方法的定义,从定义中我们可以看出它使用了Contracts机制。

加载中...

后面是正常的判空处理,重点是contract这一段代码,它代表合约的内容:如果方法返回true,表明字符串实例不是null。编译器可以根据这个约定来决定是否可以将字符串s实例从String?类型转换为String类型。我们将上面提到编译出错的代码改动一下,使用Contracts机制来帮助编译器完成智能转换。

加载中...

除了returns(value) implies(condition)这种形式,还有以下几种。

  • returns() implies(condition),如果方法调用正常返回,则表明condition成立。
  • returnsNotNull() implies(condition),如果方法返回值不为null,则表明condition成立。
在存在高阶函数的情况下改进变量初始化的分析

除了能够帮助编译器智能转换以外,Contracts机制还能帮助编译器在存在高阶函数时,判断一个变量是否初始化。先看看下面示例,因为编译器无法判断变量是否会初始化,所以导致编译出错。

加载中...

从开发者角度来看,这个x = 42这行代码会执行一次,也就是说x会在println方法之前赋值,但是对于编译器来说,它却不能很智能的知道这个情况,所以就出现了编译错误。在ContractBuilder中还定义了方法callsInPlace,用于提示编译器传入高阶函数中的表达式的执行情况。

比如说上面的代码,如果我们使用Contracts机制提示编译器,block会被执行一次,那么它就能够知道x变量会在println方法之前被赋值,也就不会出现编译错误了。

加载中...
kotlincontract契约合约smartcasts