Kotlin类型推断失败。

4

假设我们有一个第三方Java库,其中包含以下类:

//----------------------------------------------------------------------------------------

package foo;

public final class Functions {
  public interface VoidFunc0 {
    void call();
  }

  public interface VoidFunc1<T> {
    void call(T t);
  }

  @SuppressWarnings("unchecked")
  public static <T> NoOpFunc<T> noOp() {
    return new NoOpFunc();
  }

  /*public*/ static final class NoOpFunc<T> implements VoidFunc0, VoidFunc1<T> {
    @Override public void call() { /* deliberately no op */}
    @Override public void call(T t) { /* deliberately no op */ }
  }
}
//---------------------------------------------------------------------------------------- 

我们在Java应用程序中成功地使用了Functions.noOp()方法,但是当我们开始用Kotlin重写时,我们遇到了一个问题,下面的代码不能编译,并且给我们两个错误:

//----------------------------------------------------------------------------------------
package bar

import foo.Functions

object KotlinApp {
    @JvmStatic
    fun main(args: Array<String>) {
        /*
         * Error:(XX, XX) Kotlin: Type inference failed: Not enough information
         * to infer parameter T in fun <T : Any!> noOp(): Functions.NoOpFunc<T!>!
         * Please specify it explicitly.
         */
        callVoidFunc0(Functions.noOp()) // ERROR 1
        /*
         * Error:(XX, XX) Kotlin: Type Functions.NoOpFunc<Any!>! is inaccessible
         * in this context due to: Functions.NoOpFunc<Any!>!
         */
        callVoidFunc1(Functions.noOp()) // ERROR 2
    }

    fun callVoidFunc0(func0: Functions.VoidFunc0) {
        func0.call()
    }

    fun callVoidFunc1(func1: Functions.VoidFunc1<Any>) {
        func1.call("A")
    }
}
//---------------------------------------------------------------------------------------- 

但是之前用Java编写的相同代码能够编译并运行良好:

//----------------------------------------------------------------------------------------
package bar;

import foo.Functions;

public class JavaApp {
  public static void main(String[] args) {
    callVoidFunc0(Functions.noOp()); // OK
    callVoidFunc1(Functions.noOp()); // OK
  }

  public static void callVoidFunc0(Functions.VoidFunc0 func0) {
    func0.call();
  }

  public static void callVoidFunc1(Functions.VoidFunc1<Object> func1) {
    func1.call("A");
  }
}
//---------------------------------------------------------------------------------------- 

即使我们明确指定了T,类型推断仍然会失败。当将NoOpFunc声明为public时,错误2消失了,但是错误1仍然存在。


它无法推断T0的类型,实际上T0是Action0。Action0不是泛型,因此用于Action1Action2等。虽然这并没有回答你的问题。 - Dmitry Zaytsev
你需要让示例变得简短且自包含,不要引用外部代码链接。 - Jayson Minard
1个回答

4
问题是 Kotlin 中的一个 bug。 这里是问题链接:https://youtrack.jetbrains.com/issue/KT-14499。请投票。 更新: 为了解决这个问题,有一个解决方法:
@JvmStatic
fun main(args: Array<String>) {
    @Suppress("INACCESSIBLE_TYPE")
    callVoidFunc0(Functions.noOp())      // (1)

    @Suppress("INACCESSIBLE_TYPE")
    callVoidFunc1(Functions.noOp<Any>()) // (2)
}

要解决问题(1),必须抑制编译警告,要解决问题(2),此外还需显式指定类型。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接