栏目分类
热点资讯
新闻
你的位置:开云集团「中国」Kaiyun·官方网站 > 新闻 > 开云集团「中国」Kaiyun·官方网站这粗拙被称为代数数据类型-开云集团「中国」Kaiyun·官方网站
开云集团「中国」Kaiyun·官方网站这粗拙被称为代数数据类型-开云集团「中国」Kaiyun·官方网站

发布日期:2024-06-14 07:13    点击次数:77

开云集团「中国」Kaiyun·官方网站

【编者按】自从好意思国白宫对建树者敕令,“罢手使用 C 和 C++,改用 Rust 等内存安全编程说话”后,两方之间从未罢手的争论就被推到了一个新高度。而在这之中,也有部分 C++ 建树者淡薄:不祥 Rust 中的一些见识,不错试着哄骗到 C++ 编程中?

整理 | 郑丽媛

近日,一位建树者(ID:delta242)在 Reddit 上发了一篇长文《在 C++ 中应用 Rust 的见识》,里面提到了一些可用于改善 C++ 代码的 Rust 见识,引来了诸多热心和策动。

说明他在开篇的先容,“天然我不是 Rust 众人,但我很可爱这门说话的好多见识。在时常编程中,我主要用 C++,而刻下我常常会哄骗一些 Rust 的见识来改善我的 C++ 代码”,不错看出,底下是他切身实验过的、可用于优化 C++ 代码的 Rust 见识。

在 C++ 中,怎样应用 Rust 的见识?

(以下为他的长文翻译:)

(1)带值的排列

我很可爱 Rust 的排列,因为你不错给排列常量赋值(举例,Option 排列中有一个莫得值的 None 和一个有值的 Some)。在类型表面中,这粗拙被称为代数数据类型,而在 C++ 中,咱们有 variants,不错界说援助结构体来杀青雷同的功能:

struct Some { T value; };\nstruct None { };\nusing Optional = std::variant ;

(注:这个例子可能有点蠢,因为 std::optional 要好得多。但关于更复杂的类型来说,这具有一定参考意旨。)

(2)CRTP 和 Traits

在 Rust 中,Traits 用于界说类型的分享功能。而在 C++ 中,咱们不错用 CRTP 在编译时强制类杀青特定的函数来杀青静态多态性。CRTP 还允许在基类中杀青默许功能,我过去曾用这种法式来界说迭代器类型,惟有基类杀青了 operator[],就不错减少宽广模板代码的编写。

(3)字符串时事化

在 C++ 中,要是向 std::format 传递的参数数目多于时事字符串中的占位符,并不会导致编译时失误。我照旧遭逢过这么的 bug,举例由于枯竭占位符,日记音问中枯竭了某些信息,导致与代码中不一致。

而这个情况要是放在 Rust 中,就会产生编译时失误。是以这关于 C++ 来说,将是一个浮浅而实用的校正,有助于栽培代码质料和建树服从。

(4)领有 Mutex

在 Rust 中,Mutex 类型领有受保护的值。我尽头可爱这个见识,这么不取得 Mutex 就无法拜谒受保护的值(这在 C++ 中常常发生)。有一个浮浅的手段来杀青雷同后果,那即是在 C++ 中写一个具有 lock 函数的封装 Mutex 类,该函数将接受一个带有对受保护值的援用的 lambda 抒发式行为参数。由于 Rust 中有借用搜检器,这么的操作老是安全的,而在 C++ 中,误用很容易再次导致竞争条款,但至少通过这么的封装器,这种情况就不那么容易发生了。

(5)里面可变性

Rust 在安全的情况下会使用里面可变性(即使变量是 const),举例当一个值受 Mutex 保护时。在 C++ 中,咱们也不错继承雷同的目的,举例“const 暗意线程安全”。

(6)IIFE

在 Rust 中,每个作用域王人是一个抒发式,这么不错很好地将变量收尾在更小的作用域中。而在 C++ 中,咱们不错用 lamdas 抒发式来使用立即调用的函数抒发式(IIFE)来达到相似的后果:

auto value = [] {\n// Complex initializer\nreturn result;\n}(); // notice the invocation

以上,即是我刻下能预见的。

“Rust 让我成为了又名更好的 C++ 建树者”

在这篇长文下,不少建树者也分享了我方在 C++ 编程中鉴戒 Rust 见识的心得,甚而直言“Rust 让我成为了又名更好的 C++ 建树者”。

(1)“最近,我养成了在 C++ 中使用“match”宏的这个俗例,我很可爱。”

template struct overloaded : Ts... { using Ts::operator()...; };\n\ntemplate\nauto match(Val val, Ts... ts) {\nreturn std::visit(overloaded{ts...}, val);\n}

(2)“重载尽头好,我合计它不错成为 STL 的一部分。此外,有了 C++20 模板化的 lambdas,还不错编写一些尽头花哨的代码。”

visit(\noverloaded {\n[] T>(T value) {}\n[](auto other) {}\n}, value)

对此,一位建树者感叹:“这恰是我但愿看到的,天然我不可爱 Rust,但它确乎有一些 C++ 不错鉴戒的作念法,更安全总归是好的。”

在 C++ 中应用 Rust 见识的一些失败案例

不外与此同期,也有建树者领导“必须留心”:以 Rust 的 Mutex 为例,当你拜谒 Mutex 中的数据时,弗成能将该指针存储下来,然后在解锁 Mutex 后再拜谒数据(忽略稀奇情况)。你不错在 C++ 中杀青一个领有 Mutex 的类,但编译器不会防备你是否在锁的作用域以外握有一个指向受保护数据的指针,并在未受保护的情况下拜谒它。

针对这个话题,开源搜索引擎 Meilisearch 的高等工程师 Louis Dureuil 曾写过一篇关联著述《这对 C++ 来说太危急了》:“一些蓄意形态之是以实用,归功于 Rust 的内存安全性,而在 C++ 中使用则过于危急。”

在文中,Louis Dureuil 分享了他在 C++ 中应用 Rust 见识的失败案例。

其时,他正在用 Rust 编写一个里面库,其中有一个他但愿能克隆、而不会复制其中数据的失误类型。在 Rust 中,这需要使用援用计数指针,比如 Rc。他编写了一个失误类型,将其用作可能发生失误的函数的失误变体,不息了他的责任。

struct Error {\ndata: Rc ,\n}\n\npub type Response = Result ;\n\nfn parse(input: Input) -> Response {\ntodo!()\n}

其后他发现开云集团「中国」Kaiyun·官方网站,对某些输入进行默契需要很长技术,于是决定通过通谈将输入发送到另一个线程,并通过另一个通谈取得反映,这么长技术的默契就不会阻难干线程。

enum Command {\nInput(Input),\nExit,\n}\n\npub enum RequestStatus {\nCompleted(Response),\nRunning,\n}\n\npub struct Parser {\ncommand_sender: Sender,\nresponse_receiver: Receiver<(Input, Response)>,\ncached_result: HashMap ,\n}\n\nimpl Parser {\npub fn new() -> Self {\nlet (command_sender, command_receiver) = channel::();\nlet (response_sender, response_receiver) = channel::<(Input, Response)>();\n\nstd::thread::spawn(move 


资讯 娱乐 新闻 旅游 汽车 电影