当前位置: 首页 > wzjs >正文

佛山北京网站建设wordpress动态标题

佛山北京网站建设,wordpress动态标题,wordpress花园教程,怎样生成网页链接【0】准备 【1】构文・整数・变量 【2】 if・Panic・演练 ←前次 【3】可变性・循环・溢出 本次 这是“100 Exercise To Learn Rust”的第三次练习!这次是关于两个循环结构的讨论,可能与上上次练习中讨论的溢出有关! 本次相关的页面如下&…

【0】准备
【1】构文・整数・变量 
【2】 if・Panic・演练 ←前次 
【3】可变性・循环・溢出 本次

这是100 Exercise To Learn Rust的第三次练习!这次是关于两个循环结构的讨论,可能与上上次练习中讨论的溢出有关!

本次相关的页面如下:

  • 2.6. Loops: while
  • 2.7. Loops: for
  • 2.8. Overflow and underflow

那么让我们开始吧

[02_basic_calculator/06_while] while

  • 2.6. Loops: while

问题如下

// Rewrite the factorial function using a `while` loop.
pub fn factorial(n: u32) -> u32 {// The `todo!()` macro is a placeholder that the compiler// interprets as "I'll get back to this later", thus// suppressing type errors.// It panics at runtime.todo!()
}#[cfg(test)]
mod tests {use crate::factorial;#[test]fn first() {assert_eq!(factorial(0), 1);}#[test]fn second() {assert_eq!(factorial(1), 1);}#[test]fn third() {assert_eq!(factorial(2), 2);}#[test]fn fifth() {assert_eq!(factorial(5), 120);}
}

上一次,我们用递归方式编写了计算阶乘的代码,这次的任务似乎是要将其改写为使用 while 循环的方式。

todo! 宏还未实现,并且在代码执行到这里时会引起 panic。可能在未来的某个练习中会处理这个宏。因为 todo! 宏具有一种特殊的性质,即它可以返回与函数返回类型相同的值,所以它通常不会导致编译错误。

无论如何,看起来我们需要将这部分代码替换成 while 循环。

解説

pub fn factorial(n: u32) -> u32 {let mut res = 1;let mut i = 1;while i <= n {res *= i;i += 1;}res
}

我真的很想用 for 循环来写这段代码……因为平时并不会这么勉强地使用 while 循环,所以这次反而让我有点手忙脚乱了……

在这个问题中出现了两个新的要素:

  1. while 循环
  2. mut 关键字

看起来这节内容顺便引入了“可变性”这个概念。实际上,这个关键词经常在类似的循环结构中使用,所以这也是很合理的。

在 Rust 中,所有变量默认都是不可变的。除非有意为之,否则这种不可变性会贯穿到结构体、引用、数组等各种情况中。值不变的特性可以为阅读代码的人带来安心感,从而避免诸如“这个函数是否以可变引用传递了变量?”这样的多余猜测,进而实现更清晰明确的编码风格。

然而,当一切都是不可变的时,有时会显得不方便,其中一个典型例子就是循环中的变量。为了应对这种情况,当你想要使用可变变量时,可以使用 mut 关键字。通过这个关键字,你可以明确地告知代码的阅读者:“这个变量可能会因为副作用而发生变化”。

让我们回到 while 循环的讨论上来。(就像 if 表达式一样),除了条件部分没有被括号包围之外,while 循环与其他语言并没有太大区别。与 if 表达式不同,while 循环在被评估后不会立即确定返回值,因此它不具有表达式的性质(伏笔)。

没有 i++ 吗?

在 Rust 中没有增量运算符 (++)。我想这可能就是原因 。

本质上,i++ 这一单行语句做的事情太多了。由于 Rust 语言不太喜欢“偷懒”的语法(在引入新特性时非常谨慎),所以故意没有提供类似的运算符。

[02_basic_calculator/07_for] for

  • 2.7. Loops: for

终于可以用 for 循环来写代码了...!

// Rewrite the factorial function using a `for` loop.
pub fn factorial(n: u32) -> u32 {todo!()
}#[cfg(test)]
mod tests {use crate::factorial;#[test]fn first() {assert_eq!(factorial(0), 1);}#[test]fn second() {assert_eq!(factorial(1), 1);}#[test]fn third() {assert_eq!(factorial(2), 2);}#[test]fn fifth() {assert_eq!(factorial(5), 120);}
}

 阶乘真是个优秀的题目,可以作为这么多问题的练习题...

