我在 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 版权协议,转载请附上原文出处链接和本声明