< 返回版块

chinagxwei 发表于 2021-03-03 21:21

Tags:宏,表达式,解析

声明宏中有没有像过程宏中可以将字符串解析成表达式的方法?stringify! 的反向解析

然后有没有人推荐一下比较好的rust宏介绍的文章或站点?

评论区

写评论
johnmave126 2021-03-04 14:17

这种问题其实比较像http server的路由嘛

routerify,这种靠builder-pattern,运行时手动把路径(String)和handler绑起来的,内部实现我估计是棵树或者编译成了正则。简单一点的话,用一个Hashmap也行。

也有serenity,这种其实是builder-pattern,但是靠过程宏生成了绑定代码的东西。

--
👇
chinagxwei: 对,想通过这种方式达到自动调用效果,以此实现简单的rpc流程。

--
👇
johnmave126: std::any::type_name::<TraitA>()是一个运行时的值,宏是编译期的,并做不到这个。

不如说一下你到底有个什么use case,是想做反射吗,还是rpc什么的?

如果是比如rpc,可以编译期/运行时初始化的时候把字符串和对应的调用绑起来(HashMap之类的),然后就跟路由一样你去检索这个表然后去调用。

作者 chinagxwei 2021-03-04 12:27

对,想通过这种方式达到自动调用效果,以此实现简单的rpc流程。

--
👇
johnmave126: std::any::type_name::<TraitA>()是一个运行时的值,宏是编译期的,并做不到这个。

不如说一下你到底有个什么use case,是想做反射吗,还是rpc什么的?

如果是比如rpc,可以编译期/运行时初始化的时候把字符串和对应的调用绑起来(HashMap之类的),然后就跟路由一样你去检索这个表然后去调用。

johnmave126 2021-03-04 11:01

std::any::type_name::<TraitA>()是一个运行时的值,宏是编译期的,并做不到这个。

不如说一下你到底有个什么use case,是想做反射吗,还是rpc什么的?

如果是比如rpc,可以编译期/运行时初始化的时候把字符串和对应的调用绑起来(HashMap之类的),然后就跟路由一样你去检索这个表然后去调用。

--
👇
chinagxwei: lib.rs

pub trait TraitA{
    fn hi(&self);
}

pub struct StructB;

impl TraitA for StructB{
    fn hi(&self) {
        println!("Struct B")
    }
}

pub struct StructC;

impl TraitA for StructC{
    fn hi(&self) {
        println!("Struct C")
    }
}

main.rs

fn main() {
    let b = StructB;
    rust_by_example::TraitA::hi(&b);
    let c = StructC;
    rust_by_example::TraitA::hi(&c);
    println!("TraitA path: {}",std::any::type_name::<TraitA>());
}

我想动态获取trait的路径后动态调用实例方法(路径:rust_by_example::TraitA,方法:hi)。

但是获取路径表达式的字符串后就不懂要如何将字符转成表达式传入到宏当中将字符串解析为表达式,过程宏当中通过将表达式的字符串转换为TokenStream后再解析为表达式对象。但是我不懂声明宏中要如何实现。

--
👇
johnmave126: 感觉是个XY problem,不如先说一说你为什么要这么做,究竟要达成一个什么目的 简短来说,不用过程宏不太行

作者 chinagxwei 2021-03-04 10:08

lib.rs

pub trait TraitA{
    fn hi(&self);
}

pub struct StructB;

impl TraitA for StructB{
    fn hi(&self) {
        println!("Struct B")
    }
}

pub struct StructC;

impl TraitA for StructC{
    fn hi(&self) {
        println!("Struct C")
    }
}

main.rs

fn main() {
    let b = StructB;
    rust_by_example::TraitA::hi(&b);
    let c = StructC;
    rust_by_example::TraitA::hi(&c);
    println!("TraitA path: {}",std::any::type_name::<TraitA>());
}

我想动态获取trait的路径后动态调用实例方法(路径:rust_by_example::TraitA,方法:hi)。

但是获取路径表达式的字符串后就不懂要如何将字符转成表达式传入到宏当中将字符串解析为表达式,过程宏当中通过将表达式的字符串转换为TokenStream后再解析为表达式对象。但是我不懂声明宏中要如何实现。

--
👇
johnmave126: 感觉是个XY problem,不如先说一说你为什么要这么做,究竟要达成一个什么目的 简短来说,不用过程宏不太行

shaitao 2021-03-04 09:35

老版本nom好像就是这样子的

johnmave126 2021-03-04 06:24

感觉是个XY problem,不如先说一说你为什么要这么做,究竟要达成一个什么目的 简短来说,不用过程宏不太行

1 共 6 条评论, 1 页