Rust 为什么需要方法之间的静态变量传递,而不需要在同一个方法中?

Rust 为什么需要方法之间的静态变量传递,而不需要在同一个方法中?,rust,lifetime,Rust,Lifetime,我想用main()提供的port和dao参数在函数中启动一个超级服务器,但该函数只有在我明确指出的静态生存期后才能工作。这让我很困惑 extern crate futures; extern crate hyper; use futures::future::Future; use hyper::header::ContentLength; use hyper::server::{Http, Request, Response, Service}; use std::net::SocketAd

我想用
main()
提供的
port
dao
参数在函数中启动一个超级服务器,但该函数只有在我明确指出
的静态
生存期后才能工作。这让我很困惑

extern crate futures;
extern crate hyper;

use futures::future::Future;
use hyper::header::ContentLength;
use hyper::server::{Http, Request, Response, Service};
use std::net::SocketAddr;

trait Dao {}

struct MysqlDao;

impl Dao for MysqlDao {}

struct HelloWorld<'a> {
    dao: &'a Dao,
}

const PHRASE: &'static str = "Hello, World!";

impl<'a> Service for HelloWorld<'a> {
    type Request = Request;
    type Response = Response;
    type Error = hyper::Error;
    type Future = Box<Future<Item = Self::Response, Error = Self::Error>>;

    fn call(&self, _req: Request) -> Self::Future {
        Box::new(futures::future::ok(
            Response::new()
                .with_header(ContentLength(PHRASE.len() as u64))
                .with_body(PHRASE),
        ))
    }
}

fn main() {
    let addr = "127.0.0.1:3000".parse().unwrap();
    let dao = MysqlDao;
    let server = Http::new()
        .bind(&addr, move || Ok(HelloWorld { dao: &dao }))
        .unwrap();
    server.run().unwrap();
}
我得到一个错误:

error[E0477]:类型`[closure@src/main.rs:44:21:44:51 dao:&T]`未完成所需的生存期
-->src/main.rs:44:10
|
44 |.bind(addr,move | | Ok(HelloWorld{dao}))
|          ^^^^
|
=注意:类型必须满足静态生存期
所以我修正了它:

fn main() {
    let addr = "127.0.0.1:3000".parse().unwrap();
    static DAO: MysqlDao = MysqlDao;
    web_startup(&addr, &DAO);
}

fn web_startup<T: Dao>(addr: &SocketAddr, dao: &'static T) {
    let server = Http::new()
        .bind(addr, move || Ok(HelloWorld { dao }))
        .unwrap();
    server.run().unwrap();
}
fn main(){
让addr=“127.0.0.1:3000”;
静态DAO:MysqlDao=MysqlDao;
web_启动(&addr,&DAO);
}
fn web_启动(地址:&SocketAddr,dao:&T){
让服务器=Http::new()
.bind(addr,move | | Ok(HelloWorld{dao}))
.unwrap();
server.run().unwrap();
}

我不明白为什么我应该对
静态DAO:MysqlDao=MysqlDao使用
static
关键字语句,但无需在更改代码之前执行。编译器无法推断,或者我的想法不正确?

编译器无法推断只有在
web\u启动
函数被调用时才会使用
静态
调用,这是因为无法保证这一点。如果函数是公共的,并且由第三方模块调用,该怎么办?编译器必须告诉最终用户在一个似乎不需要的函数上使用一个静态的
。如果将来某个时候
eval()
被添加到Rust(例如REPL),那么即使您的私有函数也可能被意外的函数参数调用,该怎么办


你要求的是一个不应该发生的推论。

你到底想问什么问题?看来你已经解决了你的问题。请注意,你应该能够将你的问题作为你文章的标题,这是一个很好的迹象,表明你的问题足够集中,值得回答。@Shepmaster问题是最后一行“编译器无法推断它,或者我是在错误地思考问题吗?”。我认为当我从main()启动服务器时,如果编译足够智能,我不应该显式地指示静态关键字。顺便说一句,我想不出一个简单的标题来匹配我所表达的内容。那么它可能是的一个副本。我知道我说了什么,所以我给函数
web\u startup
添加了生存期。但是它还需要一个显式的静态MysqlDao。这就是我所困惑的@谢普马斯特:谢谢你更改了标题,但我认为它偏离了意思。如果标题不准确,请随时更改回来。对不起,我不明白你在问什么。谢谢。我认为
MysqlDao
实例应该只在
main()
中使用一次(由
web\u启动
),没有被误用的机会。如果编译器看到
web\u startup
方法需要一个
'static
引用,我认为它可以保证
MysqlDao
实例是静态的。@llxxbb No.Being
static
与Being
mut
不一样。可以进行
静态mut
。保持
静态
只意味着在程序执行期间不会删除它。它保证不会被删除,因为它在main结束之前不会被删除,main表示程序执行的结束。这就是为什么程序知道
dao
是静态的。
fn main() {
    let addr = "127.0.0.1:3000".parse().unwrap();
    static DAO: MysqlDao = MysqlDao;
    web_startup(&addr, &DAO);
}

fn web_startup<T: Dao>(addr: &SocketAddr, dao: &'static T) {
    let server = Http::new()
        .bind(addr, move || Ok(HelloWorld { dao }))
        .unwrap();
    server.run().unwrap();
}