2个稳定版本
1.0.1 | 2024年7月23日 |
---|
1064 在 进程宏 中
每月下载量279次
在 4 个crate中使用(通过 hydroperfox-smodel)
73KB
1.5K SLoC
SModel
SModel(语义建模)为Rust提供了一种使用动态分派和层次定义(通过允许循环引用的内存池)来描述语言语义符号的便捷方式。
定义顺序
定义顺序很重要。使用 struct
关键字在继承的数据类型之后定义子类型。
如果您以任何顺序定义 struct
,则可能会导致宏终止的错误,提示未找到。
示例
最基本的数据类型是最先出现的。您可以根据个人喜好命名它。通常可以称为 symbol 或 thingy(根据Microsoft Roslyn的一位工程师,symbol 应该被称为 thingy)。
use hydroperfox_smodel::smodel;
smodel! {
type Arena = Arena;
struct Thingy {
let x: f64 = 0.0;
let ref y: String = "".into();
pub fn Thingy() {
super();
println!("{}", self.m());
}
pub fn m(&self) -> String {
"".into()
}
pub fn m1(&self) {
println!("base");
}
}
struct Foo: Thingy {
pub fn Foo() {
super();
}
pub override fn m(&self) -> String {
"Foo".into()
}
pub override fn m1(&self) {
if true {
super.m1();
}
}
}
}
fn main() {
let arena = Arena::new();
let thingy = Foo::new(&arena);
println!("{}", thingy.m());
}
内存池
内存池的名称定义为第一个 type Arena = ArenaName1;
指令的右侧。
字段
字段(一个 let
声明)有一个可选的 ref
修饰符,指示是否使用 RefCell
或 Cell
。对于所有类型,读取时都是克隆或复制。对于堆分配的资源,如 String
,请使用 ref
。
字段有一对获取器(fieldname()
)和设置器(set_fieldname(value)
)。
对于可变的哈希表或向量,建议使用一个 共享容器(见下文),它通过引用而不是内容进行克隆。
字段始终在包含模块内部,因此没有属性;字段定义始终以 let
关键字开始,没有 RustDoc 注释。
建议字段始终以下划线 _
或私有前缀(如 m_
)开头,并相应地使用 _x()
和 set__x(v)
,或分别使用 m_x()
和 set_m_x()
。
然后,您可以在基类型中实现可能被子类型重写的函数,从而允许一个 统一的 数据类型支持操作多个变体的方法。
共享容器
此软件包提供了两种通过引用复制的容器数据类型,SharedArray
和 SharedMap
,以及 shared_array!
和 shared_map!
文字。
SharedArray
是一个由引用计数管理的可变向量。SharedMap
是一个由引用计数管理的可变哈希表。
有关使用详情,请参阅软件包文档。
构造函数
构造函数是一个名称与数据类型名称匹配的方法。参数列表中隐式添加了 arena
参数。
构造函数被转换为静态 new
方法。
构造函数包含一个局部变量 self
,其数据类型是包含数据类型的实例。
子类型
symbol.is::<T>()
检查symbol
是否是T
子类型。symbol.to::<T>()
转换为T
子类型,返回Ok(m)
或Err
。它可能是一个协变转换。symbol.into()
是一个协变转换。
超级表达式
super.f()
表达式通过预处理方法标记序列并将其转换为其他 Rust 代码得到支持;因此,它可以在实例方法内的任何位置使用。
super.f()
按降序顺序在基数据类型的方法列表中进行查找。
继承文档
使用 #[inheritdoc]
属性来继承被重写方法的重写 RustDoc 注释。
#[inheritdoc]
pub override fn m(&self) {
// Action
}
方法参数
目前,重载方法中方法参数的名称应与子类型方法中的名称匹配,否则可能会出现宏卫生错误,指示该参数不在子类型方法中存在。
依赖项
~260–700KB
~17K SLoC