本文主要是介绍Flutter 的 switch 语句补遗,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
我的 App 里,一个消息气泡变成空白了,非常奇怪,此前一直是没问题的,经过调试定位我发现:
static TextSpan _buildRootSpan(BuildContext ctx, List<LinkifyElement> parts, TextStyle? style) {List<InlineSpan> children = [];for (var p in parts) {switch (p.runtimeType) {case TextElement _:children.add(TextSpan(text: p.text));break;case UrlElement _:var url = p as UrlElement;var recognizer = TapGestureRecognizer();recognizer.onTap = () {AutoRouter.of(ctx).push(WebRoute(targetUrl: url.url));};children.add(TextSpan(text: url.text,style: TextStyle(color: Theme.of(ctx).colorScheme.secondary,decoration: TextDecoration.underline,decorationColor: Theme.of(ctx).colorScheme.secondary,),recognizer: recognizer,));break;}}return TextSpan(style: style,children: children,);}
问题出在这段代码里,最后的 TextSpan 返回的内容是空的。怎么会如此呢?从没改过这段代码。加了很多 Log 后,我发现,Switch 语句的所有 case 都没命中!我对 p.runtimeType
进行 switch 判断,但是明明类型没错,但是就是不命中。
问了一下 ChatGPT,给出了明确答案:
在 Dart 中,你不能直接在 switch
语句中对类型进行判断,因为 switch
语句要求其表达式的结果必须是编译时常量,而类型检查(使用 is
关键字)不满足这个条件。但是,你可以使用一些替代方案来根据对象的类型执行不同的逻辑。
一种常见的做法是使用 if
语句和 is
类型检查操作符,像这样:
void performAction(Object obj) {if (obj is TypeA) {// 处理 TypeA} else if (obj is TypeB) {// 处理 TypeB} else {// 处理其他类型}
}
另一种方法是使用 Dart 2.15 引入的 switch
和 case
语法的增强特性,结合枚举和 when
函数(如果你定义了一个这样的函数),你可以模仿类型判断的行为。虽然这不是直接的类型判断,但它允许你在相似的上下文中根据不同的条件执行不同的代码块,特别是当你处理的是固定集合中的值时。
如果你真的需要根据类型来分支逻辑,使用 if
-is
检查可能是最直接和最清晰的方式。 Dart 的类型系统和 is
操作符非常强大,可以满足大多数需要类型判断的场景。
说实在的,我觉得我穿越了,代码一直是这样的,也没改过,功能正常也好多个版本了,怎么突然就跟我说,dart 压根不支持对类型进行 switch 这不是搞笑么???
改成 if
和 is
后,立刻全部正常了,我服了。引以为戒吧。
又查了点资料,感觉跟 3.0 新语法有关: Dart 3.0 语法新特性 | switch 匹配加强
这篇关于Flutter 的 switch 语句补遗的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!