0

我有代码:

shared Integer getInt() {
    return 42;
}

shared Integer() i1() {
    return getInt;
}

shared Callable<Integer,Nothing> i2() {
    return getInt;
}

shared Callable<Integer,[]> i3() {
    return getInt;
}

void run() {
    // OK
    i1()();
    // Illegal `[] is not assignable to Nothing`
    i2()();
    // OK
    i3()();
}

我不确定为什么编译器可以使用“i2”声明。Nothing 是一切的子类型,因此是空元组的子类型,所以我可以理解为什么我可以进行声明。但是一旦我这样做了,我似乎不可能正常调用“i2”,因为没有参数调用它,空元组,意味着用锡兰拒绝的它想要的超类型调用它。那么有没有可能调用getInt从i2返回的?

4

2 回答 2

1

让我们稍微修改一下您的示例。

shared Integer getInt(Integer x) {
    return 42 + x;
}

shared Integer(Integer) i1() {
    return getInt;
}

shared Callable<Integer,Nothing> i2() {
    return getInt;
}

shared Callable<Integer,[Integer]> i3() {
    return getInt;
}

正如您所提到的,它Nothing是 的子类型[],因为它是所有事物的子类型。它也是 的子类型[Integer]

类型Callable<Integer, Nothing>描述任何返回的函数Integer。然而,它并没有说它不需要争论。

可以调用从 中返回的函数函数i2,但您需要先对其进行类型检查:

val gi = i2();
if(is Callable<Integer, [Integer, Integer]> gi) {
     gi(1,2);
}

上面的例子很好,因为[Integer, Integer]是可赋值的[Integer],因此Callable<Integer, [Integer]>是可赋值的Callable<Integer, [Integer, Integer]>,因为 的第二个类型参数Callable是逆变的。

于 2016-12-29T06:00:43.837 回答
1

Callable<Integer, Nothing>是合法的,因为第二个类型参数必须满足Anything[],这Nothing是因为,就像你说的,它是每种类型的子类型。但是这样的函数永远不能被调用,因为它需要一个 的实例Nothing,并且不存在这样的实例。

你可以这样做apply(i2(), nothing),这让类型检查器很高兴,但当然这只会在运行时爆炸,因为nothing它是一个不存在的东西的占位符。

于 2016-12-29T06:06:39.753 回答