Nim、C++、Go、Zig、Odin、D、Janet、Swift 比较,哪个语言更好

2024-06-20 乙酉 甲辰年 庚午 乙卯 - 农历五月十五 - 少见的几乎整天中雨

海云青飞 翻译

我用一系列小型程序测试,以确定自己最喜欢哪种编程语言。我不打算放弃 C++,但如果我喜欢 Zig 或 Odin,我愿意用它们替换 Go

更新 08/28/23

Go 对比 C#

我认为 C# 已经赢得了作为我的主要工具的地位。我仍然喜欢 Go,因为它的简单性,所以我仍然会使用它,特别是对于 Wasm 图形演示,因为目前 .NET wasm 太大了,尽管如果未来版本的 .NET wasm(或 js 编译器)能够产生足够小的代码,我会重新考虑 C# 用于浏览器图形演示

下面是我对 Go 和 C# 的优缺点:

Go 编程语言的优缺点

  • + 简单
  • + 超级容易的 C/ffi 互操作
  • + 易于分发且体积小的可执行文件
  • + 感觉像 C 加强版
  • + Wails 用于 UI 很酷
  • + Fyne 用于 UI 很简单
  • - Wails 用于 UI 使用 4 种语言,html、css、javascript 和 Go
  • - Wails(和大多数基于 webview 的 UI)在 mac 上有启动闪烁/闪光
  • - Fyne 不支持置顶/始终在顶部的窗口

C# 编程语言的优缺点

  • + 依赖 .NET 的程序分发灵活,非常轻量,也可以是自包含的可执行文件
  • + LINQ 很酷
  • + Blazor 很酷
  • + MAUI 很酷
  • + 对我来说,Avalonia 是任何语言中最好的跨平台 GUI 框架
  • + Unity
  • + Godot
  • + ASP.NET
  • - 非原生的自包含 .NET exe 的大小约为 go 的 5 倍
  • - 目前 wasm 非常大,大约 4 Mb
  • ? 总是在添加新的、通常有用的功能,可能是发展最快的语言和平台。这可能是好事也可能是坏事,但到目前为止,我喜欢它的发展方向,所以对我来说大多是正面的,但它确实使得语言/平台越来越难以学习

我对这两种编程语言都有用例。如果 C# 太慢/太大,如 wasm 的情况,我可能会使用 Go,如果那还是比我想要的大/慢,我总是可以使用 C++。我认为在 Go、C#、C++ 和 Javascript 之间,我已经涵盖了我大部分的兴趣


对 C# 编程语言的评价

C# 加入了编程语言的竞争。我一直在关注 .NET 和 C#,最近几个版本的 .NET 一直专注于一些非常酷的功能,我一直在等待测试,即:Wasm、顶级语句(C# 9)和 .NET 8 的新 Native Aot

Native AOT 非常酷,它允许将 C# 编译成小型自包含可执行文件,并使 C# 在分发方面更接近 Go。对我个人来说,最酷的功能是 Native AOT exes 不仅可以调用外部库,而且实际上还可以静态链接本机库。由于 .NET MAUI 和 Avalonia 库用于 GUI 编程,这使得 C# 成为一个引人注目的选择,尤其是对我而言

对 C++ 编程语言的评价

我爱 C++。尽管它有些丑陋,但它仍然是我的最爱。用它成功编程让我感觉自己像个超级英雄,即使是编写一些微不足道的程序

对 Go 编程语言的评价

虽然它很早就被我淘汰了,但我可能仍会将它用于使用 Webview 的小工具,因为它的网络支持太好了

更新 04/27/22

我自己直接对照 C 重写了 opengl 示例后,Go 就不再被淘汰,我认为,在将它用于一些项目之后,其中有一个项目实际上取代了以前的 C++ 版本,它可能会取代 C++ 成为我的最爱

对 Zig 编程语言的评价

Zig 非常有趣,我绝对想进一步探索它

我重点关注它的编译时间,Zig 一直比其他编程语言慢得多,不过我实际上在 discord 上与 Zig 的创建者 Andrew Kelly 就此事进行了交流,他提到,当自托管增量编译器完成时,编译时间将显着改善,此点目前大约完成了 66%(截至 2022 年 2 月 13 日)

尽管它很冗长,但我真的很喜欢该语言的内存管理(通过分配器)和错误处理方法