解説

pub fn factorial(n: u32) -> u32 {let mut res = 1;for i in 1..=n {res *= i;}res
}

通过将循环变量的作用域限制在 for 循环内,代码比使用 while 循环更加简洁!由于 i 不需要 mut 关键字,因此保证了在每个循环中 i 是不可变的,这一点非常好。

不过,仍然有一个可变变量 res 存在……如果采用类似迭代器的写法(例如使用 map或 reduce等),甚至可以去掉这个可变变量。

这与后面可能会涉及到的“迭代器”有关,1..=5 是生成 1, 2, 3, 4, 5Range 类型的值,并不是 for 循环所特有的语法。for 循环的语法实际上是 for 变量 in 迭代器 {},它从 Range 类型等迭代器中逐个取出元素进行处理。

loop 表达式

whilefor 不返回值,因此它们不是表达式。然而,loop 表达式可以返回值(这也是之前提到的伏笔)。

loop 表达式写作 loop {},它意味着 while true {},即一个无限循环的专用语法。

由于 loop 是专用于无限循环的,所以必须使用 break 才能退出,因此通过使用 break 可以返回一个值。

let mut i = 0;let res = loop {if i == 10 {break i;}println!("{}", i);i += 1;
};println!("{}", res);

通过 break i; 退出循环时,作为表达式返回了 i 的值!

……不过,我认为使用的机会应该不多。我只是觉得这是一个有趣的语法,所以介绍一下。

[02_basic_calculator/08_overflow] オーバーフロー

  • 2.8. Overflow and underflow

 问题如下

// Customize the `dev` profile to wrap around on overflow.
// Check Cargo's documentation to find out the right syntax:
// https://doc.rust-lang.org/cargo/reference/profiles.html
//
// For reasons that we'll explain later, the customization needs to be done in the `Cargo.toml`
// at the root of the repository, not in the `Cargo.toml` of the exercise.pub fn factorial(n: u32) -> u32 {let mut result = 1;for i in 1..=n {result *= i;}result
}#[cfg(test)]
mod tests {use crate::factorial;#[test]fn twentieth() {// 20! is 2432902008176640000, which is too large to fit in a u32// With the default dev profile, this will panic when you run `cargo test`// We want it to wrap around insteadassert_eq!(factorial(20), 2_192_834_560);//                           ☝️// A large number literal using underscores to improve readability!}#[test]fn first() {assert_eq!(factorial(0), 1);}#[test]fn second() {assert_eq!(factorial(1), 1);}#[test]fn third() {assert_eq!(factorial(2), 2);}#[test]fn fifth() {assert_eq!(factorial(5), 120);}
}

刚才的问题答案已经写出来了……!

虽然这问题有点难以理解,但看起来问题的意思是:“20! = 2432902008176640000 这个结果太大了,会导致溢出并引发 panic,所以请通过修改 Cargo.toml 的设置,避免出现 panic!”

解説

在项目的 Cargo.toml 文件中(不是 exercises 内各个问题的 Cargo.toml,而是项目根目录下的 Cargo.toml文件),需要添加一个设置,用来在发生溢出时忽略它。

[workspace]
members = ["exercises/*/*", "helpers/common", "helpers/mdbook-exercise-linker", "helpers/ticket_fields"]
resolver = "2"+ [profile.dev]+ overflow-checks = false

……不,这也太勉强了吧……?!顺便提一下,在 dev(调试构建)中,overflow-checks 的默认值是 true,而在 release(发布构建)中,默认值是 false。在 AtCoder上选择 Rust 进行解答时,实际上是进行发布构建,所以在本地(调试构建)时由于溢出导致运行时错误(RE),但提交后显示为错误答案(WA),这是一个很容易让人出错的陷阱。这实际上是由于不同构建配置中的默认值造成的。

应对溢出的办法有很多。在 AtCoder 上回答时,通常会取模,例如使用 10e9+7 这样的素数,而我在学习密码学时,常常使用“有限体”,这种方法保证了所有计算结果都落在一个有限的集合(体)内。

