即刻成为鸿蒙应用开发者,解锁职业发展新机遇!点击了解~ 了解详情
写点什么

受不了 Rust 这些问题,我将后端切换到了 Go

  • 2023-01-03
    北京
  • 本文字数:1767 字

    阅读完需:约 6 分钟

受不了Rust 这些问题,我将后端切换到了 Go

本文最初发布于 Level Up Coding 博客。


别激动!我能感受到你点击这篇文章时怀有的愤怒。我并不讨厌 Rust——在许多场景中,我都倾向于使用它。所有编程语言都是达成目的的手段。然而,就我要处理的场景而言,Rust 并不是很适合,我不得不把这个项目推倒重来,用 Golang 重写。


该项目是 Hasura 的一个简单的后端 webhook 服务。你可能不了解 Hasura,那是一个 Postgres 数据库封装器,可以即时提供 GraphQL API。对于像我这样独自开发个人兴趣项目的人来说,这非常方便:每个 REST 端点或 GQL 解析器都要编写的话会耗费大量的时间,而且每个模型的 CRUD 操作基本相同。当需要一些比较复杂的逻辑时,它就不那么有效了——为此,Hasura 允许你将 GQL 请求映射到自定义 webhook。举例来说,我就是用这种方法进行 S3 文件上传或身份验证。


问题 1:依赖注入难


Rust 依赖注入是一个有趣的问题。如果你需要一个具体的类型,如:

fn do_stuff(db: &Database) {    db.create(Stuff);         db.read(Stuff);}
复制代码


你必须给 do_stuff 传递一个 Database 实例;概莫能外!你不能“子类化”Database (Rust 没有子类的概念)。所以,如果你是一个不自己测试代码的程序员,那么这完全没问题;实际上,你只会有一个 Database 的实现,因此也就没有理由让这个函数接受 Database 以外的任何东西。


那我们测试人员呢?我们必须重写函数签名。Database 需要是 trait 类型的,然后我们把那个它在 mock 对象上实现。好吧,还不算太坏。事实上,在 Golang 中,我做的事情基本相同;那到底是从哪里开始有问题的呢?


问题 2:异步 Trait


在 Rust 中,异步很简单,trait 也很简单,但异步 trait 却有些困难。我在 Rust 中找到的大多数异步 trait 示例都用了 async_trait 宏。这很有帮助,我正在用它,体验还不错。


以下是我到目前为止对这个过程的一个总结:


  1. 编写一个结构;开心。

  2. 编写一个测试;意识到无法依赖注入。难过。

  3. 将结构转换为 trait;开心。

  4. 心满意足地依赖注入。

  5. 使用 mockall crate 自动生成 mock。非常非常开心!

  6. 做一个异步 http 调用。

  7. 需要用一个特殊的宏实现异步 trait。

  8. 意识到这个宏无法很好地与 Mockall 一起工作。

  9. 难过。


事后来看,这个问题是有办法解决的。也许在切换到 Go 之前我应该再试一次,但那时,下面这一点已经让我有点沮丧了……


问题 3:编译慢(致命一击)


Rust 的编译时间很糟糕。我们已经听过无数次了;不可能有一种无所不能却没有缺点的语言。那是不可能的——Rust 的缺点是难以理解的生命周期以及糟糕的编译时间。


我有一台漂亮耐用的笔记本电脑 M1 Mac,那可是一头老黄牛。在我的 Mac 上编译 Rust 绝对没有问题。通常,在编写服务器时,我会在本地开发,并且要保证每次有修改时,本地服务器会重新加载,让我可以在提交真正的单元测试之前非常快速地测试功能。两次试验之间需要进行大量的编译;可以接受!还是说,在 Mac 上编译 Rust 没有问题。


在容器里吗?还是算了吧。


对我来说,要编排许多本地服务而又不用费事在每个服务(Hasura、Web 钩子、mock s3、mock oauth 服务器……)中运行 npm run ,最简单的方法是有一个 docker-compose.yaml 文件可以运行所有这些东西。通常就是一个 docker-composition.dev.yaml 文件,因为我实际上并不使用 docker compose 进行部署。只在本地进行开发。然而,这有一个副作用,就是我的 Rust 代码需要在容器中编译,因为:必


  1. 须自动热重载。

  2. 必须在容器里开发。