此外,Zig 可以用作交叉编译 C 和 C++(我认为还有 Objective C )编译器。我甚至读过几篇 Go 文章,其中 Zig 用于使用 Cgo 交叉编译 Go 应用程序。它有一个很酷的构建系统,使用语言本身作为构建语言。我绝对会在将来更多地使用它

对 Odin 编程语言的评价

Odin 也很棒

我感觉它的语法在这些编程语言中属于最高级别

它在网络等方面还没有那么成熟,但它已经为许多游戏和媒体库提供了很好的绑定(尽管在 Mac 上我不得不做一些手动构建)

它相当酷,我甚至会考虑用它来替换 Go,因为表面上它们很相似。实际上,一旦 Odin 获得标准网络功能,我将重新审视并考虑用它来替换 Go

我还抱怨过很多关于 Odin 的强类型和严格转换的问题,但这当然被我的误解大大夸大了。您可以通过预转换您将经常使用的东西来减轻转换,也可以尽可能使用常量,因为这些是“无类型的”,并且很容易强制转换为其他类型

对 D 编程语言的评价

我发现它很有趣。在许多方面,它确实改进了 C++。但由于在 wasm 中使用它有点麻烦,对我来说很重要,所以我不会进一步使用它

对 Janet 编程语言的评价

请参阅下面的更新:

我最近添加了一个叫做 Janet 的奇怪编程语言

Janet 是一种类似 Lisp 的语言,可以嵌入到 C 中并用 C 扩展,类似于 Mruby。我之前多次遇到过它,但只是把它当作另一个奇怪的 Lisp,但最近(2022 年 2 月晚些时候)我因为 Bagger's awesome video 重新审视了 Lisps,视频中他重新编译了一个 3D 演示

我曾开始用 SBCL 学习 Common Lisp,并打算使用 Emacs 和 Slime/Swank 进行开发,但...我讨厌 Emacs。哈哈,对我来说,从 Vim 转过来,它的绑定太不自然了。我知道有一个 Spacemacs 插件可以让它更像 vim,但我在 Mac Catalina 上无法使其工作。因此,我决定彻底放弃 Lisps,因为我的想法是 Emacs 是最好的 Lisp 环境,如果我不能使用最好的环境,我根本就不会使用它

好吧,我来到了 VSCode 中的 AliveNeovim 的一个叫 Conjure 的项目,这些工具运行良好,易于设置

Janet 比 Common Lisp 简单得多,这对我来说很有吸引力。因此,我决定如果我能像 Bagger 在他的 Lisp 视频中展示的那样为 Janet 实现实时重新加载,那么我就会使用它。好吧,Janet 有一个叫做 spork 的包,其中包含了一个类似 SWANK 的服务器。因此,spork 加上 Conjure 和 Neovim 让我可以进行实时重新加载开发,所以我决定学习 Janet

Janet 很棒

一旦你适应了奇怪的 S 表达式语法,它就非常有趣。当然,复杂的表达式仍然很难读,但对我来说,它的其他优点是值得的

它自带网络、协程/纤程(绿色线程)和真正的本地(操作系统)线程,据我所知没有 GIL

对我来说,最终让 Janet 真正值得使用的特性是,使用其易于安装的包管理器 jpm,你可以将项目编译成独立的二进制文件,对于非系统语言来说,大小相当合理:使用 Raylib 的 Pong 示例在 Mac OS Catalina 上大约为 2.4MB

此外,它有一套很棒的绑定到 Raylib 的 Jaylib,这些绑定非常接近 C api,比我找到的 Commmon Lisp 绑定要近得多

由于 Janet 是一个可以嵌入到 C 中的小型虚拟机,通过 Wasm 和 Emscripten 编译它应该是小菜一碟,官方文档甚至提到了这一点。另外,在 gitter 频道 中,一位用户提到他已经成功地使用 emscripten 使用 Jaylib 绑定

它有标准库套接字封装器和一个“官方”社区版 http server

它甚至有 bindings 到 Webview,不过我可能会写我自己的,因为这些非常旧,而且我维护了我自己的 Webview 分支。总的来说,我非常喜欢 Janet,我认为它将取代 Go 成为我的第二语言

04/27/22 更新

我上个月在学习 Janet 并把它用于实践。接近月底时,我最终编写了一些 OpenGl 绑定,尽管不完全,但是很实用

