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

建设银行缴费网站登录莱芜金点子传媒电子版

建设银行缴费网站登录,莱芜金点子传媒电子版,西部数码网站开发管理助手,如何通过c语言来做网站随着项目的进展#xff0c;关于Rust的故事又翻开了新的一页#xff0c;今天来到了服务器端的开发场景#xff0c;发现错误处理中的错误类型转换有必要分享一下。 Rust抽象出来了ResultT,E#xff0c;T是返回值的类型#xff0c;E是错误类型。只要函数的返回值的类…随着项目的进展关于Rust的故事又翻开了新的一页今天来到了服务器端的开发场景发现错误处理中的错误类型转换有必要分享一下。 Rust抽象出来了ResultT,ET是返回值的类型E是错误类型。只要函数的返回值的类型被定义为ResutT,E那么作为开发人员就有责任来处理调用这个函数可能发生的错误。通过ResultT,ERust其实给开发人员指明了一条错误处理的道路使代码更加健壮。 场景 服务器端处理api请求的框架Rocket服务器端处理数据持久化的框架tokio_postgres 在api请求的框架中我把返回类型定义成了ResultT, rocket::response::status::Custom\String即错误类型是rocket::response::status::Custom\String。 在tokio_postgres中直接使用tokio_postgres::error::Error。 即如果要处理错误就必须将tokio_postgres::error::Error转换成rocket::response::status::Custom\String。那么我们从下面的原理开始逐一领略Rust的错误处理方式通过对比找到最合适的方式吧。 原理 对错误的处理Rust有3种可选的方式 使用match使用if let使用map_err 下面我结合场景逐一演示各种方式是如何处理错误的。 下面的代码中涉及到2个模块文件。/src/routes/notes.rs是路由层负责将api请求导向合适的service。/src/services/note_books.rs是service层负责业务逻辑和数据持久化的处理。这里的逻辑也很简单就是route层调用service层将数据写入到数据库中。 使用match src/routes/notes.rs #[post(/api/notes, format application/json, data note)] pub async fn post_notes(note: JsonNote) - Result(), rocket::response::status::CustomString {insert_or_update_note(note.into_inner()).await }/src/services/note_book.rs pub async fn insert_or_update_note(note: Note, ) - Result(), rocket::response::status::CustomString {let (client, connection) match connect(hostlocalhost dbnamenotes_db userpostgres port5432,NoTls,).await{Ok(res) res,Err(err) {return Err(rocket::response::status::Custom(rocket::http::Status::ExpectationFailed,format!({}, err),));}};...match client.execute(insert into notes (id, title, content) values($1, $2, $3);,[get_system_seconds(), note.title, note.content],).await{Ok(res) Ok(()),Err(err) Err(rocket::response::status::Custom(rocket::http::Status::ExpectationFailed,format!({}, err),)),} } 通过上面的代码我们可以读出一下内容 在service层定义了route层相同的错误类型在service层将持久层的错误转换成了route层的错误类型使用match的代码量还是比较大 使用if let /src/services/note_book.rs pub async fn insert_or_update_note(note: Note, ) - Result(), rocket::response::status::CustomString {if let Ok((client, connection)) connect(hostlocalhost dbnamenotes_db userpostgres port5432,NoTls,).await{...if let Ok(res) client.execute(insert into notes (id, title, content) values($1, $2, $3);,[get_system_seconds(), note.title, note.content],).await{Ok(())} else {Err(rocket::response::status::Custom(rocket::http::Status::ExpectationFailed,format!({}, unknown error),))}} else {Err(rocket::response::status::Custom(rocket::http::Status::ExpectationFailed,format!({}, unknown error),))} }src/routes/notes.rs #[post(/api/notes, format application/json, data note)] pub async fn post_notes(note: JsonNote) - Result(), rocket::response::status::CustomString {insert_or_update_note(note.into_inner()).await }使用了if let ...代码更加的别扭并且在else分支中拿不到具体的错误信息。 其实不难看出我们的目标是将api的请求经过route层和service层将数据写入到数据中。但这其中的错误处理代码的干扰就特别大甚至要有逻辑嵌套现象。这种代码的已经离初衷比较远了是否有更加简洁的方式使代码能够最大限度的还原逻辑本身把错误处理的噪音降到最低呢 答案肯定是有的。那就是map_err map_err map_err是Result上的一个方法专门用于错误的转换。下面的代码经过了map_err的改写看上去是不是清爽了不少啊。 /src/services/note_book.rs pub async fn insert_or_update_note(note: Note, ) - Result(), rocket::response::status::CustomString {let (client, connection) connect(hostlocalhost dbnamenotes_db userpostgres port5432,NoTls,).await.map_err(|err| {rocket::response::status::Custom(rocket::http::Status::ExpectationFailed,format!({}, err),)})?;...let _ client.execute(insert into notes (id, title, content) values($1, $2, $3);,[get_system_seconds(), note.title, note.content],).await.map_err(|err| {rocket::response::status::Custom(rocket::http::Status::ExpectationFailed,format!({}, err),)})?;Ok(()) }src/routes/notes.rs #[post(/api/notes, format application/json, data note)] pub async fn post_notes(note: JsonNote) - Result(), rocket::response::status::CustomString {insert_or_update_note(note.into_inner()).await }经过map_err改写后的代码代码的逻辑流程基本上还原了逻辑本身但是map_err要额外占4行代码且错误对象的初始化代码存在重复。在实际的工程项目中service层的处理函数可能是成百上千如果再乘以4那多出来的代码量也不少啊这会给后期的维护带来不小的压力。 那是否还有改进的空间呢答案是Yes。 Rust为我们提供了FromT trait用于类型转换。它定义了从一种类型T到另一种类型Self的转换方法。我觉得这是Rust语言设计亮点之一。 但是Rust有一个显示即实现FromT trait的结构必须有一个在当前的crate中也就是说我们不能直接通过FromT来实现从tokio_postgres::error::Error到rocket::response::status::CustomString。也就是说下面的代码编译器会报错。 impl Fromtokio_postgres::Error for rocket::response::status::CustomString {}报错如下 32 | impl Fromtokio_postgres::Error for rocket::response::status::CustomString {}| ^^^^^---------------------------^^^^^----------------------------------------| | | || | | rocket::response::status::Custom is not defined in the current crate| | tokio_postgres::Error is not defined in the current crate| impl doesnt use only types from inside the current crate因此我们要定义一个类型MyError作为中间类型来转换一下。 /src/models.rs pub struct MyError {pub message: String, } impl Fromtokio_postgres::Error for MyError {fn from(err: Error) - Self {Self {message: format!({}, err),}} } impl FromMyError for rocket::response::status::CustomString {fn from(val: MyError) - Self {status::Custom(Status::ExpectationFailed, val.message)} }/src/services/note_book.rs pub async fn insert_or_update_note(note: Note, ) - Result(), rocket::response::status::CustomString {let (client, connection) connect(hostlocalhost dbnamenotes_db userpostgres port5432,NoTls,).await.map_err(MyError::from)?;...let _ client.execute(insert into notes (id, title, content) values($1, $2, $3);,[get_system_seconds(), note.title, note.content],).await.map_err(MyError::from)?;Ok(()) }src/routes/notes.rs #[post(/api/notes, format application/json, data note)] pub async fn post_notes(note: JsonNote) - Result(), rocket::response::status::CustomString {insert_or_update_note(note.into_inner()).await }而MyError到rocket::response::status::CustomString之间的转换是隐式的由编译器来完成。因此我们的错误类型的转换最终缩短为map_err(|err|MyError::from(err))再简写为map_err(MyError::from)。 关于错误处理中的类型转换应用解析就到这里。通过分析这个过程我们可以看到在设计模块时我们应该确定一种错误类型就像tokio_postgres库一样只暴露了tokio_postgress::error::Error一种错误类型。这种设计既方便我们在设计模块时处理错误转换也方便其我们的模块在被调用时其它代码进行错误处理。
http://www.w-s-a.com/news/726400/

