我正在尝试导出一个使用包中定义的某些函数的宏。像这样的东西,例如在一个名为的板条箱中a_macro_a_day
// lib.rs
pub fn a() {}
#[macro_export]
macro_rules! impl_helper_funcs {
use crate::a; // error unresolved import
use a_macro_a_day::a; // error unresolved import
fn b() {
...
a() // call imported a here
}
}
Run Code Online (Sandbox Code Playgroud)
我尝试过使用各种组合use来导入a,但错误总是显示宏定义为unresolved import crateor unresolved import a_macro_a_day。
我不想采用过程宏方式,因为这只是为了减少代码重复。有没有办法导出导入本地(但公共)函数的宏?
参考:rust-cpp
emacs/spacemacs可以在主模式下支持嵌套模式吗?我习惯于对emacs/spacemacs进行vim和new.
我的部分代码如下所示:
print_usage_instructions();
print!("Command: ");
let stdin = io::stdin();
let mut line = String::new();
stdin.lock().read_line(&mut line).expect("Couldn't process the command.");
println!("{}", line);
Run Code Online (Sandbox Code Playgroud)
我期望的行为是这样的:
Usage instructions and stuff
Command: [my command]
[my command]
Run Code Online (Sandbox Code Playgroud)
但是,会发生什么:
Usage instructions and stuff
[my command]
Command: [my command]
Run Code Online (Sandbox Code Playgroud)
任何想法为什么会发生?AFAIK,编译器没有理由在这里更改执行顺序,这部分代码不是异步也不是多线程.
我想同时声明多个可变变量。定义了一个宏来声明可变变量,如下所示。
macro_rules! mutf64 {
( $( $e:expr ),+ ) => {
{
$(
let mut $e:f64;
)+
}
};
}
fn main() {
mutf64!(FT, FX, alpha, H, K, lambda, T, X);
}
Run Code Online (Sandbox Code Playgroud)
使用编译器进行语法检查时出现错误:
macro_rules! mutf64 {
( $( $e:expr ),+ ) => {
{
$(
let mut $e:f64;
)+
}
};
}
fn main() {
mutf64!(FT, FX, alpha, H, K, lambda, T, X);
}
Run Code Online (Sandbox Code Playgroud)
我为什么不能这样做macro_rules?
我有一个Component特征,该特征具有返回索引的方法,如下所示:
trait Component {
fn index(&self) -> usize;
}
Run Code Online (Sandbox Code Playgroud)
这些索引用于在位集中设置标志。例如,Component返回索引为5 的特征对象将导致在容器中设置第5位。
目前,我为每种实现类型手动返回运行索引:
struct Foo;
struct Bar;
impl Component for Foo {
fn index(&self) -> usize { 0 }
}
impl Component for Bar {
fn index(&self) -> usize { 1 }
}
Run Code Online (Sandbox Code Playgroud)
特质对象插入到容器中,该容器使用位集跟踪添加的组件:
struct Container<'a> {
components: Vec<Component + 'a>,
bits: BitSet
}
impl<'a> Container<'a> {
fn add<T: Component + 'a>(&mut self, component: T) {
self.components.push(component);
self.bits.set(component.index());
}
}
Run Code Online (Sandbox Code Playgroud)
这可以正常工作,但是手动返回每种实现类型的索引很麻烦。我怎样才能使每种实现类型都自动获得其索引?
我想编写一个宏,从整数参数生成不同的结构。例如,make_struct!(3)可能会生成如下内容:
pub struct MyStruct3 {
field_0: u32,
field_1: u32,
field_2: u32
}
Run Code Online (Sandbox Code Playgroud)
将“3”文字转换为可用于生成代码的数字的最佳方法是什么?我应该使用macro_rules!还是proc-macro?
我正在尝试创建一个宏来生成一个可以从 postgres 数据库填充的结构。现在,由于数据库中存在可为空和不可为空的字段,我希望在宏中以不同的方式处理它们。
输出应该是这样的结构:
#[derive(Debug, Default)]
pub struct MyStruct {
pub attrib_a: i64,
pub attrib_b: Option<i64>,
}
impl MyStruct {
pub fn get_row(&self, row: &postgres::rows::Row) -> MyStruct {
MyStruct {
// the non-nullable attrib_a, where I can for sure take the value out of the Option and assign it
attrib_a: match row.get::<_, Option<i64>>("attrib_a") {
Some(x) => x,
None => 0,
},
// here for the nullable attrib_b I just want to return the Option as is
attrib_b: row.get::<_, Option<i64>>("attrib_b"),
} …Run Code Online (Sandbox Code Playgroud) 尝试cargo build针对此代码:
#![allow(unused)]
use serde::{Deserialize, Serialize};
use serde_json::{Result, Value};
#[derive(Serialize, Deserialize,Debug)]
struct Repository{
r#type: String,
url: String,
}
fn main() {
println!("Hello, world!");
}
Run Code Online (Sandbox Code Playgroud)
这是 cargo.toml 文件:
[package]
name = "demo_err"
version = "0.1.0"
authors = ["Onorio Catenacci <catenacci@ieee.org>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
serde = "1.0.104"
serde_json = "1.0.44"
Run Code Online (Sandbox Code Playgroud)
当然,我的真实代码要大一些,但这是我可以重现错误的最小代码。
我收到以下错误:
Compiling demo_err v0.1.0 (U:\skunkworks\rust\demo_err)
error: cannot find derive macro `Serialize` in this scope
--> src\main.rs:9:10
|
9 | …Run Code Online (Sandbox Code Playgroud) 我正在尝试在我正在使用的库中调试复杂的程序宏。
由于我不能使用带有宏的调试器,并且各种宏扩展工具在这里被证明是无用的,我正在寻找替代方案。
程序宏是否可以像经过适当调试的函数一样运行?我想象将结果存储proc_macro::TokenStream在一个变量中。
我正在尝试制作一个宏,让我遍历类型列表以减少 trait impl 样板。(我目前正在使用不同的基于宏的解决方案,但这似乎更具可读性,如果可以不添加依赖项的话。)
这是我的目标语法:
trait MyTrait {}
tfor! {
for Ty in [i32, u32] {
impl MyTrait for Ty {}
}
}
Run Code Online (Sandbox Code Playgroud)
我的尝试:
macro_rules! tfor {
(for $ty:ident in [$($typ:ident),*] $tt:tt) => {
$(
type $ty = $typ;
tfor! { @extract $tt }
)*
};
(@extract { $($tt:tt)* }) => {
$($tt)*
};
}
Run Code Online (Sandbox Code Playgroud)
这会产生错误,因为两次迭代都定义了Ty在同一范围内命名的类型:
|
4 | type $ty = $typ;
| ^^^^^^^^^^^^^^^^
| |
| `Ty` redefined here
| previous definition of the type `Ty` …Run Code Online (Sandbox Code Playgroud)