2024-11-18
MoonBit更新
- trait 新增 abstract 和 pub(readonly) visibility
- 在当前包内,abstract/readonly trait 和一个完全公开的 trait 表现相同;
- 在当前包外不能直接调用 abstract trait 里的方法,且不能给 abstract trait 写新的实现;
- pub(readonly) 的 trait 在外部不能实现,但可以直接调用方法;
- trait 的默认可见性从私有变成 abstract。定义一个私有 trait 要写
priv trait
; - 实现一个 abstract/readonly trait 时,如果想要外部也可以使用这个实现,至少有一个方法需要用
impl Trait for Type
的形式实现。
下面是一个 abstract trait 的例子:
trait Number {
add(Self, Self) -> Self
}
pub fn add[N : Number](x : N, y : N) -> N {
Number::add(x, y)
}
impl Number for Int with add(x, y) { x + y }
impl Number for Double with add(x, y) { x + y}
使用 moon info
生成 .mbti
接口文件,可以看到上述定义对外的接口是:
trait Number
impl Number for Int
impl Number for Double
fn add[N : Number](N, N) -> N
因此,外部只能对 Int
和 Double
调用 add
函数。编译器会保证 Number
在任何时候都只能被 Int
和 Double
实现。
- 调整类型和 trait 的可见性
为了鼓励使用 readonly 的类型/trait、提供更健壮的 API,我们计划在未来将类型定义和 trait 的 pub
可见性的语义修改为默认 readonly。如果想要获得完全公开的可见性,类型定义需要写 pub(all) struct/enum/type
,trait 需要写 pub(open) trait
(表示这个 trait
可以接受外部的实现)。
目前,pub
的语义依然是完全公开的可见性,但编译器会输出一个警告提示用户将 pub
迁移至 pub(all)
/pub(open)
。已有的代码可以通过 moon fmt
自动迁移,formatter 会把 pub
自动变成 pub(all)
/pub(open)
。
struct
类型新增 private field 功能,可以在一个公开的struct
的某些 field 前用priv
关键字隐藏它:
- 在外部,
priv
field 是完全不可见的。不能读也不能修改 - 如果一个
struct
有 private field,它在外部不可以用字面量直接构造。但可以使用 struct update 语法{ ..old_struct, new_field: ... }
来更新公开的 field - 迁移到后缀风格的 label argument 语法。新的语法相当于把
~
移动到了标识符之后,如果是~label?
这种形式,波浪号可以省略。
enum Foo {
Bar(label~ : Int, Bool)
}
fn f(a~ : Int, b~ : Int = 0, c? : Int) -> Unit {...}
fn main {
f(a=1, b=2, c=3)
f(a=1, c?=Some(3))//b 声明了默认值可以省略,c 转发 option 语法照旧
let a = 1
let c = Some(3)
f(a~, c?) //和声明处一样,punning 也变成了后缀的形式
}
旧的语法将在未来移除:
enum Foo {
//deprecated
Bar(~label : Int, Bool)
}
//deprecated
fn f(~a : Int, ~b : Int = 0, ~c? : Int) -> Unit {}
fn main {
let a = 1
let c = Some(3)
f(~a, ~c?) //deprecated
}