然而,我发现将其编译为 wasm 比我最初想象的要困难得多。通过 emscripten 将 Janet 编译为 wasm 相当容易,然而我的 OpenGL 绑定是一个大型项目,包含许多子模块,Janet C 嵌入式 api 不支持在暴露绑定时保留这种模块结构,也就是说,我所有的 gl 函数都会在全局范围内暴露,这意味着我的模块导入不会起作用。解决办法是创建一个虚拟项目结构,它从全局范围导入所有函数到适当的模块中,然而这远远超出了我想做的。我真的很喜欢 Janet,但这件事导致我放弃了 gl 绑定,现在回到了我很满意的 Go

对 Swift 编程语言的评价

我在 6/1/22 添加了 Swift

Swift 在跨兼容性方面取得了很大进展,截至 2022 年,Swift 可以在 Mac、Linux、Windows 和 Wasm 上运行

在 Windows 上,已经投入了大量努力,使 Swift 能够与 win32 api 互操作,因此可以使用其原生绑定在 Mac 和 Windows 上纯粹地编写完全原生的应用程序

Swift 不是垃圾收集的,尽管从技术上讲它是因为引用计数是一种垃圾收集形式,但它不会遭受 GC 暂停

它是一种经过验证的语言,显然它在 Mac OS 上被广泛(几乎是专有)使用,用于从应用程序到游戏的所有内容

我想象这些天几乎所有的游戏都是用 Swift 为 IOS 编写的,所以它是一种经过验证的游戏编程语言,尽管我从未在游戏语言讨论中提到过它。我假设 Swift 当前无法在任何游戏机上运行,这可能是它没有在游戏语言讨论中被提及的原因,但又说回来,Python 在业余爱好者中相当流行,没有人甚至考虑在游戏机上运行 Python。它不能像 Go 或 Zig 那样跨系统编译

它非常好用,看起来和感觉就像一个 GC'd 脚本语言,但编译为本地代码。它很像 Rust,只是没有借用检查器,而且据我所知,它比 Rust 更早

Swift 很有趣,使用起来非常愉快。然而,我认为可能会阻碍它的是,即使它在 Windows 和 Linux 上得到支持,我不知道有任何跨平台网络 api 能够允许 tcp 或 udp 服务器。尽管其出色的 C 互操作确实意味着可以使用像 SDL_Net、Enet 或 Mongoose 这样的东西

对 Nim 编程语言的评价

Nim 很酷

它与 Go 类似,拥有许多内置库。我会说 Nim 与 C 的互操作更容易,因为类型更接近 C。在 Nim 中,数组与 C 数组相同,所以没有像 Go 中那样的不安全切片包装的问题

我会说,Nim 在总体上比 Go 更适合图形处理,然而,到目前为止,我测试的没有什么能比 Go 的简易并发性更好。所以,除了高度并发的网络处理之外,我会说我实际上更喜欢 Nim 而不是 Go

此外,Nim 的模块系统在我看来比 Go 的更好。Go 的系统需要特定的文件布局,当在 github 上测试仓库并推送和拉取时,我发现我必须确保 Go 没有缓存更改并使用了最新的提交,我经常忘记如何做,然而 Nim 就像 Python 一样,你只需导入文件,它就是导入路径中的文件

就你能做的事情而言,Nim 是一种比 Go 更复杂的语言,但实际上我发现,比如宏的复杂性似乎并不真正显现。如果你在学习宏,它们确实很复杂,但它们存在于许多地方,可以在不一定知道它们是如何实现的情况下使用

回到 Nim 的 C 互操作,你确实需要编写绑定,然而,可以通过 nimble 包管理器安装的 c2nim 工具非常出色。我能够非常容易地为 emoon 的 minifb 库生成 nim 绑定,唯一需要我手动做的是插入一段代码以导入单个结构,然后嵌入链接标志。我会说这比 Go 更好,因为即使 Go 可以通过 cgo 包含 C,但从 Go 与 C 互动通常涉及一些技巧,因为 Go 视 C 为不安全的,因为 Go 对于与 C 代码传递内存回来有严格的规则

Nim 代码可以直接编译为 Javascript 是很酷的功能

有趣的是,我会说,总的来说,Nim 是一种比 Go 更好的语言,比如,当涉及到与 C 的互操作时,也许是语法美学,如果你关心这个的话(我不是很在意),还有其模块系统的优点是很明显的,Nim 也感觉非常通用。它绝对是一种通用语言,并没有在任何领域真正脱颖而出。而 Go 在网络、并发、编译时间和简单性方面表现出色,尽管它带来了一些烦恼,比如它的 C 互操作,至少它有存在的理由

