如何将元组的扩展类型传递给不变的泛型函数?

时间:2019-08-30 18:22:39

标签: scala generics typeclass covariance existential-type

我有一个域类型的元组,我想将其传递给一个泛型函数(在此示例中我使用ClassTag,但是它是具有不变类型参数的自定义类型类):

Firestore db = firestore();

Future <List<String>> getString() async {

var dataList = new List<String>();

var result = await db.collection('Users').get();
result.forEach((doc) {
    dataList.add(doc.get('First name'));
  });

debugPrint(dataList.first);

return dataList;
}

这给了我错误:

  错误:类型不匹配;    找到:scala.reflect.ClassTag [T]    必需:scala.reflect.ClassTag [Any]   注意:T <:任意,但是特征ClassTag在T类型中是不变的。   您可能希望研究通配符类型,例如type TC = (ClassTag[T], Option[T]) forSome {type T} def foo[T](ct: ClassTag[T], o: Option[T]) = {} val tc: TC = (classTag[String], Option[String](null)) foo(tc._1, tc._2) 。 (SLS 3.2.10)          foo(tc._1,tc._2)

我想确保两个参数_ <: Anyct的类型使用相同的参数类型T,我认为扩展类型应确保这一点,但似乎不起作用。

但是,如果我不使用元组,而只使用ClassTag,它将很好地工作:

o

因此,ClassTag不变性的先前错误没有道理。

为什么在使用元组时它不起作用?我该如何运作?

1 个答案:

答案 0 :(得分:2)

对于val tc: TC = classTag[String], Option[String](null))tc._1的类型为ClassTag[_](与其他ClassTag[T]不同,例如ClassTag[Any],因为ClassTag是不变的),{{ 1}}的类型为tc._2,与Option[_]相同,因为Option[Any]是协变的

Option
  

其中implicitly[Option[_] =:= Option[Any]] implicitly[Option[Any] =:= Option[_]] 包含子句类型? forSome { ? }的存在类型?等同于?[tps]>:?<:?的类型?′ forSome { ? }?′产生的类型用{{1}替换??的每个协变出现,并用?替换??的每个协变出现。

https://www.scala-lang.org/files/archive/spec/2.13/03-types.html#existential-types

所以在

?

我们的类型不匹配。 ?def foo[T](ct: ClassTag[T], o: Option[T]) = {} foo(tc._1, tc._2) (又称任意Any)是不同的类型。

尝试使用通用量化而不是存在量化

_