在下面的代码中,有两种方法可以使用静态方法和使用成员函数。它们都使用泛型,但成员函数只是将所有工作委托给静态版本。问题是编译器做了不同的类型推断。
我问过非常相似的问题,但我的解释很糟糕:wrong type inference with generics。
class channel<S,Y> {
static flatMapImpl<T,R>(self: channel<any, T>, projector:(t:T) => channel<T,R>) {
var ch = new channel<T, R>();
return ch;
}
public flatMap<R>(projector: (data: Y) => channel<Y, R>) {
return channel.flatMapImpl(this, projector);
}
public merge2(...targets: channel<any, Y>[]) {
var ch = new channel<void, channel<any, Y>>().named('merge');
var r = channel.flatMapImpl(ch, x => x); // fine !
return r;
}
public merge(...targets: channel<any, Y>[]) {
var ch = new channel<void, channel<any, Y>>().named('merge');
var result = ch.flatMap(x => x); // <-- compilation error
return result;
}
}
看看code = flatMap是通过flatMapImpl实现的,并且具有相同的返回类型。 merge具有几乎相同的代码,唯一的区别是flatMap和flatMapImpl。
问题是 - 为什么第二个版本无法编译以及如何修复它?
当然,我可以设置一些注释,但实际上,成员函数是主要的用例。这意味着我将不得不在每次通话时加注注释等。