Nim 是一种很酷的语言,不要误会,但它似乎没有存在的理由。Nim 使大多数事情变得更容易(至少比 C 和 C++ 容易),但它并不一定使任何事情变得很棒。我会说,Nim 适合那些想要编译型编程语言并非常关心代码外观的人。我的意思是,我必须说,我认为 Nim 是许多编程语言中代码外观最好的语言

对多种编程语言的排名

编程语言图形功能排行榜

Place Language Notes
1 Odin Odin 内置了 Opengl、Metal、DirectX 11 & 12、Vulkan 和 WebgL 1 & 2 库。该语言还内置了数组组件操作,可用于基本向量数学,作为内置矩阵和四元数类型和库,其中包含所有游戏数学,您必须在其他语言中将其作为单独的库安装。它内置了与 SDL net 和 Enet 的绑定,用于联网。我认为使用 Odin 和 OpenGL 的 wasm 并不太难,您只需要使用 WebGL 库,而不会 OpenGL 库应该被条件导入的麻烦。我还没有专门尝试过这个,但我相信它在大多数情况下都会起作用
2 C++ 显然,几乎所有库都是用 C 或 C++ 编写的。它之所以没有排在第一位,唯一的原因是 Odin 链接标志嵌入在库中,因此您不必像在 C++ 中那样担心构建标志,而且 Odin 内置了对向量、矩阵和四元数的支持。但如果您不介意编写简单的 makefile,并且编写或获取向量和矩阵之类的库,C++ 当然还是不错的。此外,C++ 的 wasm 支持与 OpenGL 和 SDL 配合使用,只需更换编译器,使用 emscripten 而不是普通编译器。对我个人而言,Emscripten 的缺点是您会得到一个很大的包。当我说包很大时,它不是关于大小而是复杂性,emscripten 以特定的方式做事。它仍然非常易于使用,事实上,它是桌面和 Web 跨平台图形的最佳选择
3 Nim 除了 Nim 的 C 互操作性非常好,因此使用图形 API 也很简单之外,没有太多可说的。它确实有一个非常全面的库 NimGL,它不仅提供 OpenGL 绑定,还提供:GLFW、Vulkan 和 ImGui。对于 Web,Nim 与 Emscripten 一起使用,因为它可以编译为 C,但 Nim 还具有对编译到 JavaScript 的一流支持,并且 Nim 网站的首页实际上有一个由语言创建者用 JS 编写的贪吃蛇游戏
4 Go 一旦你完成了一些 C 互操作的设置,Go 就相当不错了。此外,你可以使用 C 类型而不是 Go 类型来更轻松地与 C 进行通信。例如,如果你想将一些浮点数传递给 openGL,使用 C.float 而不是 Go 的浮点数会非常容易。Go 还可以很好地与 Wasm 配合使用,甚至它的并发性也可以与 GopherJSTinyGo 配合使用
5 D 如果我们只谈论不支持 Web 的桌面,D 可以说是排名第二,要么与 C++ 并列,要么取代 C++。D 的 dstep 工具和 importc 语言特性使与 C 的互操作变得非常容易。它具有与 Odin 类似的组件式数组操作,这很好。对我来说,D 的最大问题是它对 wasm 的支持很糟糕。你实际上只能将它与 betterC 一起使用,这是 D 的有限模式,将其限制为增强的 C 子集。当我询问关于将 D 的 betterC 与 wasm 一起使用的问题时,一位 discord 用户一直将其称为更糟糕的 D,这听起来可能很负面,但却是 100% 准确的。许多使 D 变得好的东西在更好的 C 中不起作用。总的来说,在桌面上使用 D 很棒,但对于 Web 和 wasm 来说它很糟糕
6 Zig Zig 的 C 互操作性很棒,实际上在大多数情况下它几乎和 C++ 一样简单,而且它与 wasm 配合得很好。我认为 Zig 在图形方面的主要缺点是它的转换语法非常冗长,有点繁琐

编程语言网络功能排行榜

