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

制作大型网站电商网站多少钱

制作大型网站,电商网站多少钱,wordpress后台编辑主题时提示:抱歉_该文件无法被编辑,注册网站在哪里注册文章目录 闭包使用闭包来简化代码传统函数实现 闭包实现闭包的类型推导结构体中的闭包捕获作用域中的值三种 Fn 特征闭包作为函数返回值 闭包 闭包是一种匿名函数#xff0c;它可以赋值给变量也可以作为参数传递给其它函数#xff0c;不同于函数的是#xff0c;它允许捕获调… 文章目录 闭包使用闭包来简化代码传统函数实现 闭包实现闭包的类型推导结构体中的闭包捕获作用域中的值三种 Fn 特征闭包作为函数返回值 闭包 闭包是一种匿名函数它可以赋值给变量也可以作为参数传递给其它函数不同于函数的是它允许捕获调用者作用域中的值例如 fn main() {let x 1;let sum |y| x y;assert_eq!(3, sum(2)); }上面的代码展示了非常简单的闭包 sum它拥有一个入参 y同时捕获了作用域中的 x 的值因此调用 sum(2) 意味着将 2参数 y跟 1x进行相加,最终返回它们的和3。 可以看到 sum 非常符合闭包的定义可以赋值给变量允许捕获调用者作用域中的值。 使用闭包来简化代码 传统函数实现 想象一下我们要进行健身用代码怎么实现,这里是我的想法 use std::thread; use std::time::Duration;// 开始健身好累我得发出声音muuuu... fn muuuuu(intensity: u32) - u32 {println!(muuuu.....);thread::sleep(Duration::from_secs(2));intensity }fn workout(intensity: u32, random_number: u32) {if intensity 25 {println!(今天活力满满先做 {} 个俯卧撑!,muuuuu(intensity));println!(旁边有妹子在看俯卧撑太low再来 {} 组卧推!,muuuuu(intensity));} else if random_number 3 {println!(昨天练过度了今天还是休息下吧);} else {println!(昨天练过度了今天干干有氧跑步 {} 分钟!,muuuuu(intensity));} }fn main() {// 强度let intensity 10;// 随机值用来决定某个选择let random_number 7;// 开始健身workout(intensity, random_number); }可以看到在健身时我们根据想要的强度来调整具体的动作然后调用 muuuuu 函数来开始健身。这个程序本身很简单没啥好说的但是假如未来不用 muuuuu 函数了是不是得把所有 muuuuu 都替换成比如说 woooo 如果 muuuuu 出现了几十次那意味着我们要修改几十处地方。 闭包实现 use std::thread; use std::time::Duration;fn workout(intensity: u32, random_number: u32) {let action || {println!(muuuu.....);thread::sleep(Duration::from_secs(2));intensity};if intensity 25 {println!(今天活力满满先做 {} 个俯卧撑!,action());println!(旁边有妹子在看俯卧撑太low再来 {} 组卧推!,action());} else if random_number 3 {println!(昨天练过度了今天还是休息下吧);} else {println!(昨天练过度了今天干干有氧跑步 {} 分钟!,action());} }fn main() {// 动作次数let intensity 10;// 随机值用来决定某个选择let random_number 7; FnOnce该类型的闭包会拿走被捕获变量的所有权。Once 顾名思义说明该闭包只能运行一次// 开始健身workout(intensity, random_number); }在上面代码中无论你要修改什么只要修改闭包 action 的实现即可其它地方只负责调用完美解决了我们的问题 Rust 闭包在形式上借鉴了 Smalltalk 和 Ruby 语言与函数最大的不同就是它的参数是通过 |parm1| 的形式进行声明如果是多个参数就 |param1, param2,…| 下面给出闭包的形式定义 |param1, param2,...| {语句1;语句2;返回表达式 }闭包的类型推导 与函数相反闭包并不会作为 API 对外提供因此它可以享受编译器的类型推导能力无需标注参数和返回值的类型。 下面展示了同一个功能的函数和闭包实现形式 fn add_one_v1 (x: u32) - u32 { x 1 } let add_one_v2 |x: u32| - u32 { x 1 }; let add_one_v3 |x| { x 1 }; let add_one_v4 |x| x 1 ;虽然类型推导很好用但是它不是泛型当编译器推导出一种类型后它就会一直使用该类型 let example_closure |x| x;let s example_closure(String::from(hello)); let n example_closure(5);首先在 s 中编译器为 x 推导出类型 String但是紧接着 n 试图用 5 这个整型去调用闭包跟编译器之前推导的 String 类型不符因此报错 error[E0308]: mismatched types-- src/main.rs:5:29| 5 | let n example_closure(5);| ^| || expected struct String, found integer // 期待String类型却发现一个整数| help: try using a conversion method: 5.to_string() 结构体中的闭包 假设我们要实现一个简易缓存功能是获取一个值然后将其缓存起来那么可以这样设计 一个闭包用于获取值一个变量用于存储该值 可以使用结构体来代表缓存对象最终设计如下 struct CacherT whereT: Fn(u32) - u32, {query: T,value: Optionu32, }特征 Fn(u32) - u32 从表面来看就对闭包形式进行了显而易见的限制该闭包拥有一个u32类型的参数同时返回一个u32类型的值。 接着为缓存实现方法 implT CacherT whereT: Fn(u32) - u32, {fn new(query: T) - CacherT {Cacher {query,value: None,}}// 先查询缓存值 self.value若不存在则调用 query 加载fn value(mut self, arg: u32) - u32 {match self.value {Some(v) v,None {let v (self.query)(arg);self.value Some(v);v}}} } 上面的缓存有一个很大的问题只支持 u32 类型的值若我们想要缓存 str 类型显然就行不通了因此需要将 u32 替换成泛型 E该练习就留给读者自己完成具体代码可以参考这里 捕获作用域中的值 在之前代码中我们一直在用闭包的匿名函数特性赋值给变量然而闭包还拥有一项函数所不具备的特性捕获作用域中的值。 fn main() {let x 4;let equal_to_x |z| z x;let y 4;assert!(equal_to_x(y)); }上面代码中x 并不是闭包 equal_to_x 的参数但是它依然可以去使用 x因为 equal_to_x 在 x 的作用域范围内。 对于函数来说就算你把函数定义在 main 函数体中它也不能访问 x fn main() {let x 4;fn equal_to_x(z: i32) - bool {z x}let y 4;assert!(equal_to_x(y)); }报错如下 error[E0434]: cant capture dynamic environment in a fn item // 在函数中无法捕获动态的环境-- src/main.rs:5:14| 5 | z x| ^| help: use the || { ... } closure form instead // 使用三种 Fn 特征 FnOnce该类型的闭包会拿走被捕获变量的所有权。Once 顾名思义说明该闭包只能运行一次 fn fn_onceF(func: F) whereF: FnOnce(usize) - bool, {println!({}, func(3));println!({}, func(4)); }fn main() {let x vec![1, 2, 3];fn_once(|z|{z x.len()}) }FnMut它以可变借用的方式捕获了环境中的值因此可以修改该值 fn main() {let mut s String::new();let update_string |str| s.push_str(str);update_string(hello);println!({:?},s); }Fn 特征它以不可变借用的方式捕获环境中的值 让我们把上面的代码中 exec 的 F 泛型参数类型修改为 Fn(a str) fn main() {let mut s String::new();let update_string |str| s.push_str(str);exec(update_string);println!({:?},s); }fn execa, F: Fn(a str)(mut f: F) {f(hello) }闭包作为函数返回值 但是如果要使用闭包作为函数返回值该如何做 先来看一段代码 fn factory() - Fn(i32) - i32 {let num 5;|x| x num }let f factory();let answer f(1); assert_eq!(6, answer);上面这段代码看起来还是蛮正常的用 Fn(i32) - i32 特征来代表 |x| x num非常合理嘛肯定可以编译通过, 可惜理想总是难以照进现实编译器给我们报了一大堆错误先挑几个重点来看看 fn factoryT() - Fn(i32) - i32 {| ^^^^^^^^^^^^^^ doesnt have a size known at compile-time // 该类型在编译器没有固定的大小Rust 要求函数的参数和返回类型必须有固定的内存大小例如 i32 就是 4 个字节引用类型是 8 个字节总之绝大部分类型都有固定的大小但是不包括特征因为特征类似接口对于编译器来说无法知道它后面藏的真实类型是什么因为也无法得知具体的大小。 同样我们也无法知道闭包的具体类型该怎么办呢再看看报错提示 help: use impl Fn(i32) - i32 as the return type, as all return paths are of type [closuresrc/main.rs:11:5: 11:21], which implements Fn(i32) - i32| 8 | fn factoryT() - impl Fn(i32) - i32 {嗯编译器提示我们加一个 impl 关键字哦这样一说读者可能就想起来了impl Trait 可以用来返回一个实现了指定特征的类型那么这里 impl Fn(i32) - i32 的返回值形式说明我们要返回一个闭包类型它实现了 Fn(i32) - i32 特征。 完美解决但是在特征那一章我们提到过impl Trait 的返回方式有一个非常大的局限就是你只能返回同样的类型例如 fn factory(x:i32) - impl Fn(i32) - i32 {let num 5;if x 1{move |x| x num} else {move |x| x - num} }运行后编译器报错 error[E0308]: if and else have incompatible types-- src/main.rs:15:9| 12 | / if x 1{ 13 | | move |x| x num| | ---------------- expected because of this 14 | | } else { 15 | | move |x| x - num| | ^^^^^^^^^^^^^^^^ expected closure, found a different closure 16 | | }| |_____- if and else have incompatible types|嗯提示很清晰if 和 else 分支中返回了不同的闭包类型这就很奇怪了明明这两个闭包长的一样的好在细心的读者应该回想起来本章节前面咱们有提到就算签名一样的闭包类型也是不同的因此在这种情况下就无法再使用 impl Trait 的方式去返回闭包。 只需要用 Box 的方式即可实现 fn factory(x:i32) - Boxdyn Fn(i32) - i32 {let num 5;if x 1{Box::new(move |x| x num)} else {Box::new(move |x| x - num)} } 至此闭包作为函数返回值就已完美解决若以后你再遇到报错时一定要仔细阅读编译器的提示很多时候转角都能遇到爱。
http://www.sadfv.cn/news/78811/

