当前位置:网站首页>[rust submission] review impl trail and dyn trail in rust
[rust submission] review impl trail and dyn trail in rust
2022-06-25 03:52:00 【51CTO】
PrivateRookie -- author
origin
Everything must be changed from the end of the year to the special period , I read a few poems at home , I suddenly want to write a poem that can be browsed and recited TUI Procedure starts . I chose Cursive This Rust TUI library . There is such a function in the implementation , It will return a component according to different parameters ( Such as Button, TextView etc. ). stay Cursive
in , Each component implements View
This trait, Initially, this function will only return a certain component , So the function signature can be written like this
As development progresses , This function needs to return Button, TextView One of the components such as , I subconsciously wrote something like this
unfortunately Rust The compiler always smacks in the face , Rust The compiler reports an error as follows
--> 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 error
For more information about this error, try `rustc --explain E0308`.
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
From the compiler error information, we can see that the return value of the function is impl View
But it comes from if
The branch inference return value type is Button
No longer accept else
Branch returns TextView
. This is related to Rust requirement if else
The return value types of the two branches are the same . Can you make the function return multiple types ? Rust The reason why a function cannot return multiple types is because Rust In need in The compile time determines the memory size occupied by the return value , Obviously, different types of return values have different memory sizes . In that case , Pack the return value , Returns a fat pointer , In this way, the size of our return value can be determined , Maybe it will be OK . Try changing the function to the following form :
Now the code has been compiled , But if Rust 2018, You will find that the compiler will throw a warning :
The compiler tells us to use trait object Do not use dyn
The form of has been abandoned , And it also reminds us to put Box<View>
Change to Box<dyn View>
, Follow the compiler's prompts to modify the code , Now the code no warning, no error, perfect .
but impl Trait
and Box<dyn Trait>
Is there any difference except that multiple return value types are allowed ? trait object
What is it again? ? Why? Box<Trait>
The return value of form will be discarded and new dyn
Key words? ?
Buried pit
impl Trait
and dyn Trait
stay Rust They are called static distribution and dynamic distribution respectively . In the first edition of Rust Book Explain distribution in this way (dispatch)
When code involves polymorphism, there needs to be a mechanism to determine which specific version is actually run. This is called ‘dispatch’. There are two major forms of dispatch: static dispatch and dynamic dispatch. While Rust favors static dispatch, it also supports dynamic dispatch through a mechanism called ‘trait objects’.
That is, when the code involves polymorphism , Some mechanism is needed to determine the actual call type . Rust Of Trait It can be seen as some collection with pass through feature types , Take the above code for example , When we write code, we don't care about specific types , However, it must be determined at compile time or run time Button
still TextView
. Static distribution , Just like static typed languages " static state " The word , The specific call type is determined at compile time . Rust The compiler will use singleton (Monomorphization) Expand generic functions .
hypothesis Foo
and Bar
It's all done Noop
characteristic , Rust Will function
Begin to
( For principle explanation only , There is no guarantee that the compilation will expand the function name in this way ).
By monometalization , The compiler eliminates generics , And no performance loss , This is also Rust The form advocated , The disadvantage is that too many expansions may cause the volume of the secondary system file generated by compilation to be too large , You may need to refactor the code .
Static distribution has high performance , But at the beginning of the article, another shortcoming is also reflected , That is, functions cannot return multiple types , therefore Rust Also support passing trait object Realize dynamic distribution . since Trait Is a collection of types with certain characteristics , Then we can put Trait Also as a certain type , But it is " In the abstract ", It's like OOP Abstract class or base class in , Cannot instantiate directly .
Rust Of trait object Used with c++ Allied vtable
Realization , trait object contain 1 Points to the actual type data
The pointer , And an implementation that points to the actual type trait Functional vtable, This enables dynamic distribution . A more detailed introduction can be found in
Exploring Dynamic Dispatch in Rustalschwalm.com
notice . since trait object The size can be determined during implementation , Then why not fn x() -> Trait
In the form of ? although trait object The size can be determined in the implementation , But logically , because Trait Represents a collection of types , Its size cannot be determined . allow fn x() -> Trait
It will lead to semantic disharmony . that fn x() -> &Trait
Well ? Certainly. ! However, in this scenario, all references are created in the function and then return the value , Obviously, the life cycle needs to be added :
I don't like to add additional lifecycle descriptions , You must be the same . So we can use the Box
Smart pointers avoid annoying life cycle descriptions . thus Box<Trait>
At last . So here comes the question , Why does the compiler prompt Box<Trait>
Will be abandoned , Specially introduced dyn
Key words? ? The answer can be in RFC-2113 Find .
RFC-2113 The introduction of dyn
Why , That is, semantic fuzziness , It's confusing , The reason is that there is no dyn
Give Way Trait and trait objects It looks exactly the same , RFC List 3 An example shows .
First example , Add the code you see below , Do you know what the author wants to do ?
Do you understand ? To tell the truth, I can't understand : ) PASS
Second example , impl MyTrait {}
Is the correct grammar , But it makes people think that this will be in Trait Add default implementation on , Extension method or other Trait Some of their own operations . In fact, this is trait object Add method on .
As explained in the following code , Trait The correct way to define the default implementation is to define Trait When you specify , Instead of impl Trait {}
In the block .
Bar
In the realization of Foo
You can go through b.default_impl
call , No additional implementation is required , but b.trait_object
No way. , because trait_object
The method is Foo
Of trait object The method on the .
If it is Rust 2018 The compiler should also display a warning , Tell us that we should use impl dyn Foo {}
The third example is based on function type and function trait Contrast , The only difference between the two is whether the initial letter is capitalized (Fn Representative function trait object, fn Is the function type ), It is inevitable to confuse the two .
More detailed instructions can be moved
RFC-2113github.com
.
summary
impl trait
and dyn trait
The difference is that static distribution is different from dynamic distribution , Static distribution performance good , However, extensive use may cause binary file expansion ; Dynamic distribution to trait object The concept of is realized through virtual tables , There will be some runtime overhead . Because of trait object And Trait Without introducing dyn
It often leads to semantic confusion , therefore Rust Specially introduce dyn
keyword , stay Rust 2018 Has been stabilized in .
quote
The following are the references for this article
impl Trait for returning complex types with easedoc.rust-lang.org
impl trait Community Tracking github.com
rust-lang/rfcsgithub.comTraits and Trait Objects in Rustjoshleeb.comDynamic vs. Static Dispatchlukasatkinson.deExploring Dynamic Dispatch in Rustalschwalm.com
PS: The picture above shows Lupu Bridge , My favorite bridge in Shanghai , Not one of them. ~
边栏推荐
- OpenSUSE environment PHP connection Oracle
- Is it safe to open an account online? How to open an account?
- Is it safe for tonghuashun securities to open an account
- 你真的需要自动化测试吗?
- Tutorial on installing SSL certificates in Microsoft Exchange Server 2007
- Program. Launch (xxx) open file
- The era of copilot free is over! The official version is 67 yuan / month, and the student party and the defenders of popular open source projects can prostitute for nothing
- Three key explanations of overseas e-commerce operation in 2022
- Perfect shuffle problem
- Jilin University 22 spring March "official document writing" assignment assessment-00029
猜你喜欢
程序员真人秀又来了!呼兰当主持挑灯狂补知识,SSS大佬本科竟是药学,清华朱军张敏等加入导师团...
x86 CPU,危!最新漏洞引发热议,黑客可远程窃取密钥,英特尔“全部处理器”受影响...
How to raise key issues in the big talk club?
DevEco Studio 3.0编辑器配置技巧篇
Rebeco:使用机器学习预测股票崩盘风险
Redis related-02
Collaboration + Security + storage, cloud box helps Shenzhen edetai restructure its data center
Tensorflow, danger! Google itself is the one who abandoned it
Google founder brin's second marriage broke up: it was revealed that he had filed for divorce from his Chinese wife in January, and his current fortune is $631.4 billion
完美洗牌问题
随机推荐
马斯克被诉传销索赔2580亿美元,台积电公布2nm制程,中科院发现月壤中含有羟基形式的水,今日更多大新闻在此...
2点睡10点起不算熬夜?除非你每天都能执行
Is it safe to open an account on your mobile phone?
腾讯开源项目「应龙」成Apache顶级项目:前身长期服务微信支付,能hold住百万亿级数据流处理...
在线股票开户安全吗?
Maybe it's the wrong reason
多睡觉,能减肥,芝加哥大学最新研究:每天多睡1小时,等于少吃一根炸鸡腿...
Wechat development related
Redis related-02
Jilin University 22 spring March "career design" assignment assessment-00072
TC object structure and abbreviation
同花顺证券开户是安全的吗?
可能是拿反了的原因
Comprehensive assignment of thesis writing instruction of Dongcai
Is it safe to open an account online? Online and other answers
做自媒体不知道怎样变现?7大变现方法分享
你真的需要自动化测试吗?
浏览器下载的文件属性里都有保护,如何去掉
Is it safe to open a stock account with the customer's haircut account link? Tell me what you know
JSP cannot be resolved to a type error reporting solution