Crystal 是一种通用的、面向对象的编程语言,由 Ary Borenszweig、Juan Wajnerman、Brian Cardiff 和 300 多名贡献者设计开发。Crystal 的语法受到 Ruby 的启发,属于编译语言,具有静态类型检查功能,但一般不需要指定变量或方法参数的类型,可实现接近 C/C++ 的性能。它的类型由一个先进的全局类型推理算法来解决。
Crystal 1.5.0 已发布,此版本包含了自 1.4.1 版本以来由 23 位贡献者所做的 102 项更改。主要内容如下:
实现抽象的方法的参数DEF
必须与名称匹配
为了提供更好的文档和健壮性,可以将参数与其名称(ref)显式关联:
class Foo
def foo(name : Int32) : Nil
p name
end
end
Foo.new.foo name: 42
因此,考虑参数的名称是其接口的一部分是必须的。然而,在 1.5.0 之前,编译器不会检查抽象方法的实现与其定义之间的参数名称是否匹配。也就是说,以下示例编译时没有错误或警告:
abstract class FooAbstract
abstract def foo(number : Int32) : Nil
end
class Foo < FooAbstract
def foo(name : Int32) : Nil
p name
end
end
从 1.5.0 ( #11915 ) 开始,上面的示例将引发警告:
6 | def foo(name : Int32) : Nil
^---
Warning: positional parameter 'name' corresponds to parameter 'number' of the overridden method FooAbstract#foo(number : Int32), which has a different name and may affect named argument passing
实例变量的方法限制
当一个实例变量被赋值为一个无类型方法参数的值时,该参数被限制为与实例变量共享相同的类型。
例如以下代码:
class Foo
@x : Int64
def initialize(x)
@x = x
end
end
直到 1.4.1,x
ininitialize
都不受限制,但这会导致几个问题:
- 如果用户传递了一个不正确的参数,例如 Foo.new 'a',而不是在参数 'a' 中标记错误,它会指责 x 没有正确的类型。
- 例如,如果我们改为传递 Int32,则不会执行自动转换: Foo.new 1 失败。
- 生成的文档没有提供参数 x 类型的提示。
从 1.5.0 开始,在像 @x = x 这样的赋值中,参数 x 获取了 @x 的类型,有效地解决了上述三个问题。可以从 #12103 中阅读详细信息。
方法参数上允许的注释
现在可以为方法或宏的参数添加注释。作为说明,假设一个 linter 会在未使用参数时发出警告。
def foo(x); end# Warning: argument `x` is not used
然后我们可以向 linter 发出信号,在特定情况下不要警告我们。假设 linter 提供以下注解:
annotation MaybeUnused; end
将其应用于参数会删除警告(在这个特定的虚构 linter 中):
def foo(@[MaybeUnused] x); end# OK
在 #12039 中了解详细信息。
元组的常量索引器
当使用常量索引元组或命名元组时,类型检查器将正确推断所访问值的精确类型(#12012)。
KEY = "s"
foo = {s: "String", n: 0}
# Before 1.5.0 this failed; it would assume the type of foo[key] to be (String | Int32)
puts foo[KEY].size
加强 FILE.TEMPFILE
安全保障
根据 #12076,临时文件的创建不允许在文件名的字符串中使用空字符。
NO_COLOR 合规性
编译器和解释器支持 NO_COLOR 环境变量来禁用终端上的彩色输出。可以通过将任何非空值设置为NO_COLOR
来启用。#11984 中可查看详细信息。
向原生 WINDOWS 支持迈出一大步
Windows 上的并发运行时由功能正常的事件循环 (#12149 ) 支持。这跨越了通往原生 Windows 支持的道路上的一项重要检查。此外,现在有一个与 Windows 兼容的Makefile
( #11773 )。
其他内容可以在更新公告中查阅:https://crystal-lang.org/2022/07/06/1.5.0-released.html 。