我想在port
提供的dao
和main()
参数的函数中启动Hyper服务器,但该函数仅在我明确指出'static
生命周期后才有效。这让我很困惑。
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();
}
Http::new().bind
API文档说它需要NewService + 'static
,所以我认为编译器会推断dao
变体是'static
,但是当我移动最后三个语句时出于主要原因,它无法推断!
fn main() {
let addr = "127.0.0.1:3000".parse().unwrap();
let dao: MysqlDao = MysqlDao;
web_startup(&addr, &dao);
}
fn web_startup<T: Dao>(addr: &SocketAddr, dao: &T) {
let server = Http::new()
.bind(addr, move || Ok(HelloWorld { dao }))
.unwrap();
server.run().unwrap();
}
我收到错误:
error[E0477]: the type `[closure@src/main.rs:44:21: 44:51 dao:&T]` does not fulfill the required lifetime
--> src/main.rs:44:10
|
44 | .bind(addr, move || Ok(HelloWorld { dao }))
| ^^^^
|
= note: type must satisfy the static lifetime
所以我修理了它:
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();
}
我不明白为什么我应该在static
语句中使用static DAO: MysqlDao = MysqlDao;
关键字,但在更改代码之前不需要。编译器无法推断它,或者我在不正确地思考问题?
答案 0 :(得分:1)
编译器无法推断...
GridView {
anchors.fill: parent
cellWidth: 100; cellHeight: 100
focus: true
model: FileModel{
id: myModel
folder: "/mnt/sdcard/app_pictureFrameImage"
nameFilters: ["*.mp4","*.jpg"]
}
currentIndex: 0
highlight: Rectangle { width: 80; height: 80; color: "lightsteelblue" }
delegate: Item {
width: 100; height: 100
Image {
id: myIcon
y: 20; anchors.horizontalCenter: parent.horizontalCenter
source: icon
}
Text {
anchors { top: myIcon.bottom; horizontalCenter: parent.horizontalCenter }
text: fileName
}
MouseArea {
anchors.fill: parent
onClicked: parent.GridView.view.currentIndex = index
}
}
}
...
函数被调用它的唯一时间是#ifndef FILEMODEL_H
#define FILEMODEL_H
#include <QAbstractListModel>
#include <QDirIterator>
#include <QUrl>
#include <QMetaType>
#include <QFuture>
#include <QtConcurrent/QtConcurrent>
#include <iostream>
using namespace std;
struct File
{
Q_GADGET
Q_PROPERTY(QString name MEMBER name)
Q_PROPERTY(QUrl url MEMBER url)
public:
QString name;
QUrl url;
File(const QString& name=""){
this->name = QFileInfo(name).fileName();
this->url = QUrl::fromLocalFile(name);
}
};
Q_DECLARE_METATYPE(File)
class FileModel : public QAbstractListModel
{
enum dashBoardRoles {
NameRole=Qt::UserRole+1,
URLRole
};
Q_OBJECT
Q_PROPERTY(QString folder READ folder WRITE setFolder NOTIFY folderChanged)
Q_PROPERTY(QStringList nameFilters READ nameFilters WRITE setNameFilters NOTIFY nameFiltersChanged)
public:
FileModel(QObject *parent=Q_NULLPTR):QAbstractListModel(parent){
}
Q_INVOKABLE QVariant get(int index){
return QVariant::fromValue(m_all_dirs[index]);
}
int rowCount(const QModelIndex &parent=QModelIndex()) const{
Q_UNUSED(parent)
return m_all_dirs.count();
}
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const{
if(index.row()<0 && index.row()>= rowCount())
return QVariant();
File file = m_all_dirs[index.row()];
if(role == NameRole)
return file.name;
else if(role == URLRole)
return file.url;
return QVariant();
}
QHash<int, QByteArray> roleNames() const {
QHash <int,QByteArray> roles;
roles [NameRole]="fileName";
roles [URLRole]="url";
return roles;
}
QString folder() const{
return mFolder;
}
void setFolder(const QString &folder)
{
if(mFolder == folder)
return;
mFolder = folder;
emit folderChanged();
findFiles();
}
QStringList nameFilters() const{
return mNameFilters;
}
void setNameFilters(const QStringList &nameFilters){
if(mNameFilters == nameFilters)
return;
mNameFilters = nameFilters;
emit nameFiltersChanged();
findFiles();
}
signals:
void folderChanged();
void nameFiltersChanged();
private:
void findFiles(){
beginResetModel();
m_all_dirs.clear();
if(QDir(mFolder).exists()){
QFuture<QStringList> future = QtConcurrent::run([=]() {
QStringList files;
QDirIterator it(mFolder, mNameFilters, QDir::Files, QDirIterator::Subdirectories);
while (it.hasNext()){
files<<it.next();
}
return files;
});
QStringList fullNames = future.result();
for(const QString& fullName: fullNames){
File file{fullName};
m_all_dirs << file;
}
}
endResetModel();
}
QString mFolder;
QList<File> m_all_dirs;
QStringList mNameFilters;
};
#endif // FILEMODEL_H
调用的原因是因为无法保证。如果该功能是公开的并且它是由第三方模块调用的,该怎么办?编译器必须告诉最终用户在似乎需要的函数上使用web_startup
。如果将来某个时间'static
添加到Rust(例如REPL),那么即使您的私有函数也可以使用意外的函数参数调用,该怎么办?
你要求推断不应该发生。