【Rust投稿】捋捋 Rust 中的 impl Trait 和 dyn Trait

2024-06-23 00:32
文章标签 rust trait impl dyn 投稿

本文主要是介绍【Rust投稿】捋捋 Rust 中的 impl Trait 和 dyn Trait,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文来自 PrivateRookie 的知乎投稿:https://zhuanlan.zhihu.com/p/109990547


缘起

一切都要从年末换工作碰上特殊时期, 在家闲着无聊又读了几首诗, 突然想写一个可以浏览和背诵诗词的 TUI 程序说起. 我选择了 Cursive 这个 Rust TUI 库. 在实现时有这么一个函数, 它会根据参数的不同返回某个组件(如 Button, TextView 等). 在 Cursive 中, 每个组件都实现了 View 这个 trait, 最初这个函数只会返回某个确定的组件, 所以函数签名可以这样写

fn some_fn(param: SomeType) -> Button

随着开发进度增加, 这个函数需要返回 Button, TextView 等组件中的一个, 我下意识地写出了类似于下面的代码

fn some_fn(param1: i32, param2: i32) -> impl View {    if param1 > param2 {        // do something...return Button {};    } else {        // do something...return TextView {};    }}

可惜 Rust 编译器一如既往地打脸, Rust 编译器报错如下

--> src\main.rs:19:16|
13 | fn some_fn(param1: i32, param2: i32) -> impl View {|                                         --------- expected because this return type...
...
16 |         return Button {};|                --------- ...is found to be `Button` here
...
19 |         return TextView {};|                ^^^^^^^^^^^ expected struct `Button`, found struct `TextView`error: aborting due to previous errorFor more information about this error, try `rustc --explain E0308`.

从编译器报错信息看函数返回值虽然是 impl View 但其从 if 分支推断返回值类型为 Button 就不再接受 else 分支返回的 TextView. 这与 Rust 要求 if else 两个分支的返回值类型相同的特性一致. 那能不能让函数返回多种类型呢? Rust 之所以要求函数不能返回多种类型是因为 Rust 在需要在 编译期确定返回值占用的内存大小, 显然不同类型的返回值其内存大小不一定相同. 既然如此, 把返回值装箱, 返回一个胖指针, 这样我们的返回值大小可以确定了, 这样也许就可以了吧. 尝试把函数修改成如下形式:

fn some_fn(param1: i32, param2: i32) -> Box<View> {    if param1 > param2 {        // do something...return Box::new(Button {});    } else {        // do something...return Box::new(TextView {});    }}

现在代码通过编译了, 但如果使用 Rust 2018, 你会发现编译器会抛出警告:

warning: trait objects without an explicit `dyn` are deprecated--> src\main.rs:13:45|
13 | fn some_fn(param1: i32, param2: i32) -> Box<View> {|                                             ^^^^ help: use `dyn`: `dyn View`|= note: `#[warn(bare_trait_objects)

这篇关于【Rust投稿】捋捋 Rust 中的 impl Trait 和 dyn Trait的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1085829

相关文章

BD错误集锦7——在集成Spring MVC + MyBtis时使用c3p0作为数据库时报错Method com/mchange/v2/c3p0/impl/NewProxyPreparedStatem

异常信息如下: Type Exception ReportMessage Handler dispatch failed; nested exception is java.lang.AbstractMethodError: Method com/mchange/v2/c3p0/impl/NewProxyPreparedStatement.isClosed()Z is abstractDescr

Rust:Future、async 异步代码机制示例与分析

0. 异步、并发、并行、进程、协程概念梳理 Rust 的异步机制不是多线程或多进程,而是基于协程(或称为轻量级线程、微线程)的模型,这些协程可以在单个线程内并发执行。这种模型允许在单个线程中通过非阻塞的方式处理多个任务,从而实现高效的并发。 关于“并发”和“并行”的区别,这是两个经常被提及但含义不同的概念: 并发(Concurrency):指的是同时处理多个任务的能力,这些任务可能在同一时

区块链会议投稿资讯CCF A--WINE 2024 截止7.15 附录用率 附录用的区块链文章

Conference:The Conference on Web and Internet Economics (WINE) CCF level:CCF A Categories:Cross-cutting/comprehensive/emerging Year:2024 Conference time: December 2-5, 2024 录用率: selected 66 p

【Rust日报】 2019-04-06

Arenas vs. Indices:為型別寫函數要寫在型別裡還是外面? 作者舉了一些例子 下面簡單說明他討論的這個問題 他想為MVPArena寫一個add的函數 那把add這個函數從 impl MVPArena 移到外面 那首先就要解決生命週期的問題 struct MVPArena<T>(Vec<T>);impl<T> MVPArena<T> {fn add(&mut self, T valu

【Rust日报】 2019-04-05

「系列文章」审阅Sled源码 Part I #CodeReview #sled Sled项目是一个用Rust编写的嵌入式数据库。该文作者在日程工作中用到了它,为了掌握它的工作原理,准备开始写这个系列的博客。也可以通过学习此文,掌握一些阅读开源项目源码的技巧或其他启示,比如: 先找你擅长领域的项目去阅读,事半功倍。从整体上先把握代码组织结构、依赖库,从所获得的信息中去推测更多信息。携带某个主要的问

【Rust日报】 2019-04-04

成功故事:Rust在企业领域的应用 #zalando 本文描述了zalando公司从Scala转向Rust的成功故事。 缘起: 2016年该文作者作为Scala开发者加入了Zalando公司。半年后,他们打算开始做一个新的应用,与此同时,团队内商量该使用什么新技术,Rust就在这时被提及,同时他们也用Rust快速实现了原型,但是最后这个新应用被取消了。但Rust却成为了该团队的一门候选语言。 碰

【Rust日报】 2019-04-02

愚人节 RFCs 提议整个Rust项目由bors机器人管理。 https://github.com/rust-lang/rfcs/pull/2671 提议将Cow来默认导出 (这个我真信了) https://github.com/rust-lang/rfcs/pull/2672 信了你就瓜了。:) 台湾 COSCUP 開源人年會 COSCUP 2019 - Aug 17th-18th. NTUS

【Rust日报】 2019-04-01

Rust算法俱乐部 #algo 台湾同胞搞的Rust学习算法的教程 rust-algo.club cnx:用Rust实现的X11状态栏 #x11 cnx rustsim 报告 #5 #rustsim 简要: alga 0.9 和 nalgebra 0.18开始支持复数并且与#[no-std]保持兼容nalgebra开始在几何代数上添加对三角函数和卷积的支持等等。 Read More Rus

【Rust日报】 2019-03-31

Rust日报小组成立 从下周开始将由ChaosBot、Mike和Damody三位轮流发布日报,其中Damody为台湾同胞,如果大家看到中文繁体日报,就是他发布的。 发日报有什么好处?我来给大家透露一下。至少有三点好处: 了解Rust生态最新动态锻炼自己的总结能力。对于感兴趣的文章,可以快速汲取其主要观点。为自己的提升和学习铺垫了资料库。 所以,也欢迎大家参与Rust日报的内容建设中。 Ocyp

【Rust日报】 2019-03-30

使用rust與tensor來做臉部辨識 Read more Ocypod: 一個用Redis來備份的工作佇列 基於actix來實作,目前看起來功能還沒有 beanstalkd 之類的老牌 job queue 完整 不過效能應該是可以期待的,使用json來溝通 如果之後能直接支援 protobuff 就好了 畢竟json比protobuff慢多了 Read more sgx sdk 1.0了 In