Dart用户名校验while循环二次运行触发无限循环问题
问题根因
代码触发了Dart的**块级作用域变量遮蔽(Variable Shadowing)**逻辑,和你描述的现象完全吻合:
- 你在
main函数外层作用域第一次声明userName变量,存储首次输入的用户名。如果第一次输入的是Allan,while循环条件不成立,不会进入循环块,程序直接走到欢迎逻辑正常退出,这就是首次输入正确值能正常运行的原因。 while循环的大括号包裹的是独立的内层作用域,你在循环内部又用var重新声明了同名的userName变量,这个变量仅在循环块内部生效,和外层的userName完全是两个独立的变量。- 每次循环判断
userName != 'Allan'时,读取的永远是外层作用域里第一次输入的错误用户名,循环内读取的新输入值只会赋值给内层临时变量,根本不会修改外层用于判断的变量,所以无论后续输入什么内容,循环条件永远为真,就会进入无限循环,哪怕中途输入正确的Allan也无法终止。
另外你的代码还缺失了dart:io库的导入,直接运行会报stdin未定义的错误。
修复方案
核心修复逻辑是:不要在循环内重新声明同名变量,直接修改外层作用域的userName即可。
最小改动修复
只需要去掉循环内userName前的var关键字,同时补充缺失的IO库导入:
import 'dart:io'; void main() { print('Please enter the user name:'); var userName = stdin.readLineSync()!; while (userName != 'Allan') { print('Sorry that is not the correct user name. Please try Again'); // 移除var,直接给外层变量赋值,不声明新的同名局部变量 userName = stdin.readLineSync()!; } print('Hey $userName welcome'); }
精简写法
可以把输入逻辑合并到循环条件中,减少重复代码:
import 'dart:io'; void main() { String? userName; print('Please enter the user name:'); while ((userName = stdin.readLineSync()) != 'Allan') { print('Sorry that is not the correct user name. Please try Again'); } print('Hey $userName welcome'); }
注意:Dart中在代码块内用
var/final/类型名声明的变量都遵循块级作用域规则,内层作用域声明的同名变量不会覆盖外层变量,只会在内层暂时遮蔽外层同名变量,这是从函数作用域语言(比如旧版JS的var)转Dart时非常容易踩的坑。
内容的提问来源于stack exchange,提问作者A-Commons
相关产品推荐
相关产品推荐