相关文章:

  • 桂林相关网站包头市建设工程质量监督站网站
  • 邯郸网站建设选哪家好采集侠 wordpress
  • 美食网站建设的功能全球咨询公司排名
  • 做漂亮的二维码网站wordpress数组
  • 哪些网站可以做视频直播为某公司或企业做的门户网站
  • 网站设计内容做任务给钱的网站
  • 如何做网站结构分析湖北工程建设信息网官网
  • 网站开发小程序开发公司公司网站建设行为规定
  • 网站运营外包鲜花电子商务网站建设规划书
  • 青岛博海建设集团有限公司网站临夏网站制作
  • 单页面网站怎么优化阿里云 wordpress 建站
  • 河南省建设招投标网站电子商务网站设计怎么做
  • CMS网站建设实战试题网络论坛有些什么平台
  • 常州手机网站效果深圳品牌网站开发
  • 模仿大型门户网站做ppt做自媒体小视屏哪个网站好
  • 江门网站推广网页设计市场价
  • 为企业开发网站网页设计工资怎么样
  • 手机能用的网站流程图
  • asp做的网站数据库在哪里wordpress中front-page
  • 郑州企业网站排名优化自己搭建云手机服务器
  • 哪个网站可以免费做网页制作网架厂家
  • 企业的网站用vue做的买了个域名 如何建网站
  • 云商城是什么网站加载优化
  • 上海网站建设在哪里郓城那家网站做的好
  • 开发一个网站大概多少钱重庆 建网站
  • 安徽太基建设官方网站成都品牌形象设计公司
  • 用个人的信息备案网站吗手机网站建设需要多少钱
  • 公司做网站的费用怎么做账网站建设冖金手指花总十四
  • 深圳网站开发公网站上添加图片的原则
  • 网站建设及空间推进门户网站建设 用好用活