假设我有这个 java 示例:
interface Sink<T> {
void accumulate(T t);
}
public static <T> void drainToSink(Collection<T> collection, Sink<? super T> sink) {
collection.forEach(sink::accumulate);
}
注意第二个参数是如何声明的? super T
。我需要这个,因为我想这样调用该方法:
Sink<Object> sink = .... // some Sink implementation
Collection<String> strings = List.of("abc");
drainToSink(strings, sink);
现在我正试图用 kotlin 来实现同样的目标(我对它的经验很少):
interface Sink<T> {
fun accumulate(t: T)
}
fun <T> drainToSink(collection: List<T>, sink: Sink<T>) {
....
}
现在我正在尝试使用它:
fun main(args: Array<String>) {
val sink = object : Sink<Any> {
override fun accumulate(any: Any) { }
}
val strings = emptyList<String>()
drainToSink(strings, sink)
}
有趣的是,这并没有失败(除非我在这里对 kotlin 知之甚少)。
我真的希望我需要在声明中添加一些东西,比如Sink<in T>
让编译器知道这实际上只是一个Consumer
,或者in T
默认情况下总是打开?
比我更了解 kotlin 的人能指出我正确的方向吗?