您现在的位置是:首页 > 文章详情

Nim 语言 1.2 版本发布!向后兼容性增强和新的宏

日期:2020-04-09点击:571

以下由中文社区翻译,能力有限,如有翻译错误,欢迎指正!

在持续六个月的开发后,我们骄傲地宣布,Nim 1.2 版本发布了!

本发行版包含了超过 600 次的尚未被合并到 1.0.x 版本的提交。 与 1.0 相比,添加了几个新功能和标准库。 我们努力将断崖式的改动降至最低, 但如果不进行这些必要的更改,某些错误是无法被修复的, 而且我们认为我们的用户将从中受益。

我们建议所有用户升级和使用 1.2 版本。

使用多个版本的 Nim

useVersion

如果你想要更新到 v1.2 版本,但依赖与 v1.0 版本的一些行为, 你可以使用命令行参数 --useVersion 来切换。 在最新的 Nim 中,你可以用这个参数来模拟之前版本的 Nim 。

举个例子,v1.2 版本的 Nim 对 proc 类型的类型转换变得更加严格。 如果这个变更无法兼容你的代码,你可以使用 --useVersion:1.0 来模拟之前版本的行为。

上面的例子只是个示例。 如果你依赖于一些边缘案例,或现已修复的错误行为,试试 --useVersion:1.0 ,他可能返回你想看到的结果。

如果没有得到你想要的之前版本的行为,请打开在 我们的 bug 追踪器 上提个 issue , 我们会努力在未来的 bug 修复版本(1.2.x)中进行修复。

when declared

如果你开发了 Nim 的库,而且想让不管是用 v1.0 的还是 v1.2 版本的用户都能使用你的库, 但却依赖了一些在 v1.0 版本没有,而在 v1.2 版本中才加入的新特性, 你可以使用 when declared 作为你的优势。

举个例子, sequtils 模块现在加入了 unzip 过程。 你就可以把你的代码写成下面这样:

 import sequtils when not declared(unzip): proc unzip*[S, T](s: openArray[(S, T)]): (seq[S], seq[T]) = result[0] = newSeq[S](s.len) result[1] = newSeq[T](s.len) for i in 0..<s.len: result[0][i] = s[i][0] result[1][i] = s[i][1] let a = @[('a', 1), ('b', 2), ('c', 3)] let b = unzip(a) # version 1.0 将会使用上方声明的过程 # version 1.2 会直接使用 sequtils 模块的过程 assert b == (@['a', 'b', 'c'], @[1, 2, 3]) 

安装 Nim 1.2

Nim 的新用户

检查你系统的包管理器是否已经装载了 1.2 版本, 或者按照 这里 的说明进行安装。

老用户

如果你之前使用 choosenim 安装过老版本的 Nim , 升级到 1.2 版本就这么简单:

 $ choosenim update stable 

为 v1.2 贡献力量

我们的贡献者都是超人, 我们列举了很多到 这里。 给你们个大大的么么哒,没有你们就没有这个版本!

新特性

GC: ARC

我们这次版本主要的新特性是 --gc:arc !

为了避免陷入本文中大量的细节, 我们建议你查看下 FOSDEM上的这个视频(YouTuBe), Araq 在视频中解释了 ARC 背后的详细信息,并展示了一些显示其优点的基准。 之后可能会更新一篇关于 ARC 详细说明的文章。

新的宏语法糖

1.2.0 版本介绍了一些新的宏,它们应该可以帮你完成一些通用的任务。

在接下来的一些章节中,我们会给你展示他们和他们的用例。 所有的示例都意味着 import sugar

Collect

collect 是一个用以解析序列/集合/表解析的宏。 它替代了 lc (list comprehension,列表解析), 而且比 lc 更人性化和强大。 使用 collect 没有开销,比如说:你可以把 newSeqOfCap 和它配合使用。

所有集合的语法都是类似的,区别在于 init 函数和最后一个表达式。

举个例子:

 let numbers = collect(newSeq): # 或者: collect(newSeqOfCap(10)) for i in 1..10: i assert numbers == @[1, 2, 3, 4, 5, 6, 7, 8, 9, 10] import tables let oddSquares = collect(initTable): for i in numbers: if i mod 2 == 1: {i: i * i} assert len(oddSquares) == 5 assert oddSquares[7] == 49 import sets let oddOrNegative = collect(initHashSet): for i in numbers: {if i mod 2 == 1: i else: -i} assert 5 in oddOrNegative assert 2 notin oddOrNegative assert -2 in oddOrNegative 

Dup

dup 是一个宏,它让原地函数(in-place functions,译者注:引用传递参数的函数) 可以在不影响和修改函数输入的情况下返回结果。

我们是这么考虑的,Nim的未来版本将只提供函数的原地版本 (即不再提供 sortsortedrotateLeftrotatedLeft 等), 他们可以被 dup 转换为返回拷贝的函数。 这些版本可以通过 dup 转换成返回副本的函数。

这个宏也允许了(其他方式的)函数链(function chaining)。

还是看示例吧:

 proc makePalindrome(s: var string) = for i in countdown(s.len-2, 0): s.add(s[i]) var a = "abc" makePalindrome(a) assert a == "abcba" var b = "xyz" var c = b.dup(makePalindrome) assert b == "xyz" assert c == "xyzyx" 

下划线(_)可用于表示传递参数的位置:

 import algorithm # b = "xyz" var d = dup b: makePalindrome # xyzyx sort(_, SortOrder.Descending) # zyyxx makePalindrome # zyyxxxyyz assert d == "zyyxxxyyz" 

Capture

capture 是一个宏,在循环中创建闭包时非常有用, 以捕获一些局部循环变量(按其当前迭代值)。 您可能希望将其用于事件处理和 {int: callBack} 查找表。‎

举例如下:

 import strformat, sugar var myClosure: proc(): string for i in 5..7: for j in 7..9: if i * j == 42: capture i, j: myClosure = proc (): string = fmt"{i} * {j} = 42" let a = myClosure() assert a == "6 * 7 = 42"
原文链接:https://www.oschina.net/news/114765/nim-1-2-released
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章