我有一个域类型的元组,我想将其传递给一个泛型函数(在此示例中我使用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)
我想确保两个参数_ <: Any
和ct
的类型使用相同的参数类型T,我认为扩展类型应确保这一点,但似乎不起作用。
但是,如果我不使用元组,而只使用ClassTag,它将很好地工作:
o
因此,ClassTag不变性的先前错误没有道理。
为什么在使用元组时它不起作用?我该如何运作?
答案 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
)是不同的类型。
尝试使用通用量化而不是存在量化
_