类Ruby编译型编程语言-Crystal
2023-02-26 17:03:03 阿炯

Crystal 是一种通用的、面向对象的编程语言,由 Ary Borenszweig、Juan Wajnerman、Brian Cardiff 和 300 多名贡献者设计开发。其语法受到 Ruby 的启发,属于编译语言,具有静态类型检查功能,但一般不需要指定变量或方法参数的类型,可实现接近 C/C++ 的性能。它的类型由一个先进的全局类型推理算法来解决。跨平台运行并在ApacheV2协议下授权。


它是一群热爱 Ruby 的人创建的,最初的编译器是由 Ruby 实现的(指对 LLVM 绑定的前端)。早期的 Crystal 是高度兼容 Ruby 语法(和语义)的,以至于编译器用 Crystal 重写的时候只需要进行少量修改便能成功移植。不过这也是早在多年前就完成的历史了。虽然现在的 Crystal 有了些许自己的新语法,不过无论走多远,Ruby 程序员的亲切感都是不会丢失的。毕竟它的宣传语至今还是这么写的:Fast as C, slick as Ruby因为 Ruby 真的太慢,从最开始用 Crystal 重写编译器的进程其实就是在同步进行的。

Crystal 在多门语言上取过经,包括 Ruby/Rust 和 Go。注意 Rust 取经主要在编译器后端的方面,跟语言设计无关,跟 GC 更加无关。目前依赖了例如 libssl 和 libevent 这样的 C 库来作为其基础。这些限制导致了如下的不足:不适合开发客户端,仅靠单线程就能满足的客户端类型是少见的,CPU 密集计算功能太常见无法进入嵌入式领域,因为平台和交叉编译的支持都不健全即便是服务端应用也无法充分利用 CPU,需要单机多进程部署。

特点
具备 Ruby 的语法和灵活性
便捷的 C 绑定
简单易用的并发模型


最新版本:1.8
1.8.0 已于2023年4月中旬发布,此版本的一些修改:
本版本中的一个重大且必要的更改是 PCRE2 成为 Regex的默认引擎。1.7 中添加了对 PCRE2 的支持,并在 1.7.3 中稳定下来。官方认为默认使用它是安全的,仍然可以回退到 PCRE,如果 PCRE2 在编译时不可用则自动回退,或者通过编译器标志 -Duse_pcre 回退。从 1.8 开始,Crystal 编译器应使用 PCRE2 构建以确保一致性。作为简化向 PCRE2 迁移的措施, Regex::Options 获得了更多可在两个引擎版本中工作的命名成员。为了容纳额外的值,枚举基类型从 Int32 更改为 UInt64)。此外,添加了一个新的枚举 Regex::MatchOptions 来保存特定于匹配操作的选项, Regex::Options 现在别名为 Regex::CompileOptions ( #13248 )。不推荐使用匹配方法的 Regex::Options 重载。

正则表达式:无效的 UTF,与升级无关,此版本包含影响两个引擎版本的错误修复。 Crystal 的 String 类旨在成为有效的 UTF-8,但并未强制执行,完全可以接受包含无效的 UTF-8。字符串传递给 PCRE 或 PCRE2 时,有必要确保其内容有效。之前没有这样做,库可能会崩溃。现在 Regex.new 和所有匹配方法都会验证字符串,并在它们包含无效的 UTF-8 时引发异常。如果已知字符串是有效的 UTF-8,则 Regex::CompileOptions::NO_CHECK_UTF 和 Regex::MatchOptions::NO_CHECK_UTF 会跳过验证以提高性能。

语言方面增加了对 LLVM 15 的支持,其中包括迁移到 LLVM 的不透明指针,这已证明可以显着提高编译速度。
建议使用 LLVM 15 构建 Crystal 以提高编译性能。此版本放弃了对旧 LLVM 版本的支持,现在需要 LLVM 8 或更高版本。LLVM 16 支持正在开发中。

平台支持方面此版本支持 Android,并在 Windows 中取得了重大进步。AArch64 安卓现在可以使用 Bionic C 运行时 ( aarch64-linux-android ) 以 Android 为目标。在实现 Windows 的完整 stdlib 功能覆盖方面取得了进展。此版本包括一些与符号链接相关的改进,还为 Windows 信号 添加了一个完整的存根。接受了一个补丁来支持 Windows 7 版本。

信号方面在 Unix 系统中,进程间通信(例如终止进程和响应中断)是基于信号的, Crystal 中的 Signal API 用于此。为了支持使用不同机制的操作系统(例如 Windows),有必要使用可移植的 API,从实现中抽象出意图。
Process.on_interrupt 处理中断: SIGINT (Unix) 和 Ctrl+C 或 Ctrl+Break (Windows)。
Process#terminate 获得了一个 graceful 参数。在 Unix 上,它会在 SIGTERM 和 SIGKILL 之间进行选择,而它对 Windows 没有影响,并且不管怎样,其行为都类似于 taskkill /f。
Process::Status#exit_reason 和 Process::ExitReason 以可移植的方式提供有关程序退出状态的信息。

标准库方面修复了 LibC 的一些函数定义,它们在部分场景中使用了错误的类型(例如 Int 而不是 SizeT ),这会影响在 *-linux-gnu 目标上发送大量网络数据包的错误。

HTTP::StaticFileHandler 现在支持 Range 请求。

Spec 结果使用 pretty_inspect格式化,规范运行器支持 --color 选项。

Enum#includes? 现在需要设置所有位。Enum.[] 是一个新的便捷构造函数,对标志枚举特别有用。它取代了现在已弃用的 Enum.flags。 Enum#inspect 使用 Enum.[]的简洁语法。

Range:当泛型参数为 Nil 时, Range#size 、 #each 、 #sample 在编译时不再出错。例如, (..4).each { } 现在在运行时引发而不是编译失败)。

Indexable 的实现应该是稳定的,即除非显式突变,否则不会改变行为。

更多信息请参考更新公告

官方主页:https://crystal-lang.org/