我在 Rust 中的第一个真实代码

我在 Rust 中的第一个真实代码

每种语言都始于游乐场。你可以在那里做一些令人惊奇的事情,但它们就像邻近的儿童沙饼一样令人惊奇。

一旦你从操场进入“做一些真正的事情”,你就会从沙饼领域进入“用胶水和松果做纸应用”,这更容易获得,但仍然是“孩子”的水平。

提交到现有的应用程序或库是一种非常不同的活动。 “小而重要的事情”的数量是惊人的,真正的代码不受解释简单性的约束。

所以,我已经对我使用的库进行了第一次小提交(准确地说是 PR)。该库是 Speedy2D,我发现了那种类型 矢量2 (这是两个数字的简单元组)缺少分配操作(fe x+=y )。我决定添加它们。代码很简单,但过程很有趣。这是我的公关 #66 .

我发现了什么

首先,Speedy2D 使用了一种相当不寻常的代码风格。

通常

 fn foo(){  
 ...  
 }

变得

 fn foo()  
 {  
 ...  
 }

我不知道原因,除了对老 C 的怀念。

其次,我找到了justfile,这是一个脚本 只是 .这是我第一次听说。这是一个现代化的升级 制作 没有 。假 疯狂,这绝对是我与工作相关的兴趣,所以我将它添加到我的学习列表中。

此外,编写代码出乎意料地微妙。我虽然这将是一个微不足道的两条线( self.x+=rhs.x ; self.y+=rhs.x ),但我在类型方面发现了更多信息。

这是要实现的功能之一的代码 += 手术。

 暗示<T: Copy + std::ops::AddAssign, R: Into<Vector2<T> >> std::ops::AddAssign<R>  
 对于矢量2<T>  
 { #[排队]  
 fn add_assign(&mut self, rhs: R)  
 {  
 让 rhs = rhs.into();  
 self.x += rhs.x;  
 自我.y += rhs.y; } }

我写它是为了大量窥探周围的代码。

看看类型表达式!

我们正在与 矢量2 类型,按类型参数化 .

我们正在实施 std::ops::AddAssign 性状 矢量2<T> .它包含 add_assign 接受可变引用的函数 自己 和第二个值 rhs 带类型 R ,我们需要(有趣的部分从这里开始)可转换为 .

我很高兴也很困惑。我们允许使用不同的类型,而不是要求两种类型相同,但条件是第二种类型可以通过以下方式转换为第一种类型 进入 功能。这是一件非常非常聪明的事情,因为它不限制正常操作(当所有数字都是相同类型时),而是增强了其他类型的正确表达式。 。进入 对于相同的类型转换被消除(当 T::进入(t:T) 被调用),因此它不会产生任何开销(按下的按钮除外)。

此外,还有 复制 为了 (我不完全确定它为什么在这里。这是对 ,内部类型为 矢量2 ,所以我们希望它有便宜的副本?为什么?)。

最后,我感兴趣的是测试。我期待一长串测试,但我发现有一个双重测试系统:

  • 单元测试(带有 ' 的正常测试 #[测试] '指令)。
  • 具有无头 opengl 上下文的集成测试(在 lib 中仅称为“测试”)。

集成测试

集成测试通常是最完整的,有数百万个细微差别和关键点。

 #[cfg(not(all(target_arch = "x86_64", target_os = "linux")))]  
 compile_error!("目前自动化测试只支持 Linux x86_64");

这让我非常远离我所知道的 Rust 到一些用于编译时表达式的“其他 Rust”。 核心::compile_error 很有趣,而且它没有源代码(在标准库中):

 #[稳定(特征=“compile_error_macro”,因为=“1.20.0”)]  
 #[rustc_builtin_macro]  
 #[宏导出]  
 #[cfg_attr(not(test), rustc_diagnostic_item =  
 “编译错误宏”)]  
 宏规则!编译错误{  
 ($msg:expr $(,)?) => {{ /* 编译器内置 */ }};  
 }

老实说 cfg(不是(所有 有点……金鸡。我得到了很多那些迂回的表达方式是 Jinja/Ansible,它们通常使用或阅读都不是很愉快。

测试中更有趣的是它们的声明方式。 (我不确定,这可能是 Rust 测试的常见做法,但我在阅读文档时错过了它)。

主要的 初始化的函数 事件循环 (哇),通过将闭包推入测试向量来收集测试)。基本上,所有测试都是里面的闭包列表 主要的 功能。为什么有事件循环?为什么不直接调用函数?是在嘲笑什么吗?为什么测试都是这种形式而不是一个小的独立程序?我不觉得他们正在解决的痛苦( 所有集成代码都在解决某人的痛苦。或添加 .)。

我觉得它不是一个真正好的测试系统,因为测试在第一个失败的断言上失败,而没有运行其余的测试。

实际上,我发现其中一个测试在我的机器上失败了,修复这些测试对我来说是一个更有趣的问题。

CI

我还查看了该库的 CI 工作流程。有一个运行它的时间表(推送/公关除外),我不知道它为什么在那里。检测代码腐烂?这是我第一次看到这样的做法。我还注意到测试部分仅运行“功能禁用”测试。奇怪,奇怪……

我还发现没有发布工作流程,看起来发布是手动管理的。

代码通过 xvfb-运行 ,这解决了在 CI 服务器(这是 Github Actions 的 VM 没有硬件访问)上提供 X11 服务器的明显问题。由于我的爱好相关的 Rust 方面主要是图形应用程序,我非常欣赏这种测试方式。 (我的工作在另一边,零图形和最大服务器,所以我觉得自己是“图形桌面应用程序”领域的新手)。

变更日志

我希望能找到一些变更日志管理器,例如 里诺 (不确定我是否喜欢),但没有,更改日志完全是手动的。

只是文件

就像我说的, 只是 是这项努力的主要发现。通常很难为所有东西设置 CI(比如自动发布),所以有些操作是手动完成的。 “Just”允许将这些半自动过程的程序写成代码库中的代码(耶!更少的知识!更多的代码!)。

Speedy2D 有两个目标: 构建示例 webgl 预提交 (带有构建检查 wasm32-未知-未知 平台)。我猜测 预提交 用于预提交 git 钩子。

从wasm32的数量来看,它是最痛苦的,或者是最受QuantumBadger(图书馆作者)喜爱的。

结论

我瞥见了一些生产级代码,这将对我自己的代码有很大帮助。我还没有收到评论,但如果我没有未知的东西到达,我很确定它会被接受。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明

本文链接:https://www.qanswer.top/1498/50442916

posted @ 2022-08-29 16:51  哈哈哈来了啊啊啊  阅读(87)  评论(0编辑  收藏  举报