gpt4 book ai didi

rust - 如何将具有类型参数的结构作为函数参数传递?

转载 作者:行者123 更新时间:2023-11-29 08:03:54 26 4
gpt4 key购买 nike

如何传递 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) { ... } 这样的函数它会起作用,那么上面的例子为什么不起作用?

最佳答案

问题是 EcsClient不是类型,它是构建类型的蓝图(也称为“类型构造函数”)。

因此,您不能使用EcsClient当需要类型时,无论是在函数中还是对于结构成员;相反,每次您都必须通过指定其泛型参数来使用它来构建类型。

因此,第一步是引入类型参数:

fn get_task_definition_revisions<P, D>(client: &EcsClient<P, D>) {}

然而,现在编译器会提示 PD约束不足:EcsClient只接受一种非常特殊的 PD !

因此,下一步是查找为 P 指定的边界和 DEcsClient 的定义中并应用它们。此时只是复制/粘贴:

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 中,下次您阅读该函数时,您将获得所有信息。

关于rust - 如何将具有类型参数的结构作为函数参数传递?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42064853/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com