我对Rust和一般的编程都是新手。我正在尝试创建一个非常简单的猜数字游戏在命令行中.
目前,用户必须给出一个范围来猜测,但我也想给出一个默认选项。以前我有这个函数只是要求范围。
下面是尝试给出默认范围选项的情况。
fn get_range() -> Vec<i32> {
println!("Press C for custom range or any key for default range");
println!("Custom range");
println!("Default range [0,10]");
for line in stdin().lock().lines() {
if line.unwrap().to_lowercase() == "c" {
loop {
let range_start: i32 = {
println!("\nStart of range:");
get_user_number().unwrap()
};
let range_end: i32 = {
println!("\nEnd of range (end is inclusive):");
get_user_number().unwrap()
};
if range_start < range_end {
return (range_start..=range_end).collect();
} else {
println!("\nThe start of the range must be a lower number than the end!")
}
}
} else {
return (0..=10).collect();
}
}
(0..=10).collect()
}
然而,由于某种原因,请求自定义范围的循环一旦在if语句中就停止正常工作,我也试图 Package 在函数中,但也不起作用。结果是它打印了Start of range
,然后就停在那里了,之后什么都不工作了。
其他问题:
1.如果我删除函数(0..=10).collect()
末尾的最后一条语句。我在 * for * 循环开始时从Rust分析器中得到这些错误。
1.不匹配的类型expected struct Vec<i32>
found unit type ()
在循环没有要迭代的元素的情况下返回一个值,或者考虑更改返回类型以解决这种可能性[E0308]
1.函数期望总是返回一个值,但循环可能运行零次[E0308]
for循环中的所有内容不都返回Vec<i32>
吗?为什么类型不匹配?
1.如果我删除else选项,那么默认选项就不起作用。我不理解这一点,因为 * if * 语句只在用户键入C时发生。否则,它会跳过if并到达函数的末尾,在那里返回Vec<i32>
。为什么我必须显式地放置一个 * else * 语句?
这是整个文件,如果你想要更多的上下文。请注意,get_range()
函数是直接请求范围而不是提供默认选项的原始版本。
最后,对于小型项目的构建有哪些建议?我的下一个是一个简单的Neofetch类程序,它提供一些系统信息。我对命令行工具和底层的东西很感兴趣,比如内核和操作系统(但是构建内核或操作系统对我的技能来说还很遥远,希望有一天能实现:)
1条答案
按热度按时间nlejzf6q1#
for循环中的所有内容不都返回一个Vec吗?为什么类型不匹配?
编译器研究了如果
stdin().lock().lines()
中没有行会发生什么。在这种情况下,for循环将永远不会执行,但for循环是一个表达式,并且根据“Programming Rust(Revised 2nd Edition)”,p.一百四十三:循环是Rust中的表达式[这意味着它们有一个可以赋值给变量的值],但是while或for循环的值总是
()
,所以它们的值不是很有用。这意味着编译器将整个for循环替换为
()
。类似的事情发生在这里:for循环从未执行过,但其计算结果为
()
。因此,如果stdin().lock().lines()
中没有行,您的for循环将被跳过,它将计算为()
,并且您的函数最终返回()
。但是,你告诉编译器你的函数返回一个向量:()
不是向量因此,不匹配的类型等。添加行:在for循环之后,意味着如果跳过for循环,你的函数将不再返回
()
,这会使编译器关闭。如果我删除else选项,那么默认选项就不起作用。我不明白这一点,因为if语句只在用户键入c时发生。否则,它将跳过if并到达函数的末尾,在那里返回Vec。为什么我必须显式地添加else语句?
这又和表情有关。
if
是一个表达式,这意味着它产生一个可以赋值给变量的值,例如:根据“Programming Rust(Revised 2nd Edition)”,p.一百三十八:
...如果没有else,则必须始终返回
()
。这意味着一个返回某些值的
if expression
也必须有一个返回相同类型的else
分支。下面是一个与该规则相冲突的示例:输出:
“Programming Rust Revised 2nd”中所述的规则实际上 * 意味着 *:
...没有else的if必须总是[求值为]
()
。...因为下面的代码编译时没有错误:
输出:
显然,
if expression
内部的return
被不同地对待。根据“Programming Rust(Revised 2nd Edition)”,p.一百四十六:与
break
表达式类似,return
可以放弃正在进行的工作。有趣的是,下面的代码也不会产生任何错误:
而且,编译器推断
result
的类型为()
。因此,要么赋值将被返回中断,并且永远不会发生,要么如果x
不等于2
,则if将计算为()
-因为“没有else的if必须始终[计算为]()
”-并且该值将被赋值为result
。让用户只按Return键来获取默认范围,或者输入两个数字来定制范围,这不是更简单吗?
在The Rust Programming Language中有一个
Guess The Number
示例程序,您可能想看看。最后,有没有什么建议,让小项目建设?
你熟悉exercism.org吗?您可以注册Rust曲目(免费),然后您将被分配一系列程序来完成。如果你有一个github帐户(免费),你可以无缝下载并提交你完成的程序。当您下载作业时,会有一套您的程序必须通过的测试--这些测试充当您作业的规范。在您提交解决方案之后,导师将检查您的程序并提出改进建议,直到您迭代地得出最终解决方案。然后你进入下一个程序。