问题描述
我似乎无法理解为什么 mySet 变量被推断为具有动态参数类型的泛型集,当我清楚地将它等同于一个 int 集文字时.那么这个结果是合乎逻辑的还是 dart 真的无法推断泛型集参数类型?
main(){设置 mySet = {1 ,2 , 3};var myProducts = {1:'电视',2:'冰箱',3:mySet.lookup(2),4:'平板电脑',5:'计算机'};var userCollection = {"name":"John Smith","Email":"[email protected]"};myProducts.forEach((x,y) => print("${x} : ${y}"));userCollection.forEach((k, v) => print("${k} : ${v}"));}
如果你声明一个具有泛型类型 Generic
的变量但省略了参数化类型,它是 (通常是) Generic
的简写.推理确实发生在你的作业中,但不是你期望的方向:因为你明确声明了 mySet
的类型,{1, 2, 3 的类型}
是从那个显式类型 (Set
/Set
) 推断出来的,变成 {1, 2, 3}
而不是 {1, 2, 3}
.
这就是为什么最好省略显式类型而只允许在可能的情况下推断类型的原因之一.使用:
var mySet = {1, 2, 3};
允许将 mySet
推断为 Set
.如果你真的想使用显式类型,你应该确保你也为泛型类型参数指定了显式类型.
您可以通过设置来捕获此类错误:
分析器:语:严格原始类型:true
在您的 analysis_options.yaml
文件中.(您可能还希望启用:
分析器:强模式:隐式转换:false隐式动态:假
也是.)
另见https://github.com/dart-lang/language/blob/master/resources/type-system/strict-raw-types.md:
void main() {列表 a = [1, 2, 3];}
开发者通常认为推理是从赋值的右侧填入a
的类型.它可能看起来像 a
的类型 List
.但是 Dart 填充省略的类型参数,例如 List
上的 E
,带有 dynamic
(或相应类型参数的绑定);List a;
纯粹是 List 的简写.一个;
.推理然后从 a
流向赋值右侧的表达式.
严格来说,如果泛型的类型参数受到约束(例如 class Generic
),则省略类型参数是使用该约束的简写(即,Generic
是 Generic
的简写).大多数泛型不限制它们的类型参数,因此它通常以动态
结束.
I can't seem to understand why the mySet variable is being inferred as a generic set with dynamic parameter type, when I clearly equated it to an int set literal. So is this result logical or has dart genuinely failed to infer the generic sets parameter type?
main(){
Set mySet = {1 ,2 , 3};
var myProducts = {
1:'TV',2:'Refrigerator',
3:mySet.lookup(2),
4:'Tablet',
5:'Computer'
};
var userCollection = {"name":"John Smith","Email":"[email protected]"};
myProducts.forEach((x,y) => print("${x} : ${y}"));
userCollection.forEach((k, v) => print("${k} : ${v}"));
}
If you declare a variable with a generic type Generic
but omit the parameterized type, it's (usually) shorthand for Generic<dynamic>
. Inference does happen in your assignment, but not in the direction you expect: since you explicitly declared the type of mySet
, the type of {1, 2, 3}
is inferred from that explicit type (Set
/Set<dynamic>
) and becomes <dynamic>{1, 2, 3}
instead of <int>{1, 2, 3}
.
This is one reason why it can be better to omit explicit types and just allow types to be inferred when possible. Using:
var mySet = {1, 2, 3};
would allow mySet
to be inferred as Set<int>
. If you really want to use explicit types, you should ensure that you specify explicit types for generic type parameters too.
You can catch such errors by setting:
analyzer:
language:
strict-raw-types: true
in your analysis_options.yaml
file. (You also might wish to enable:
analyzer:
strong-mode:
implicit-casts: false
implicit-dynamic: false
too.)
Also see https://github.com/dart-lang/language/blob/master/resources/type-system/strict-raw-types.md:
Strictly speaking, if a generic's type parameter is constrained (e.g. class Generic<T extends Base>
), then omitting the type parameter is shorthand for using that constraint (i.e., Generic
would be shorthand for Generic<Base>
). Most generics don't constraint their type parameters, so therefore it usually ends up being dynamic
.
这篇关于为什么 dart 错误地推断出我的泛型参数类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!