Dart控制台游戏:无输入超时扣分及循环Stream报错问题求助
解决Dart控制台循环读取输入时的"Stream has already been listened to"错误
报错原因
stdin是单订阅流,只能被订阅一次。你在循环中每次调用stdin.transform(...).first时,都会尝试重新订阅这个已被订阅过的流,违反了单订阅流的规则,因此抛出Bad state: Stream has already been listened to错误。
修复原测试代码
使用stdin.readLineSync()替代流转换的方式,这个方法内部已处理流的订阅逻辑,支持直接设置超时,适合循环场景:
import 'dart:io'; void main() { for(var i = 0; i < 10; i++) { print('You have 5 seconds! WHAT IS YOUR NAME!!!!'); final name = stdin.readLineSync(timeout: const Duration(seconds: 5)); if (name == null) { print('LOL WUT DO YOUR NOT EVEN KNOW YOUR NAME!!!!'); } else { print('I knew it. Your name is $name!'); } } }
实现你的控制台游戏需求
针对"输入有效数字加分、超时未输入减分"的需求,调整后的完整代码如下:
import 'dart:io'; void main() { int score = 0; const totalRounds = 10; for (var round = 0; round < totalRounds; round++) { print('\nRound ${round + 1}/${totalRounds}'); print('Enter a number within 5 seconds! Current score: $score'); final input = stdin.readLineSync(timeout: const Duration(seconds: 5)); if (input == null) { // 超时未输入,分数减1 score--; print('Time\'s up! Score decreased by 1. Current score: $score'); } else { // 尝试解析输入为整数 final number = int.tryParse(input); if (number != null) { // 有效数字,分数加1 score++; print('Valid number! Score increased by 1. Current score: $score'); } else { // 输入不是有效数字,分数不变 print('Invalid input! Please enter a number. Score remains: $score'); } } } print('\nGame over! Final score: $score'); }
代码说明
- 使用
stdin.readLineSync(timeout: ...)实现带超时的输入读取,超时返回null - 用
int.tryParse()判断输入是否为有效数字,避免抛出解析异常 - 循环控制游戏轮次,每轮根据输入结果更新分数并反馈给用户
内容的提问来源于stack exchange,提问作者jessi cas
相关产品推荐
相关产品推荐

