Dart中Switch语句与Set表达式相关的两个技术问题
Dart Switch模式匹配问题解答
示例代码
void main() { var list = [1, 2]; var set = <int>{1, 2}; var map = <int, int> {1: 2, 3: 4}; switch (list) { case 1: print(1); break; case [1, 2]: print(2); break; case const <int> {1, 2}: print(3); break; case <int, int>{1: 2, 3: 4}: print(4); break; } }
已知运行现象:
- 当switch表达式为
list时,控制台输出2; - 当switch表达式为
set时,无任何输出; - 当switch表达式为
map时,控制台输出4。
问题1:为何当switch表达式为set时,switch语句不输出3?
Dart的switch模式匹配里,case const <int>{1,2}属于常量模式,常量模式的匹配逻辑是对象恒等(===),而非内容相等(==)。
你定义的var set = <int>{1,2}是运行时创建的普通Set对象,而const <int>{1,2}是编译时生成的常量对象,两者是完全不同的实例,恒等判断不成立,所以这个case不会被匹配到,自然不会输出3。
问题2:为何Set在case模式中需要使用const修饰,而List和Map却不需要?移除Set case中的const会报错:“常量模式的表达式必须是有效的常量。”
核心原因是Dart的模式匹配语法对List、Map和Set的处理逻辑不同:
- 对于
[1,2]这种列表写法,它属于列表模式,是专门用来匹配List结构的模式,匹配逻辑是检查目标List的长度、对应位置元素是否匹配,不需要目标或模式本身是常量; - 对于
{1:2,3:4}这种Map写法,它属于映射模式,专门用来匹配Map的键值对结构,同样是检查内容匹配,不需要常量; - 但Dart目前没有专门的Set模式语法,当你在case里写
{1,2}时,它会被解析为常量模式,而常量模式要求表达式必须是编译时常量,所以必须加const修饰。如果去掉const,{1,2}是运行时创建的普通Set,不符合常量模式的要求,就会抛出“常量模式的表达式必须是有效的常量”的错误。
内容的提问来源于stack exchange,提问作者Anonymous
相关产品推荐
相关产品推荐

