ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

MoonBit v0.10.9 版本更新

MoonBit v0.10.9 版本更新 MoonBit v0.10.4版本更新对应moonc版本:v0.10.9语言更新with-pattern 现在需要在使用了 with 的分支显示加上括号便于读者更容易理解with-pattern 的优先级。可以使用moon fmt进行自动迁移fnmain{letaSome(hello)matcha{Some(x)|(Nonewith x)println(x)// ^~~~~~~~~~~~~~~~~~ 需要加上括号}}bitstring pattern 支持 v128le可以从字节序列中一次提取 16 个字节,构造成一个V128值。目前只支持以字节为单位的小端序,即输入的第 0 个字节对应结果的最低位字节fnmain{letbitsBytes::makei(16,ii.to_byte())guard!bits is[v128le(bits),..]println(bits)// 输出 V128(0x0706050403020100, 0x0f0e0d0c0b0a0908)}lexscan正式进入 stable 状态。lexscan支持lexbuf.Lexbuf和lexbuf.AsyncLexbuf以及lexbuf.StringScanner。其中Lexbuf和AsyncLexbuf为 streaming 模式我们对内存占用做了优化可以放心在 infinite stream 上使用此前的lexscanonString/StringView迁移到使用lexmatch关键字现在 catch-all case 在明确不可达的情况下不再需要添加并且编译器会对不可达的 cases 报告警告///|asyncfnwordcount(input:lexbuf.AsyncLexbuf,lines:Int,words:Int,chars:Int,)-(Int,Int,Int){lexscan input{re^\nwordcount(input,lines1,words,chars1)re^[^ \t\r\n]aswordwordcount(input,lines,words1,charsword.length())re^.wordcount(input,lines,words,chars1)re^(lines,words,chars)}}///|asyncfnmain{letutf8_readerUtf8Reader(()stdio.stdin.read_some())letlexbuflexbuf.AsyncLexbuf::from_fn(()utf8_reader.read())let(lines,words,chars)wordcount(lexbuf,0,0,0)println(lines: \{lines}, words: \{words}, chars: \{chars})}具体请参考文档 https://docs.moonbitlang.com/en/latest/language/fundamentals.html#lexmatch,https://docs.moonbitlang.com/en/latest/language/fundamentals.html#lexscan引入了新的errdefer语法errdefer expr rest如果rest抛出了错误或者作为一段异步代码被取消了errdefer就会被触发执行expr然后把错误继续向上抛出。errdefer对于构造器类的函数尤其实用例如asyncfnconnect_to(addr:socket.Addr)-Tcp{letsocketmake_tcp_socket()errdefer socket.close()connect_socket(socket)socket}当connect_to成功返回时socket的所有权会随返回值转移至调用方因此当前作用域无需释放该资源。若connect_socket(socket)执行失败或被取消socket会被丢弃此时若不释放socket就会导致资源泄漏。errdefer适用于此类仅在错误路径上执行清理的场景可用于确保资源得到可靠释放。使用return/break/continue跳出errdefer的范围不会触发errdefer。和defer一样errdefer是结构化的它只会在程序离开整个errdefer表达式的范围时触发。所以下面的程序是错误的letresult[]forxinxs{letresmake_resource(x)errdefer res.close()do_something_with_res(res)result.push(res)}result这里每个errdefer仅在其所在的单次循环作用域内有效。第一次循环正常结束后对应的errdefer即不再生效。当后续循环发生错误时只会执行当前循环对应的清理逻辑此前循环中已成功创建的资源无法得到释放进而导致资源泄漏。正确的写法是letresult[]errdefer result.each(resres.close())forxinxs{letresmake_resource(x)do_something_with_res(res)result.push(res)}resultdefer和errdefer支持raise与async。之前defer expr的expr中不能抛出错误或是调用异步代码。这一限制现在已被解除。如果defer/errdefer中抛出错误新的错误会替代旧的错误。有多条defer/errdefer语句时如果其中某处defer/errdefer抛出了错误剩下的defer/errdefer依然会按顺序执行不会被丢弃。新增将catch迁移至defer/errdefer的警告。目前在moonbitlang/async中被取消的异步程序会抛出一个特殊的错误作为被取消的信号以方便被取消的程序释放资源。但这个特殊错误有可能被意外捕获、转换从而导致程序在被取消时出现错误。未来我们计划不再使用特殊错误来表示取消信号并让catch不再捕获取消信号。但如果程序依赖于catch来执行资源清理这一改动会导致程序在被取消时无法正确释放资源。因此我们引入了errdefer并解除了defer的副作用限制以保证几乎所有资源释放代码都可以用defer/errdefer表达取消信号未来也依然会触发defer和errdefer。为了帮助用户迁移现有的、基于catch的资源释放代码我们提供了一个新的警告fragile_catch_all。它会识别可能可以改写成defer/errdefer的catch表达式并给出警告提示用户迁移。除了在未来能正确处理异步取消之外defer/errdefer本身相比catch也更加可读和健壮。这一新警告可能会出现误报的情况。如果发生了误报可以通过#warnings(-fragile_catch_all)对当前函数临时关闭警告。guard现在会进行完备性检查对于不完备的 pattern 会报警告。对于希望使用之前的guard无法匹配则 panic 的语义的用户应该迁移到guard!来更加明确地表达自己的意图。fnmain{letstringSome(content)guard string isSome(content)// ^~~~~~ Warning (guard_inexhaustive):// This guard pattern is not exhaustive and will panic when// it does not match. Missing cases:// None// To fix: add an else { ... } clause after the condition to// handle those cases, or write guard! if the panic is intended.guard!string isSome(content)// 推荐的新写法println(content)}支持 labelled block给代码块加上标签后,块内可以用break携带一个值提前退出,该值就是整个块的求值结果。fnabsolute(n:Int)-Int{result~:{ifn0{breakresult~(-n)}n}}Labelled block 不存在匿名形式不带 label 的break始终以最近的循环为目标而不会作用于某个 block。为了避免阅读代码时的歧义直接出现在 labelled block 内的不带 label 的break会被视为错误即使外层存在可作为跳转目标的循环。此时必须显式指定 label以明确需要退出的控制流层级。fnf()-Int{for;;{label~:{break1// ^^^^^^^ An unlabelled break is not allowed directly inside a labelled block.}}}增加了新的保留字nocancel#warnings现可作用于语法警告。此前它仅支持屏蔽类型检查阶段的警告deprecated_syntax等语法警告不受影响。现在#warnings已可局部屏蔽大多数警告包括语法警告部分跨顶层定义的警告和词法警告仍不支持。工具链更新默认后端改为 wasm现在moon prove只需要用户安装至少一个支持的求解器 (Z3 / Alt-Ergo / CVC5) 即可直接使用不再需要单独安装 Why3。相应的, 现在 Why3 的data-dir和lib-dir不支持通过环境变量指定始终读取~/.moon/share/why3/和~/.moon/lib/why3/。现在可以通过moonx username/example[version]的方式来执行 mooncakes.io 上面的 WASM executable 默认以 WASM 后端执行可以通过--target native的方式以 native 后端执行$ moonx moonbit-community/moongrep error: the following required argument was not provided:subcommandUsage: moongrepcommandScan MoonBitsourcefiles with structural and taint rules. Commands: scan Scan MoonBitsourcefiles. lint Scan MoonBitsourcefiles with embeddedbuiltinrules. docs Print embedded moongrep documentation. dump Parse a MoonBit impl or expression and print untyped_ast debug output.helpPrinthelpforthe subcommand(s). Options: -h,--helpShowhelpinformation.支持.moonignore文件之前如果用户需要显示指定某些文件是否应该包含在 moon publish 发布到 mooncakes.io 上面的 module 的话需要通过.gitignore配合 moon.mod 中的exclude和include字段来配置修改起来不方便。现在打包时遵守通行的 ignore 文件规则。选择文件夹中的.moonignore或如前者缺失.gitignore作为 ignore 文件。默认忽视.开头文件和文件夹可通过 ignore 文件覆写规则_build文件夹不可覆写规则。excludeinclude字段将被废弃。mooncakes.io 现已禁止上传仅大小写不同的包。此前如user/pkga与user/pkgA这样的包可以同时存在但可能在大小写不敏感的平台上产生冲突因此现在会对这类包名进行限制。标准库更新moonbitlang/coreQuickCheck 更新支持qc.check失败会 raise 一个错误成功则不打印其他东西 和qc.report返回结构化的测试报告两种主要测试函数用户可以传递函数(A) - Bool raise?来进行基于属性的测试可以向测试函数传递filter?: (A) - Bool参数来过滤 Generator 一些不满足要求的值利用参数discard_ratio可以控制测试在丢弃多少比例的时候会失效qc.Generator[T]类型和相关的函数提供了一套常用的组合子可用于辅助构建Arbitrary实例core/quickcheck/shrink包提供了大部分常用类型的 Shrinker 收缩器可在找到反例的时候进行收缩以寻找更小更简单的反例支持统计分析功能可以通过observe?参数给 check / report 传递一个观测组合(A) - Observation其中Observation可以使用如下函数构造qc.label(val: String)标注一个字符串标签qc.classify(cond: Bool, val: String)在条件cond成立的时候打上标签valqc.collect(val : T)把一个值的 Debug Repr 作为标签更多具体细节可以参考文档https://mooncakes.io/docs/moonbitlang/core/quickcheck新增moonbitlang/core/diff包提供通用的两种序列Diff算法Myers和Patience, 用户可以通过diff.Diff(old~, new~).edits()获取两个序列的编辑脚本提供多个计算不同序列编辑距离的函数edit_distance(ArrayView[T]),edit_distance_str(StringView),以及对应的限制最大编辑距离的版本新增moonbitlang/core/lexbuf包提供StringScanner、Lexbuf、AsyncLexbuf 以配合 lexscan 进行使用。StringScanner同步的 String based scanner由 lexscan 维护 scanner 上的 cursor 字段Lexbuf/AsyncLexbufStreaming scannar由Lexbuf::from_fn定义数据源lexscan 过程中会自动 refill。两者区别在于 lexscanAsyncLexbuf的表达式整体是要求 async 上下文的。immut/array包之前已经 deprecate 了很长一段时间现在正式删除应该改用immut/vector。debug.to_repr(x)弃用可改用debug.Repr(x)。moonbitlang/async目前最新版本为 0.21.0自上次月报0.20.2以来的主要更新有[breaking]http包中HTTP headers 的类型从Map[String, String]变成了大小写不敏感的type http.Headers Map[http.CaseInsensitiveString, String]因此构造和读取 HTTP header 时不再需要手动注意大小写问题。http.CaseInsensitiveString可以从String隐式构造因此直接使用Map字面量构造 header 和读取 header 的代码无需修改。但对 header 写了类型标注的代码需要将类型改为http.Headers[breaking]fs.open等 API 的create和truncate参数已被废弃一段时间由create_mode和permission代替。这次更新中create和truncate被正式移除。此外fs.write_file和process.redirect_to_file的默认create_mode从OpenExisting变成了CreateOrTruncate。fs.open的默认create_mode则依然是OpenExisting[breaking]async.protect_from_cancel的默认行为变为resume_on_canceltrueresume_on_cancelfalse选项被废弃。未来只会有resume_on_canceltrue的行为protect_from_cancel(resume_on_cancelfalse)在被取消时会保证内部的代码完整运行然后丢弃其结果并抛出取消信号。这里被丢弃的结果可能导致资源泄露因此是不安全的对大部分用户的代码来说这一行为变动不会产生实质性的影响moonbitlang/async现在会在程序陷入死锁状态例如两个任务互相等待时自动检测到死锁并强行终止程序防止事件循环无限空转。可以通过async.set_deadlock_handler控制死锁时的行为或是关闭死锁检测之前moonbitlang/async必须在主线程中运行自己的事件循环因此无法与其他外部事件循环例如 GUI 框架自带的事件循环整合。本次更新新增了async.set_external_event_loopAPI可以用于设置一个外部事件循环。moonbitlang/async会将自己的事件循环运行在单独的线程里并和主线程的外部循环整合。所有 MoonBit 代码依然会运行在主线程里。关于外部事件循环的实现需要为moonbitlang/async提供哪些 API详见async.set_external_event_loop的文档新增了process.pipeAPI可以用于将一个子进程的输出重定向到另一个子进程的输入process.read_from_process和process.redirect_to_file新增了shared? : Bool false参数。如果sharedtrue用于重定向的输出管道可以被同时传给多个子进程但必须在最后一个子进程启动后通过.close()手动关闭。如果sharedfalse默认行为和之前相同用于重定向的输出管道只能被传给一个子进程但可以同时传给同一个子进程的stdout和stderr不过无需手动关闭新增辅助函数http.request可以用于执行任意方法的单次 HTTP 请求Wasm1 后端新增了websocket和fs.realpath支持现已支持除fs.Watcher外的所有功能在 Linux/MacOS 上当子进程被某个信号终止而非正常退出时process.run等 API 能识别这种情况并返回-signal当一个async fn main程序被信号取消时之前async fn main会在程序释放完资源后以128 signal作为返回值退出bash convention。但这一行为对父进程来说是有歧义的。现在async fn main在被信号取消时会在程序完成清理后重新模拟出当前进程被信号强制中止的状态作为程序的退出状态moonbitlang/x弃用了moonbitlang/sys应该改用moonbitlang/core/envmoonbitlang/x/path现在可以在浏览器环境正常使用Windows 的路径比较现在可以正确处理非 ascii 且有大小写形式的字符。moonbitlang/x/rational现在不会出现溢出误判和分母零问题。
返回列表