7.2.3 动态类型

原文链接: https://kotlinlang.org/docs/dynamic-type.html

7.2.3 动态类型

注意: 面向 JVM 的代码不支持动态类型。

作为静态类型语言,Kotlin 仍然需要与无类型或弱类型的环境(例如 JavaScript 生态)互操作。为方便这些用例,语言中提供了 dynamic 类型:

1
val dyn: dynamic = ...

dynamic 类型基本上会关闭 Kotlin 的类型检查器:

  • dynamic 类型的值可以赋给任何变量,或作为参数传给任何地方。
  • 任何值都可以赋给 dynamic 类型的变量,或传给接受 dynamic 参数的函数。
  • 对 dynamic 类型的值会禁用 null 检查。

dynamic 最奇特的地方在于,我们可以对 dynamic 变量调用任何属性或函数,并传入任何参数:

1
2
dyn.whatever(1, "foo", dyn) // 'whatever' 在任何地方都没有定义
dyn.whatever(*arrayOf(1, 2, 3))

在 JavaScript 平台上,这段代码会"原样"编译:Kotlin 中的 dyn.whatever(1) 会变成生成的 JavaScript 代码中的 dyn.whatever(1)。

在 dynamic 类型的值上调用用 Kotlin 编写的函数时,请注意 Kotlin 到 JavaScript 编译器所做的名称改编。你可能需要用 @JsName 注解为你需要调用的函数指定明确的名称。

动态调用总是返回 dynamic 作为结果,因此你可以自由地链式调用:

1
dyn.foo().bar.baz()

当你把 lambda 传给动态调用时,它的所有参数默认都是 dynamic 类型:

1
2
3
dyn.foo {
    x -> x.bar() // x 是 dynamic
}

使用 dynamic 类型值的表达式会被"原样"转换为 JavaScript,不使用 Kotlin 的运算符约定。支持以下运算符:

  • 二元:+、-、*、/、%、>、< >=、<=、==、!=、===、!==、&&、||
  • 一元
  • 前缀:-、+、!
  • 前缀和后缀:++、--
  • 赋值:+=、-=、*=、/=、%=
  • 索引访问:
  • 读取:d[a],多于一个参数会报错
  • 写入:d[a1] = a2,[] 中多于一个参数会报错

禁止对 dynamic 类型的值使用 in、!in 和 .. 操作。

更技术性的描述请参阅规范文档。