У меня есть код, который я хочу превратить в ящик.Но он включает в себя структуру, которая содержит поле, которое я хочу предоставить пользователю ящика.Но мне нужна функциональность из этого поля, поэтому я хочу указать ее как черту.
pub trait RoleTrait {
fn owner<T: RoleTrait>() -> T;
fn order<T: RoleTrait>(&self) -> usize;
}
pub struct RequestInfo<Role: RoleTrait + PartialEq> {
role: Option<Role>,
name: String,
}
impl<Role: RoleTrait> RequestInfo<Role>
where
Role: std::cmp::PartialEq,
{
fn name(&self) -> String {
self.name.to_string()
}
fn role(&self) -> &Option<Role> {
&self.role
}
fn is_owner(&self) -> bool {
if let Some(role) = self.role {
role == Role::owner()
} else {
false
}
}
fn order(&self) -> usize {
if let Some(role) = self.role {
role.order() + 1
} else {
0
}
}
fn from(name: String) -> RequestInfo<Role> {
RequestInfo::<Role> {
role: None,
name: name,
}
}
fn with_role(name: String, role: Role) -> RequestInfo<Role> {
RequestInfo::<Role> {
role: Some(role),
name: name,
}
}
}
С двумя реализациями RoleTrait
:
#[derive(PartialEq)]
pub enum CourseRole {
Professor,
Marker,
Student,
}
impl RoleTrait for CourseRole {
fn owner<T: RoleTrait>() -> T {
CourseRole::Professor
}
fn order<T: RoleTrait>(&self) -> usize {
if *self == CourseRole::Professor {
0
} else {
1
}
}
}
#[derive(PartialEq)]
pub enum BlogRole {
Owner,
Blogger,
}
impl RoleTrait for BlogRole {
fn owner<T: RoleTrait>() -> T {
BlogRole::Owner
}
fn order<T: RoleTrait>(&self) -> usize {
if *self == BlogRole::Owner {
0
} else {
1
}
}
}
Я получаю 3 ошибки с этим.
error[E0282]: type annotations needed
--> src/main.rs:28:18
|
28 | role.order() + 1
| ^^^^^ cannot infer type for `T`
error[E0308]: mismatched types
--> src/main.rs:55:9
|
54 | fn owner<T: RoleTrait>() -> T {
| - expected `T` because of return type
55 | CourseRole::Professor
| ^^^^^^^^^^^^^^^^^^^^^ expected type parameter, found enum `CourseRole`
|
= note: expected type `T`
found type `CourseRole`
error[E0308]: mismatched types
--> src/main.rs:72:9
|
71 | fn owner<T: RoleTrait>() -> T {
| - expected `T` because of return type
72 | BlogRole::Owner
| ^^^^^^^^^^^^^^^ expected type parameter, found enum `BlogRole`
|
= note: expected type `T`
found type `BlogRole`
(и вторая ошибка повторилась для другого перечисления)
Честно говоря, я удивлен (и рад!), Что часть моего кода верна (например, ссылки наowner
в черте).У меня было гораздо больше ошибок, когда я начал писать этот вопрос, но я не могу понять эти оставшиеся, поскольку T
выглядит так ясно, а rustc
, кажется, уже выяснил более сложные вещи.В последних двух ошибках почти как будто он не осознает, что есть реализация признака для перечисления, потому что он находится в середине определения этой реализации (но он, очевидно, понимает это в других местах).