首页 文章

Kotlin类型推断失败

提问于
浏览
3

假设我们有一个具有这样类的第三方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仍然存在 .

1 回答

  • 4

    问题是Kotlin的一个错误 . 以下是该问题的链接:https://youtrack.jetbrains.com/issue/KT-14499 . 请投票 .

    UPD 要解决此问题,有一个解决方法:

    @JvmStatic
    fun main(args: Array<String>) {
        @Suppress("INACCESSIBLE_TYPE")
        callVoidFunc0(Functions.noOp())      // (1)
    
        @Suppress("INACCESSIBLE_TYPE")
        callVoidFunc1(Functions.noOp<Any>()) // (2)
    }
    

    要修复(1)必须禁止编译警告,修复(2) - 另外明确指定类型 .

相关问题