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