相关文章:

  • 浅谈高校网站群的建设网站不支持m.域名
  • 和平网站建设公司做实验教学视频的网站
  • 音乐网站源码带手机版WordPress菜单调用不出
  • 昆明网站设计都需要设计什么网络推广岗位职责和任职要求
  • 国外公司网站模板网站建设公司选择意见书
  • 如何创建一个网站卖东西郑州 网站建设公司
  • 石景山郑州阳网站建设南京网站搜索引擎优化
  • 一个网站需要哪些备案书店网站建设策划书总结
  • 网站建设的重点是什么注册网站空间
  • 网站公司企业宗旨我的网站 dedecms
  • 沧州网站优化做详情图的网站
  • 中国建设银行公积金网站wordpress表单 post
  • 找权重高的网站方法wordpress视频网站上传视频
  • 营销型网站架构师迁移wordpress500错误
  • 做网站还是博客由()承担
  • wordpress 导购站模板中国最新军事新闻直播83军
  • 公众号h5网站开发wordpress文章主图
  • ps怎么艺术字字体设计网站我想自己做网站
  • 北京做机柜空调的网站模板网站和插件
  • 手机购物网站模板wordpress添加分类文档
  • 网站开发知识网上怎么申请个人营业执照
  • 音乐网站建设费用营销策略都有哪些4p
  • 深圳制作网站怎么样wordpress 学习视频
  • 新公司注册网站传奇手游大型网站
  • 无极网站网站涉案多少人被抓网站的按钮怎么做
  • ds216j做网站做购物网站那个好
  • 做淘宝门头的网站阿里巴巴官网app
  • 安踏网站建设策划方案如何通过域名访问网站
  • 建设网站破解版seo查询 站长之家
  • 太原模板建站平台旅游企业网站建设工作的通知