pub trait EnumIndex{
value(Self)->Int
}
pub enum TextAlign{
Left
Right
Center
Start
End
}
pub impl EnumIndex for TextAlign with value(self: TextAlign)->Int{
match self{
Left=>0
Right=>1
Center=>2
Start=>3
End=>4
}
}
这样实现了接口之后,不能直接使用textAlign.value()来访问这个接口的value方法,必须得用EnumIndex::value(textAlign)来访问?试验了一下,相当于还是得实现一个
pub fn value(self: TextAlign)->Int{
match self{
Left=>0
Right=>1
Center=>2
Start=>3
End=>4
}
}
像这种一模一样的方法,才能使用textAlign.value()来访问,这个设计感觉是不是可以稍微优化一下
tiye
2024 年10 月 22 日 05:20
2
我印象里用到的时候似乎是有的, 可能需要加上 (textAlign as EnumIndex).value()
才能明确匹配上? 或者某些情况才会自动推断?
这是因为 x.f()
这个语法调用的是普通方法(如果你写 Rust 的话,相当于 impl T { ... }
),而 impl
不是普通方法。这两个东西的区别是:
普通方法只能在类型所在的包定义,而 impl
可以在外面定义
同一个类型只能有一个同名方法,但可以 impl
多个不同的、有同名方法的 trait
Rust 是允许用 x.f(...)
调用 impl
的,但这意味着解析 x.f(...)
需要查找所有 import 的包,而且添加一个新的依赖有可能导致现有代码的 x.f(...)
冒出歧义。MoonBit 希望符号解析是一个相对 local 的过程,所以 x.f(...)
只能调用普通方法。
但当你在类型所在的包里 impl
一个 trait 的时候,可能会希望把它自动变成一个方法。这时候可以这么写:
pub fn value(self : TextAlign) -> Int { EnumIndex::TextAlign(self) }
1 个赞
这样说的话,就大致明白了,如果必须local过程就搞定的话
不过用 as
是有开销的,会分配一个 trait object(Rust 的 dyn
)再去调用它。所以如果需要用 .f(...)
调用 impl
还是建议写个 wrapper