2016-10-20 1 views
3

Disons que nous avons une 3ème partie bibliothèque Java avec cette classe:inférence de type Kotlin n'a pas

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

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 */ } 
    } 
} 
//---------------------------------------------------------------------------------------- 

Nous avons utilisé avec succès sa méthode Functions.noOp() dans notre application Java, mais quand nous avons commencé à réécrire dans Kotlin, nous face à la question que le code ci-dessous ne compile pas et nous donne deux erreurs:

//---------------------------------------------------------------------------------------- 
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") 
    } 
} 
//---------------------------------------------------------------------------------------- 

mais le même code déjà écrit en Java compile et fonctionne bien:

//---------------------------------------------------------------------------------------- 
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"); 
    } 
} 
//---------------------------------------------------------------------------------------- 

L'inférence de type échoue même si nous spécifions explicitement T. L'erreur 2 disparaît lorsque NoOpFunc est déclaré comme public, mais l'erreur 1 reste toujours.

+0

'Il ne peut pas déduire le type de T0 qui est réellement Action0' -' Action0' n'est pas générique, donc 'T0' est utilisé pour' Action1', 'Action2', etc. Cela ne répond pas à votre question. –

+0

Vous devez rendre l'échantillon petit et autonome, sans faire référence à un lien de code externe. –

Répondre

4

Le problème est un bug dans Kotlin. Voici le lien vers le numéro: https://youtrack.jetbrains.com/issue/KT-14499 S'il vous plait, votez.

UPD Pour résoudre ce problème, il y a une solution de contournement:

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

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

Pour fixer (1), il faut supprimer l'avertissement de compilation, de fixer (2) - préciser en outre le type explicitement.