我有两个选择:要么启动一个可能会跑死整台计算的巨大镜像,以便在其中编译 Rust 代码,要么就要与 3 分多钟的编译时间周旋。开发周期陷入停滞,让我感觉非常低效。我试着改变工作流程,在手动测试之前编写代码和测试,或者不使用自动热加载,但糟糕的是,我就是没能做到。


最后,我咬紧牙关,换成了 Go。让人怀念的 Rust:我非常喜欢编写 Rust 代码。我觉得它漂亮而富有表现力,实用而优雅。


如果我正在编写本地辅助库、性能敏感代码、任何不需要在容器中运行的后端服务……那么,Rust 会是我的第一选择。特别是如果我不需要说服其他任何人使用它。


对于我提到的问题,特别是最后一个问题,如果你有任何解决方法,请务必告诉我。我想让 Rust 回到项目中,我愿意回到旧版本,并将其提升到同等水平。


原文链接:https://levelup.gitconnected.com/why-i-switched-from-rust-to-go-on-the-backend-28bda21dbee9

2023-01-03 18:0115707
用户头像
刘燕 InfoQ高级技术编辑

发布了 1112 篇内容, 共 562.5 次阅读, 收获喜欢 1978 次。

关注

评论

发布
暂无评论
发现更多内容

Java后端开发面试题之MySQL上篇(含答案)

北游学Java

Java MySQL 面试

Redis - 替换策略:LRU和LFU

insight

redis 3月日更

聊聊LiteOS中生成的Bin、HEX、ELF三种文件格式

华为云开发者联盟

编译器 LiteOS Bin HEX ELF

作为后端开发人员应该懂的TCP、HTTP、Socket、Socket连接池,一文详解丨Linux后端开发

Linux服务器开发

TCP 后端 socket HTTP Linux服务器开发

你不知道的 Proxy

阿宝哥

JavaScript Proxy web api

设计与思考,关于资源和生命周期(二)

程序员架构进阶

设计实践 生命周期 28天写作 3月日更 池化技术

这个 29.7 K 的剪贴板 JS 库有点东西!

阿宝哥

JavaScript 开源 源码解析

JSP中Vue.js的使用受限

空城机

vue.js 大前端 jsp

rmtc交易所系统开发平台丨rmtc交易所源码设计

系统开发咨询1357O98O718

9种常用便捷的Java异常处理方法,帮你脱身繁琐

北游学Java

Java 异常 异常检测 异常处理

管理者如何应对员工离职

石云升

离职 28天写作 职场经验 管理经验 3月日更

17张图带你搞懂ZooKeeper一致性原理!

Java小咖秀

程序员 TCP udp 传输协议

初识Golang之函数及方法的多返回值

Kylin

3月日更

坚持输出文字

lenka

3月日更

聊一聊 Vue 3 双向绑定是如何工作的

阿宝哥

Vue Vue 3

Wireshark数据包分析学习笔记Day22

穿过生命散发芬芳

Wireshark 数据包分析 3月日更

要求输出事故报告,线上日志文件却不见了!!

陈皮的JavaLib

Java 运维 日志框架

JVM疑难情况分析

秋天

jvm调优

Python OpenCV 图像缩放 cv2.resize 方法

梦想橡皮擦

3月日更

智能化软件开发微访谈·第十六期:低代码/无代码开发

吴盛

低代码 快速开发 sql 无代码开发

Python基础之:Python中的IO

程序那些事

Python 人工智能 数据分析 程序那些事

2021最新整理Java面试合集(1000道附答案解析)

比伯

Java 编程 架构 面试 程序人生

发展数字经济要因地制宜

CECBC

数字经济

为什么很多工程师不了解Serverless

云原生

Serverless 云原生 Knative

金三银四了!必知必会,HTTP面试题!漫画图解超硬核!

小白debug

面试 网络编程 网络 HTTP 网络层

百度AI人才培养课程0元报名倒计时

百度大脑

百度 AI 飞桨

寻找被遗忘的勇气(二十五)

Changing Lin

3月日更

35岁了,还不知道,TCP为什么会粘包?【硬核图解】

小白debug

TCP 网络 协议栈 TCP/IP 网络层

为智能世界“高”歌:HEIGHT,五种风景,一个答案

脑极体

架构师训练营第一课学习笔记

杰语

常见Http响应码

风翱

3月日更 http响应码

受不了Rust 这些问题,我将后端切换到了 Go_AI&大模型_Anthony Oleinik_InfoQ精选文章