我一直在我的一个程序中使用#[tokio::main]宏.在导入main并使用它之后,我遇到了一个意外的错误.

use tokio::main;

#[main]
async fn main() {}
error[E0659]: `main` is ambiguous
 --> src/main.rs:3:3
  |
3 | #[main]
  |   ^^^^ ambiguous name
  |
  = note: ambiguous because of a name conflict with a builtin attribute
  = note: `main` could refer to a built-in attribute

我一直在浏览文档,但在任何地方都找不到这个内置的#[main]属性.The Rust Reference contains an index of built-in attributes.该指数不包括#[main],但包括an attribute named #[no_main].

我搜索了rustlang/rust存储库,找到了some code that seems related个,但它似乎使用了一对名为#[start]#[rustc_main]的宏,而没有提到#[main]本身.(这两个宏在stable上似乎都不可用,#[start]发出一个不稳定的错误,#[rustc_main]发出一个只供编译器内部使用的错误.)

我从这个名字猜测,它是用来将一个不同的函数标记为入口点,而不是main,但它似乎也没有这样做:

#[main]
fn something_else() {
    println!("this does not run");
}

fn main() {
    println!("this runs");
}

Rust Analyzer没有太多可以提供的功能:

a screenshot showing Rust Analyzer's contextual help for the #[main] attribute, devoid of any details

除了与我的导入冲突外,内置的#[main]属性还有什么作用??

推荐答案

#[main]在1.53.0中是一个旧的、不稳定的属性that was mostly removed from the language.然而,删除操作漏掉了一行,结果是:该属性没有效果,但它可以在稳定的 rust 迹上使用,不会出现错误,并且与名为main的导入属性冲突.这是a bug, not intended behaviour.截至nightly-2022-02-10年和1.59.0-beta.8年,该数据为has been fixed.您的use tokio::main;#[main]示例现在可以毫无错误地运行.

在它被删除之前,不稳定#[main]被用来指定程序的入口点.Alex Crichton在a 2016 comment on GitHub中描述了它的行为和相关属性:

是的,我们有三个入口.我我想这就是它们的工作原理:

  • 首先是#[start]int argcchar **argv的接收器.这实际上是符号main(或编译器中生成的符号所称).
  • 接下来是#[lang = "start"].如果 crate 图中不存在#[start],那么编译器将生成一个main函数来调用它.此函数接收argc/argv以及第三个参数,该参数是指向#[main]函数(定义如下)的函数指针.重要的是,图书馆里可以找到#[lang = "start"]个.例如,它位于标准库(libstd)中.
  • 最后,#[main]是一个可执行文件的主函数.它没有参数传递,由#[lang = "start"]调用(如果它决定).标准库使用它来初始化自己,然后调用Rust程序.如果未指定,则顶部的默认值为fn main.

所以要回答你的问题,这和#[start]不一样.回答你的另一个问题(可能还没有被问到),是的,我们有太多的切入点.

Rust相关问答推荐

为什么单元类型(空元组)实现了`Extend`trait?

在Rust中有没有办法在没有UB的情况下在指针和U64之间进行转换?

将数组转换为HashMap的更简单方法

同时从不同线程调用DLL的不同函数会出现分段错误或产生STATUS_STACK_BUFFER_OVERRUN

什么时候和为什么S最好是按值或引用传递简单类型

关于使用平面图功能的borrow 判断器的问题

为什么RefCell没有与常规引用相同的作用域?

通过异常从同步代码中产生yield 是如何工作的?

将特征与具有生命周期的关联类型一起使用时的生命周期方差问题

借来的价值生命周期 不够长,不确定为什么它仍然是借来的

std mpsc 发送者通道在闭包中使用时关闭

如何使用 Rust Governor 为每 10 秒 10 个请求创建一个 RateLimiter?

在 Rust 中使用 `SecTrustSettingsSetTrustSettings` 绑定导致 `errSecInternalComponent`

内部值发生变化时 Rc 的行为

如何展平以下嵌套的 if let 和 if 语句?

返回引用字符串的future

如何在 nom 中构建负前瞻解析器?

有没有办法阻止 rust-analyzer 使非活动代码变暗?

为什么我可以在没有生命周期问题的情况下内联调用 iter 和 collect?

为移动和借位的所有组合实现 Add、Sub、Mul、Div