如何将带有签名EcsClient的impl<P, D> EcsClient<P, D> where P: ProvideAwsCredentials, D: DispatchSignedRequest实例作为Rust中的引用传递给函数?因此,我的尝试是:
extern crate rusoto;
use std::default::Default;
use rusoto::{ DefaultCredentialsProvider, Region };
use rusoto::ecs::{ EcsClient };
use rusoto::default_tls_client;
fn get_task_definition_revisions(client: &EcsClient) {
// Use EscClient instance here
}
fn main() {
let provider = DefaultCredentialsProvider::new().unwrap();
let client = EcsClient::new(default_tls_client().unwrap(), provider, Region::EuWest1).unwrap();
get_task_definition_revisions(&client);
}这给了我以下错误:
error[E0243]: wrong number of type arguments: expected 2, found 0
--> src/main.rs:9:43
|
9 | fn get_task_definition_revisions(client: &EcsClient) {
| ^^^^^^^^^ expected 2 type arguments我试图修复这个问题是这样的:
extern crate rusoto;
use std::default::Default;
use rusoto::{
DefaultCredentialsProvider,
Region,
ProvideAwsCredentials,
DispatchSignedRequest
};
use rusoto::ecs::{ EcsClient, ListTaskDefinitionsRequest };
use rusoto::default_tls_client;
fn get_task_definition_revisions(client: &EcsClient<ProvideAwsCredentials, DispatchSignedRequest>) {
// Use EcsClient instance here
}
fn main() {
let provider = DefaultCredentialsProvider::new().unwrap();
let client = EcsClient::new(default_tls_client().unwrap(), provider, Region::EuWest1);
get_task_definition_revisions(&client);
}这给了我:
error[E0277]: the trait bound `rusoto::ProvideAwsCredentials + 'static: std::marker::Sized` is not satisfied
--> src/main.rs:14:1
|
14 | fn get_task_definition_revisions(client: &EcsClient<P, D>) {
| _^ starting here...
15 | | let defs = client.list_task_definitions(&ListTaskDefinitionsRequest {
16 | | family_prefix: None,
17 | | max_results: None,
18 | | next_token: None,
19 | | sort: None,
20 | | status: Some("ACTIVE".to_string()),
21 | | });
22 | | }
| |_^ ...ending here: the trait `std::marker::Sized` is not implemented for `rusoto::ProvideAwsCredentials + 'static`
|
= note: `rusoto::ProvideAwsCredentials + 'static` does not have a constant size known at compile-time
= note: required by `rusoto::ecs::EcsClient`
error[E0277]: the trait bound `rusoto::DispatchSignedRequest + 'static: std::marker::Sized` is not satisfied
--> src/main.rs:14:1
|
14 | fn get_task_definition_revisions(client: &EcsClient<P, D>) {
| _^ starting here...
15 | | let defs = client.list_task_definitions(&ListTaskDefinitionsRequest {
16 | | family_prefix: None,
17 | | max_results: None,
18 | | next_token: None,
19 | | sort: None,
20 | | status: Some("ACTIVE".to_string()),
21 | | });
22 | | }
| |_^ ...ending here: the trait `std::marker::Sized` is not implemented for `rusoto::DispatchSignedRequest + 'static`
|
= note: `rusoto::DispatchSignedRequest + 'static` does not have a constant size known at compile-time
= note: required by `rusoto::ecs::EcsClient`这感觉就像兔子洞我不应该掉下去的。
我还尝试更改函数签名以接受泛型,但是EcsClient是一个结构,而不是一个特征。谷歌并没有提供多少帮助,因为我不知道搜索的正确术语。
This question似乎意味着我应该能够声明一个像fn my_func(client: &EcsClient) { ... }这样的函数,并且它会工作,那么为什么上面的例子不能呢?
发布于 2017-02-06 12:29:38
问题是EcsClient不是类型,而是构建类型(也称为“类型构造函数”)的蓝图。
因此,当需要类型时,无论是函数还是结构成员,都不能只使用EcsClient;相反,每次都必须通过指定类型的泛型参数来使用它来构建类型。
因此,第一步是引入类型参数:
fn get_task_definition_revisions<P, D>(client: &EcsClient<P, D>) {}但是,现在编译器会抱怨P和D没有受到足够的约束:EcsClient只接受一种非常特定的P和D!
因此,下一步是查找P和D在EcsClient定义中指定的界限,并应用它们。在这一点上只是复制/粘贴:
fn get_task_definition_revisions<P, D>(client: &EcsClient<P, D>)
where P: ProvideAwsCredentials,
D: DispatchSignedRequest
{
}然后你就成了黄金。
如果对于这个特定的函数需要更多的P或D功能,可以通过使用+添加更多的边界来对它们进行适当的约束。
fn get_task_definition_revisions<P, D>(client: &EcsClient<P, D>)
where P: ProvideAwsCredentials + 'static,
D: DispatchSignedRequest
{
}如果您想知道为什么Rust选择让您重复P和D的界限,而它可以完美地推断它们,那是因为它关心您。更具体地说,它关心的是你6个月后,以及下一个维护者的到来。因此,如果你只写一次,读了很多次,它就会迫使你复制边界,这样以后你就不用想知道它们是什么了,并且递归地钻研每种类型/函数,这些类型/函数用来痛苦地聚合所有的片段。在Rust中,下一次阅读函数时,您将得到所有的信息。
发布于 2017-02-06 11:54:42
我不正确地理解了语法。P和D似乎是占位符,就像T一样。我需要指定这些类型,因此签名现在如下所示:
fn get_task_definition_revisions<P: ProvideAwsCredentials, D: DispatchSignedRequest>(client: &EcsClient<P, D>) {
...
}函数体中不使用P或D,但必须声明它们。
完整的示例现在看起来如下:
extern crate rusoto;
use std::default::Default;
use rusoto::{
DefaultCredentialsProvider,
Region,
ProvideAwsCredentials,
DispatchSignedRequest
};
use rusoto::ecs::{ StringList, EcsClient, ListTaskDefinitionsRequest };
use rusoto::default_tls_client;
fn get_task_definition_revisions<P: ProvideAwsCredentials, D: DispatchSignedRequest>(client: &EcsClient<P, D>) {
let res = client.list_task_definitions(&ListTaskDefinitionsRequest {
family_prefix: None,
max_results: None,
next_token: None,
sort: None,
status: Some("ACTIVE".to_string()),
});
// ...
}
fn main() {
let provider = DefaultCredentialsProvider::new().unwrap();
let client = EcsClient::new(default_tls_client().unwrap(), provider, Region::EuWest1);
get_task_definition_revisions(&client);
}我仍然不完全确定为什么这是有效的或需要的,但我希望这个答案能帮助到其他人。
https://stackoverflow.com/questions/42064853
复制相似问题