虽然在这个问题中我们并没有使用素数取模的方式,这可能会影响运算的一致性,但本题的测试用例看起来像是实现了溢出后重新从 0 开始计数(wrap around)。考虑到这点,我尝试了另一种避免编辑 Cargo.toml 并避免溢出的解决方案。

pub fn factorial(n: u32) -> u32 {let mut result = 1u32;for i in 1..=n {result = result.wrapping_mul(i);}result
}

总结

使用 u32::wrapping_mul可以让运算在溢出时自动 wrap around,从而通过测试!在源代码中明确说明已经考虑了溢出处理,这样就不需要每次查看 Cargo.toml 了,这会更方便。

那么,让我们进入下一个问题吧!

下一篇文章:【4】类型转换与结构体(有时涉及 UFCS)


文章转载自:

http://bonneFTk.qnxzx.cn
http://odmwTSye.qnxzx.cn
http://GHmIQWyC.qnxzx.cn
http://4iucEGLI.qnxzx.cn
http://JMRUm9US.qnxzx.cn
http://HIzpWZCA.qnxzx.cn
http://owf1Qpo5.qnxzx.cn
http://t6Pgtrdt.qnxzx.cn
http://LTn4pixc.qnxzx.cn
http://BnXZM1M6.qnxzx.cn
http://elTgPhAK.qnxzx.cn
http://HWHDyiAU.qnxzx.cn
http://oZaAOnvd.qnxzx.cn
http://oG23YMM6.qnxzx.cn
http://lEL2HHXd.qnxzx.cn
http://B0Pt5Rjc.qnxzx.cn
http://26yuLxmg.qnxzx.cn
http://eqhF1lZT.qnxzx.cn
http://G3tVwviO.qnxzx.cn
http://zYuhpboR.qnxzx.cn
http://J5n21TOt.qnxzx.cn
http://DExUYrrp.qnxzx.cn
http://3aVCMwtg.qnxzx.cn
http://KjYDLeMb.qnxzx.cn
http://MnPJhRcQ.qnxzx.cn
http://vKG5sCCY.qnxzx.cn
http://xZJ4QhG3.qnxzx.cn
http://05oV1RSK.qnxzx.cn
http://R9i2LMcN.qnxzx.cn
http://t6ZNqpTg.qnxzx.cn
http://www.dtcms.com/wzjs/737304.html

相关文章:

  • 大型网站制作软件免费移动网站建站
  • 阳泉住房和城乡建设厅网站广州市网络科技有限公司
  • 兴宁市住房和城乡规划建设局网站阿里云备案域名购买
  • 电商网站建设 问题与解决方案网站调用网页怎么做
  • 淘宝客必须做网站国内推广平台
  • 网站seo诊断分析巴南区网站建设
  • php做网站速成厦门网站建设厦门
  • 网站源码酒类磁力帝
  • 淘宝禁止了网站建设类网站运营存在的问题
  • 货源网站开发网站设计影响seo的因素
  • 佛山模板网站建站番禺区画册设计公司
  • 南通网站建设知识浙江建设厅网站查询
  • 重庆网站建设推荐google chrome官网入口
  • 主机做网站服务器吗济南网站搜索引擎优化
  • 网站建设营销外包公司排名网站建设优化服务价位
  • 龙游县住房和城乡建设局网站公众号文章模板素材
  • 湖北省建设工程招标网站字体设计网站大全
  • 宁夏城乡和住房建设厅网站韩国做暖暖网站
  • 网站模块插件是怎么做的WORDPRESS网站如何改版
  • 天河建设网站系统电子商务包括哪些
  • 如何建立一个网站根目录wordpress播放页
  • 福州最好的网站设计服务公司电商运营怎么做如何从零开始
  • 科技公司网站制作模板百度seo是啥
  • 鹧鸪哨网站1v1深度开发网站店铺建设
  • 查找网站域名网站建设的作用是什么
  • 传统企业公司网站优化案例无锡专业网站建设
  • 网站备案怎么做超链接海口网站开发师招聘
  • 网站软件app美术馆网站建设
  • 网站建设公司代理商网站颜色
  • 提供给他人做视频解析的网站源码杂粮网站建设的必要性