Place Language Notes
1 Go 这并不奇怪。Go 的网络是最好的,不仅因为它有如此多专门为网络构建的内置库,还因为它的并发性如此简单和高效
2 Nim Nim 的异步和多线程不如 Go 的协程并发那么精致,但它们很简单,而且很有效。它的网络也相当简单。它并没有特别引人注目,但它很简单,简单就是好
3 D D 内置了套接字,用于 http 服务器的高级 vibe D 库也有很好的文档记录。D 还具有不错的并行构造。没有太多要说的,因为我实际上没有使用 D 进行网络开发,我只是查看了一些文档和教程。虽然我自己实际上没有做过任何 D 网络开发,但仅从 Dlang 网站和 Rosetta 代码上的示例我可以看出它使用起来非常简单
4 Odin 尽管没有标准网络,Odin 还是内置了对 SDL_NetEnet 的支持。我没有使用过 Enet,但我确实使用过 SDL net 来编写 Odin 的 echo 服务器示例
5 C++ 当然,如果您不关心跨平台支持,您可以使用 Unix 或 Windows 套接字,但 Asio 真的很棒。它比上面的选项更冗长,但它确实为 C++ 提供了跨平台网络。它还可以作为 C++ 的通用异步运行时。它使用起来非常简单,使用 Asio 重写 echo 服务器也很容易组合在一起
6 Zig Zig 的网络功能实际上非常好,但它没有文档记录,可能要到 1.0 版才会改变。Zig 的创建者 Andrew Kelley 表示,适当的文档记录将在 1.0 版中出现,这是一个合理的计划。我认为一旦 Zig 的网络功能记录下来,它就会轻松升至此列表的顶部。Zig 的异步功能非常酷,但不完整,而且比 Go 更复杂,所以我认为我不能把它排在第二位以上

编程语言综合排行榜

分数越低越好。Battle 和 Guess Number 等琐碎程序没有分数

lang ppm & png http & json opengl echo server build system platformer pong total
c++ 1 2 2 1 3 1 1 11
go 1 1 4 1 2 todo todo 9
zig 2 3 3 2 1 4 n/a 15
odin 1 6 1 2 2 3 1 16
d n/a n/a n/a 1 n/a n/a 1 tbd
janet n/a n/a n/a 1 n/a n/a 1 tbd
nim n/a 1 n/a 1 n/a n/a n/a n/a
c# n/a 4 n/a n/a n/a n/a n/a n/a
  • Guess Number
  • Http and Json
  • Langton's Ant
  • PPM and PNG
  • Text Battle Simulation
  • Build System
  • Echo Server
  • OpenGL Triangle
  • Mini Platformer - One Lone Coder port
  • Pong

海云青飞 对编程语言的选择

我不是计算机专业出身,也无意通过自学达到专业水准,主要是没有那个时间,其实我对计算机技术是很感兴趣的

我学习一点计算机技术主要是为了打开一个多数普通人未知的世界。我认为,像我这么做,对每个有理想的现代人都是有益的、必要的。特别是集权国家领导人,一定要会一点编程语言,否则,他一个人会影响全国所有人

我选择编程语言主要考虑如下因素:

  • 跨平台支持,至少支持 Windows、Linux、Mac 三个平台

    我平时主要使用 Windows 电脑,但是服务器一般是 Linux 系统,我时间有限,不想学习一种 Windows 上的编程语言后,再去学习一门 良好支持 Linux 的编程语言

    C# 和 Swift 语言的跨平台支持已经在变好,但是 C# 以 Windows 为主,Swift 以 Mac 为主,因此我暂时没有学习这二种编程语言的打算

    Nim 语言的标准库丰富,并且是跨平台的

  • 代码的表达简洁

    • 以缩进组织语句。这样写代码时方便,代码写好后看上去也干净、美观

      Nim 和 Python 语言符合这条要求

    • 语句换行处不需要写 ; 或其他符号表示语句结束

      C 语言因为历史原因就不评论了,近几十年新出的编程语言如果还是强制语句以 ; 或其他符号结束,这就表明编程语言的设计者有点跟不上时代了。这不仅仅是书写和美观的问题,更重要的是屏幕上出现本不需要的符号会干扰人的视觉,影响人的思维

      Nim 和 Go 语言符合这条要求

      同样原理,文章的段落结束处是不需要写 的,不明白这个道理、不这么做的人已经落伍了。你看 海云青飞 官方网站的文章,都是符合这条要求的

  • 对网络开发的支持要好

    单机版的软件只能自己用,做网站的软件可以光速为全球所有人服务,可见网络开发是何等的重要

    如本文原作者所述,Go 和 Nim 对网络开发的支持都很好

综合考虑,目前来说 Nim 编程语言最佳,同时,大家如果有时间还可以了解一下其他编程语言

相关内容


独立思考最难得,赞赏支持是美德!(微信扫描下图)