Nim团队很高兴地宣布,最新版本的Nim 0.18.0版现已发布。 Nim是一个系统编程语言,专注于性能,可移植性和表现力。 安装 0.18.0如果您使用choosenim安装了Nim的早期版本,那么获取Nim 0.18.0就像下面这样简单:
$ choosenim update stable 如果您还没有它,可以按照这些说明进行选择,也可以按照安装页上的说明手动安装Nim。请注意,Windows用户使用安装页面中描述的unimp + finish.exe安装Nim方法的时间可能仍然更短。
0.18.0中的新功能
自从我们上次发行以来已经有一段时间了,但我们一直很忙。自上次发布以来,超过1000次提交,v0.18.0是Nim的最大版本之一。
我们多次提到这将是一个主要版本。主要是因为我们的目标是为了准备v1.0而清理标准库。我们在这个版本中取得了巨大的进步,以实现这一目标。不利之处在于,这个版本比正常版本有更大的突破性变化,但这都在更干净的Nim v1.0的精神之中。
需要注意的突破性变化
你会发现当一个分片的索引操作符超出边界时,会引发一个IndexError异常。以前它只会返回被捕获的字符串部分。你可能会发现你的程序没有考虑到这个问题,现在会因IndexError异常而崩溃。要恢复以前的行为,请使用substr procedure 。这是一个问题的例子,以及如何解决它:
var myString = "hello world" doAssertRaises IndexError: discard myString[6 .. 45] doAssert myString.substr(6, 45) == "world" $操作符现在处理集合的方式不同。例如:
doAssert $(@["23", "12"]) == "@[\"23\", \"12\"]" # Whereas in 0.17.2: doAssert $(@["23", "12"]) == "@[23, 12]" 数组[x,char]不能再转换为cstring类型。在数组上定义$会有副作用:
var x: array[5, char] doAssert $x == r"['\x00', '\x00', '\x00', '\x00', '\x00']" 请务必查看下面的更新日志以获取重大更改的完整列表。如果遇到任何奇怪的回归,可随意进入IRC,Gitter,Discord或我们提供的任何其他聊天室/论坛。链接到他们都可以在我们的社区页面。
新功能格式化字符串Literal
最大的新增功能是strformat模块。它实现了与Python 3的f-字符串非常相似的字符串格式。
格式化字符串用fmt前缀或&操作符 import strformat let name = "Fred" let age = 24 let weight = 94.52 doAssert fmt"My name is {name}. I'm {age} years of age and weigh {weight:.3f}." == "My name is Fred. I'm 24 years of age and weigh 94.520." 关更多信息,请查看strformat文档。 可测试的文档样例文档生成器现在可以测试示例。这是使用新的runnableExamples宏完成的。
proc add*(x, y: int): int = ## Adds two numbers together. ## ## Examples: ## runnableExamples:
doAssert add(5, 5) == 10 doAssert add(-5, 2) == -3 x + y 如果将其保存为addLib.nim,然后通过nim doc addLib.nim生成其文档,则应该看到如下所示的内容: Hint: /tmp/addLib_examples [Exec]
Hint: operation successful (13129 lines compiled; 0.492 sec total; 19.742MiB peakmem; Debug Build) [SuccessX] runnableExamples下的代码将嵌入到procedure的文档中。
如果示例中存在错误,那么将在运行时发现错误以及堆栈信息。这对确保您的文档保持最新非常有用。
mapLiterals这是一个新的宏,它允许您轻松创建数组和序列文字。
import sequtils let x = mapLiterals([12, 34, 15, 1], uint32)
doAssert x is array[4, uint32] 新的内存管理器算法 新的TLSF算法用以减少内存碎片。这会产生alloc和dealloc O(1)操作的副作用。 异步改进对stdlib中的异步IO模块进行了多种改进。不再有"upcoming"和标准asyncdispatch拆分,前者被合并,是现在默认的asyncdispatch实现。
一个新的getIoHandler过程现在可用,它返回一个到底层IO Completion Port的句柄或asyncdispatch使用的epoll / kqueue fd。这样做的主要优点是库现在可以更好地控制事件循环。例如,它允许更高效的HTTP服务器实现(一个这样的实现称为httpbeast)。
还为asyncjsmodule中的JavaScript后端添加了异步等待的新实现。
Nimble v0.8.10在发行版中也是对Nim软件包管理器的更新。包含最新版本的Nimble,并包含多项新功能和错误修复。
主要的新功能是在单个Git / Hg存储库中支持多个Nimble包。
查看自Nimble上一次发布以来更改列表的更改日志。
v0.18.0的贡献者们
我们的贡献者都很棒,并且有太多可以列在这里。非常感谢大家,如果没有你,我们不可能推出这个版本!
Changelog影响后向兼容性的变化 标准库的突破性变化 当指定的切片超出边界时,字符串的[] proc现在会引发IndexError异常。有关更多详细信息,请参阅问题#6223。您可以使用substr(str,start,finish)返回旧行为,请参阅此提交的示例 具有空字符串和分隔符的strutils.split和strutils.rsplit现在返回该空字符串。见问题#4377。 字符数组不能转换为cstring了,指向字符数组的指针可以!这意味着数组$可以最终存在于system.nim中,并做正确的事情。这意味着$ myArrayOfChar改变了它的行为!使用-d:nimNoArrayToString进行编译以查看修复代码的位置。 reextended不再是re模块中重构构造函数的默认值。 对于所有标准库集合,$的行为已被更改。集合到字符串的实现现在执行适当的引用和转义字符串和字符。 采用AsyncFD的newAsyncSocket现在在fd上运行setBlocking(false)。 mod和bitwise,不再生成范围子类型。事实证明,这样做比帮助更有害,而且没有这种特殊的打字规则,语言就更简单了。 formatFloat / formatBiggestFloat现在支持用零精度数字格式化浮点数。以前的precision = 0行为(默认格式)现在可通过precision = -1获得。 从stdlib移到Nimble包: Proc toCountTable 现在生成一个CountTable,其值与输入中键的出现次数相对应。它用于生成一个所有值都设置为1的表格。 计算序列中的出现次数为: let mySeq = @[1, 2, 1, 3, 1, 4] var myCounter = initCountTable[int]() for item in mySeq:
myCounter.inc item 现在,你可以简单的做到 let mySeq = @[1, 2, 1, 3, 1, 4] myCounter = mySeq.toCountTable() 如果在OpenSSL 1.0.x中使用--dynlibOverride:ssl,则必须定义openssl10符号(-d:openssl10)。默认情况下,假定OpenSSL 1.1.x。 newNativeSocket现在被命名为createNativeSocket. newAsyncNativeSocket现在被命名为createAsyncNativeSocket 它不再引发OS错误,但在创建失败时返回osInvalidSocket。 现在不推荐使用securehash模块。而是导入std / sha1 readPasswordFromStdin proc已经从rdstdin移到了terminal模块, 不再依赖linenoise。
编译器的突破性变化
\ n现在只有单行换行符,就像大多数其他编程语言一样。新平台特定的换行符转义序列写为\ p。此更改仅影响Windows平台。 重载规则略有改变,因此受约束的泛型比无约束的泛型更受欢迎。 (Bug#6526) 我们改变了阵列如何实现“从后向”如[^ 1]或[0 .. ^ 1]。这些现在纯粹在没有编译器支持的情况下在system.nim中实现。有一个新的“异质”切片类型系统。HSlice采用2个可以是BackwardsIndex索引的通用参数。 BackwardsIndex由系统生成。^。这意味着如果你重载[]或[] =你需要确保他们也可以使用system.BackwardsIndex(如果适用于访问器)。 if表达式的解析规则已更改,以便在分支中允许多个语句。我们发现很少的代码示例现在因为这种改变而失败,但是这里有一个: t[ti] = if exp_negative: '-' else: '+'; inc(ti) 现在需要写成: t[ti] = (if exp_negative: '-' else: '+'); inc(ti) 点(.)的实验性重载。操作符现在采用一个非类型化的参数作为字段名称,它曾经是一个static[string]。定义时可以使用(nimNewDot)使您的代码可以同时使用旧版和新版Nim。有关更多信息,请参阅特殊运营商。 在数组,seq或对象构造函数中yield (或等待映射到yield的值)从未可靠工作 ,现在在编译时被阻止。
增添库添加了sequtils.mapLiterals,以便更容易地构建数组和元组文字。 增加了system.runnableExamples,使得Nim文档中的示例更易于编写和测试。这些例子是作为nim doc的最后一步进行测试的。 在asyncdispatch模块中实现getIoHandler proc,它允许您在指定的调度程序中检索底层 IO Completion Port 或Selector[AsyncData]对象。 对于字符串格式化/插值,称为strformat的新模块已添加到stdlib中。 选择器模块中的ReadyKey类型现在包含一个errorCode字段,以帮助区分Event.Error事件。 实现了一个在NativeSocket中的SocketHandle上运行的accept proc。 添加 algorithm.rotateLeft. 添加 typetraits.$作为 typetraits.name的别名. 添加了system.getStackTraceEntries,它允许以结构化的方式访问堆栈跟踪,而无需解析字符串 . 添加 parseutils.parseSaturatedNatural. 添加 macros.unpackVarargs. 使用asyncjsmodule添加了对JavaScript后端异步编程的支持。 对某些终端添加真色彩支持. 样例: import colors, terminal const Nim = "Efficient and expressive programming." var fg = colYellow
bg = colBlue int = 1.0 enableTrueColors() for i in 1..15:
styledEcho bgColor, bg, fgColor, fg, Nim, resetStyle int -= 0.01 fg = intensity(fg, int)
setForegroundColor colRed
setBackgroundColor colGreen
styledEcho "Red on Green.", resetStyle
Library changesecho现在可以处理包含\ 0的字符串(二进制零不显示),零字符串等于空字符串。 JSON:弃用getBVal,getFNum和getNum以支持getBool,getFloat和getBiggestInt。还增加了一个新的getInt过程。 有理数。 toRational 现在使用基于连续分数的算法。这意味着它的结果更精确,并且不能再陷入无限循环。 os.getEnv 现在接受一个默认的可选参数,告诉getEnv 如果环境变量不存在返回什么. random.nim中的随机过程都已被弃用。而是使用新的rand procs。模块现在将随机数发生器的状态输出为Rand类型,这样多个线程就可以轻松使用它们自己的不需要锁定的随机数发生器。有关此重命名的更多信息,请参见问题#6934 writeStackTrace现在被宣称不具有IO效果(即使它的作用),以便它对调试更有用。 db_mysql 模块: DbConn 现在是一个独立的类型,不会公开底层PMySQL的细节。 parseopt2 废弃,改为使用parseopt。
语言添加
现在可以前置声明对象类型以便交互递归类型可以跨模块边界创建。更多信息见 package level objects . 添加VM(编译时和nimscipt)相同比特大小整型之间的强制类型转换。 这允许除其它事项外,有符号整数将重新解释为无符号。 自定义 pragmas 现在通过使用pragma pragma支持, 详见语言手册。 标准库模块现在可以通过std标准伪目录导入。这对于区分标准库和nimble包导入很有帮助。 import std / [strutils, os, osproc] import someNimblePackage / [strutils, os]
语言变化
双目运算符< 废弃, 对 .. < 使用 ..< 对其它使用pred proc. for循环体现在有自己的作用域: for i in 0..4: let i = i + 1 echo i 为了使Nim更加稳健,系统迭代器 .. 和 countup 现在只接受一个泛型类型T. 这意味着下面的代码不会再因为out of rang 错误挂掉: var b = 5.Natural var a = -5 for i in a..b: echo i atomic and generic 不再是Nim的关键字。 generic之前是concept的别名, atomic没有使用过。 内存管理器现在使用具有更好内存碎片行为的TLSF变体算法。根据http://www.gii.upv.es/tlsf/ 测得的最大碎片率低于25%. 是alloc和dealloc成为O(1)操作的一个额外好处。 编译器现在在对待模糊符号时更加一致:遮蔽proc的类型会被标记为模糊的,反之亦然 (bug #6693). codegenDecl pragma 现在适用于JavaScript后端。它为函数返回类型占位符返回一个空字符串。 noreturn pragma对proc额外的语义检查: 返回类型不被允许, 调用 noreturn procs 后的语句不再被允许. Noreturn proc 调用和发起的异常分支现在在if和case表达式通用类型推断中会跳过。下面的代码片断现在可以编译 import strutils let str = "Y" let a = case str: of "Y": true of "N": false else: raise newException(ValueError, "Invalid boolean") let b = case str: of nil, "": raise newException(ValueError, "Invalid boolean") elif str.startsWith("Y"): true elif str.startsWith("N"): false else: false let c = if str == "Y": true elif str == "N": false else: echo "invalid bool" quit("this is the end") Pragmas 现在支持调用语法, 例如: {.exportc"myname".} and {.exportc("myname").} 废弃的pragma 对procs现在支持用户自定义的警告信息。 proc bar {.deprecated: "use foo instead".} = return
bar()
工具变化nim doc命令现在是nim doc2的别名,文档生成器的第二个版本。老版本1仍然可以通过新的nim doc0命令访问。 Nim的 rst2html 命令现在通过:test: RST扩展支持代码片断测试 .. code-block:: nim
:test:
# shows how the 'if' statement works
if true: echo "yes"
BugfixesFixed “ReraiseError when using try/except within finally block” (#5871) Fixed “Range type inference leads to counter-intuitive behvaiour” (#5854) Fixed “JSON % operator can fail in extern procs with dynamic types” (#6385) Fixed ““intVal is not accessible” in VM” (#6083) Fixed “Add excl for OrderedSet” (#2467) Fixed “newSeqOfCap actually doesn’t reserve memory” (#6403) Fixed “[Regression] Nim segfaults” (#6435) Fixed “Seq assignment is slower than expected” (#6433) Fixed “json module issues with empty dicts and lists” (#6438) Fixed “mingw installed via finish.exe fails to link if Nim located in path with whitespace” (#6452) Fixed “unittest.check does not perform short-circuit evaluation” (#5784) Fixed “Error while concatenating an array of chars.” (#5861) Fixed “range initialization: [ProveInit] hint: Cannot prove that” (#6474) Fixed “scanf can call procs with side-effects multiple times” (#6487) Fixed “gcsafe detection problem” (#5620) Fixed “C++ codegen: mitems generates invalid code.” (#4910) Fixed “strange runtime behavior on macOS” (#6496) Fixed “stdtmpl: invalid indentation after a line ending in question mark” (#5070) Fixed “Windows: NAN troubles on c backend” (#6511) Fixed “lib/nim/system/cellsets.nim(33, 31) Error: type mismatch while attempting to compile for 16bit CPUs” (#3558) Fixed “Can’t compile dynlib with -d:useNimRtl and --threads:on” (#5143) Fixed “var s = @[0,1,2,…] can generate thousand of single assignments in C code” (#5007) Fixed “echo discards everything after a null character” (#1137) Fixed “Turn off reExtended by default” (#5627) Fixed “Bad Links in docs/backends.html” (#5914) Fixed “Index out of bounds error in db_postgres when executing non parameter-substituted queries containing “?”” (#6571) Fixed “Please add pipe2 support to posix stdlib” (#6553) Fixed “Return semantics vary depending on return style” (#6422) Fixed “parsecsv.open reports SIGSEGV when calling ‘open’ on missing file” (#6148) Fixed “VCC: Nim generates non-compilable code for system.nim” (#6606) Fixed “Generic subtype matches worse than a generic” (#6526) Fixed “formatFloat inconsistent scientific notation” (#6589) Fixed “Generated c code calls function twice” (#6292) Fixed “Range type inference leads to counter-intuitive behvaiour” (#5854) Fixed “New backward indexing is too limited” (#6631) Fixed “Table usage in a macro (SIGSEGV: Illegal storage access.)” (#1860) Fixed “Incorrect deprecation error” (#6634) Fixed “Wrong indices in arrays not starting with 0” (#6675) Fixed “if expressions” (#6609) Fixed “BackwardsIndex: converter + [] + unrelated type[^1]: lib/system.nim(3536, 3) Error” (#6692) Fixed “BackwardsIndex: converter + [] + unrelated type[^1]: lib/system.nim(3536, 3) Error” (#6692) Fixed “js backend 0.17.3: array bounds check for non zero based arrays is buggy” (#6532) Fixed “HttpClient’s new API doesn’t work through a proxy for https URLs” (#6685) Fixed “isServing isn’t declared and isn’t compiling” (#6707) Fixed “[Regression] value out of range” (#6710) Fixed “Error when using multisync macro” (#6708) Fixed “formatFloat inconsistent scientific notation” (#6589) Fixed “Using : (constructor arguments) for passing values to functions with default arguments causes a compiler crash.” (#6765)
详情请查看发布说明。 |