我有一个java函数:
public static void initialize(@NonNull Activity activity, Settings... settings) {}
Run Code Online (Sandbox Code Playgroud)
我想从kotlin叫它:
fun initialize(activity: Activity, vararg settings: settings) = JavaClass.initialize(activity, settings)
Run Code Online (Sandbox Code Playgroud)
但它没有编译,告诉我有类型不匹配,Settings是必需的,但争论是kotlin.Array<out Settings>
我看到它试图将它与signture相匹配
public static void initialize(@NonNull Activity activity, Settings settings) {}
Run Code Online (Sandbox Code Playgroud)
但我想用
public static void initialize(@NonNull Activity activity, Settings[] settings) {}
Run Code Online (Sandbox Code Playgroud)
Mic*_*ael 17
您应该使用以下语法:
fun initialize(activity: Activity, vararg settings: settings) =
JavaClass.initialize(activity, *settings)
Run Code Online (Sandbox Code Playgroud)
https://kotlinlang.org/docs/reference/java-interop.html#java-varargs
Nic*_*ler 10
迈克尔的回答是正确的,但我想发表一些额外的评论。
究其原因,你不能传递一个科特林vararg参数成期待另一个Java(或科特林)函数vararg是因为编译器解析vararg成Array。
因此,就好像您已将函数声明如下(从函数的内部作用域的角度来看):
fun initialize(activity: Activity, settings: Array<Settings>) = //...
Run Code Online (Sandbox Code Playgroud)
这就是为什么我们需要使用扩展*运算符是不直观的。据我所知,这种设计选择有两个好处:
除了用于填充变量参数之外,扩展运算符还可用于在单个参数和扩展数组之间进行混合匹配。这意味着 Kotlin 为我们提供了一种向vararg列表添加额外参数的便捷方式。
在 Java 中,以下代码无法编译:
Settings[] settings = //...
Setting myAdditionalSetting = new Setting();
JavaClass.initialize(activity, settings, myAdditionalSetting); //Compiler Error
Run Code Online (Sandbox Code Playgroud)
但是,在 Kotlin 中,我们可以这样做:
JavaClass.initialize(activity, *settings, myAdditionalSetting)
Run Code Online (Sandbox Code Playgroud)第二个好处是增加了安全性。扩展运算符编译为一个调用,Arrays.copyOf()该调用保证扩展值的不变性。i这确保被调用的函数不会破坏原始数组。
i:虽然实际的类引用是不可变的,但它们引用的对象可能仍然是可变的。
| 归档时间: |
|
| 查看次数: |
3895 次 |
| 最近记录: |