Hoey
2025 年5 月 19 日 10:26
1
2025-05-19
语言更新
x..f(..) 的语义即将发生改变,在 ./… 调用链末尾的最后一个 … 以后会自动丢弃它的值。因此,下面的代码:
impl[X : Show, Y : Show] Show for (X, Y) with output(self, logger) {
logger
..write_string("(")
..write_object(self.0)
..write_string(", ")
..write_object(self.1)
// 原本,这里必须写 `.`,否则整个 `.` 链的类型是 `&Logger`,不符合预期类型 `Unit`
.write_string(")")
}
以后可以简化成
impl[X : Show, Y : Show] Show for (X, Y) with output(self, logger) {
logger
..write_string("(")
..write_object(self.0)
..write_string(", ")
..write_object(self.1)
// 以后可以直接一路 `..` 到底了
..write_string(")")
}
但这也意味着直接使用 x..f() 的值的用法将会被废弃,需要显式保存x。例如,下面的代码:
let arr = []..push(1)..push(2)
需要改写成:
let arr = []
arr..push(1)..push(2)
moonbit-lang 枚举构造器和结构体的字段支持单独的文档注释,在补全时会显示相应的文档。
///| Location enum
struct Location {
/// X coordinate
x : Int
/// y coordinate
y : Int
}
///| Variant enum
enum Variant {
/// Stirng constructor
String(String)
/// Number constructor
Number(Double)
}
@bytes.View 和 @string.View 在 C 和 wasm1 后端现在会被编译成值类型,这意味着这两个类型不会引入内存分配,性能有较大提升
工具链更新
vscode 插件支持semantic token, 会对有effect的函数(会抛出异常的函数, 异步函数)调用使用不同的样式高亮.
构建系统支持 virtual package 特性,通过将一个 package 声明为虚拟包,定义好一套接口,用户可选择具体使用哪一份实现,如不指定则使用该虚拟包的默认实现。通过这项特性,给分离接口与实现带来较大灵活性。注意:目前这项特性处于实验性状态。详情请查看:MoonBit 新特性:Virtual Package 虚拟包机制
支持对于单个 .mbt 和 .mbt.md 文件的 test 和 debug codelen
2 个赞
tiye
2025 年5 月 20 日 17:30
2
寄. 问一下原来的写法,
{}..set(Input, f1)..set(Change, f2)
之前会返回最终的对象, 现在结果会被丢弃. 有什么简短的写法?
如果 key 都是字符串是有很简单的写法的, 但是这里 Input 跟 Change 都是 enum 里的 Constructor, 有什么语法? 也能自行做类型推断的.
我看着好像没影响呀,不是仍然可以根据下文进行自动推断吗?
///|
enum Event {
Input
Change
} derive(Eq, Hash)
///|
fn init {
let f1 = fn() { }
let f2 = fn() { }
let a = {} // 可以自动推导出 Map[Event, () -> Unit]
a..set(Input, f1)..set(Change, f2)
}
tiye
2025 年5 月 21 日 05:06
5
我需要的直接拿到这个表达式的返回值, 原来的返回值就是修改以后的 a. 现在这个返回值不是被丢弃了吗. 拿不到了.
我看你的意思应该是 respo.mbt/src/main/panel.mbt at main · Respo/respo.mbt · GitHub 这个仓库里头这种写法吧。
感觉可以考虑改成 [(Input, f1), (Change, f2)] 这样的表达式替代吧。
不过话说回来x..f()这个破坏性更新的问题,我觉得应该提供一个语法糖来向下兼容,比如x..self
tiye
2025 年5 月 21 日 06:53
7
是啊. 暂时用 Map::of([]) 应该可以. 不过 Map 本身有使用 {"a": 1} 这样的语法, 如果能对于任意数据类型用也省事. 试了试没试出来.
要不加个helper function吧:
fn events(click? : (Event) -> Unit, dbclick? : (Event) -> Unit, ...) -> Map[(EventType, Callback)] {
...
}
tiye
2025 年5 月 21 日 15:09
9
嗯我考虑下方法. 总体上高频用到的写法, 总还是指望短一点.
tiye
2025 年5 月 22 日 05:40
11
gaubee:
按照你的需求,前面提到的方案 type Events[X,Y] Array[(X, Y)] + [(Input, f1), (Change, f2)] 我觉得是更好的替代,同时 Array 方案也有额外的好处,就是可以Key可以多次重复,但视觉上可能没有map来得干净,同时属于破坏性更新
嗯这个也可以试试. 不过最后估计还是看我的偏好了. 前面的版本因为是从 ClojureScript 最早实现的用了 hashmap, 也方便做 diff, 所以就沿用下来了. 我如果通过 Array[Tuple] 去初始化 hashmap, 使用的感觉差异不太大.
就是说这里的 .event(...) 方法返回的是 Element, 而不是 Unit 对吧. 这个主要的感觉是跟已有的用法差异比较大, 不倾向于这个.
gaubee:
按照你的需求,非要使用Map的话,我自己感觉用 ..set 其实也不算符合直觉的追加方案,因为它是指令式地去构建map,不是一次性把内存非配好的感觉。
整体确实也不符合直觉. 最初想的是找一个 2 的字面量语法, 没找到所以用了这个备用的方案. 但并不算是契合的.
tiye
2025 年5 月 23 日 04:07
12
索性改成了标签参数把 hashmap 藏到内部去,
"prompt-modal",
effects=[
// (effect_focus_data as @node.RespoEffect).turn_effect(),
effect_modal_fade_data,
],
div(style=respo_style(position=Absolute), [
if show {
div(
class_list=[ui_fullscreen, ui_center, css_backdrop],
style=options.backdrop_style,
on_click=fn(e, dispatch) {
if e is Click(original_event~, ..) {
original_event.stop_propagation()
}
on_close(dispatch)
dispatch.empty_state!(cursor)
},
[
div(
class_list=[ui_column, ui_global, css_modal_card],
style=respo_style(line_height=32.0 |> Px)