У меня возникли проблемы с пониманием того, как работать с чертами и владельцами. Ниже приведен пример:Невозможно вызвать функцию со ссылкой на тип, реализующий признак
struct X([u8; 4]);
impl X {
pub fn get(&self, n: usize) -> u8 {
self.0[n]
}
}
fn f1(x: &X) {
println!("{}", x.get(1));
f2(&x);
}
fn f2(x: &X) {
println!("{}", x.get(2));
}
fn main() {
let z1 = X([1u8, 2u8, 3u8, 4u8]);
f1(&z1);
}
Но когда я пытаюсь создать черту (здесь XT
) с get
:
trait XT {
fn get(&self, n: usize) -> u8;
}
struct X([u8; 4]);
impl XT for X {
fn get(&self, n: usize) -> u8 {
self.0[n]
}
}
fn f1<T: XT>(x: &T) {
println!("{}", x.get(1));
f2(&x);
}
fn f2<T: XT>(x: &T) {
println!("{}", x.get(2));
}
fn main() {
let z1 = X([1u8, 2u8, 3u8, 4u8]);
f1(&z1);
}
Не удается скомпилировать со следующим сообщением об ошибке:
в признак
XT
не применяется для типа&T
Он работает, если я меняю f2(&x)
на f2(x)
. Мое предположение заключалось в том, что замена типов по признакам, все будет работать.
Но запутанная вещь заключается в том, что она работает нормально в первом случае. (Отказ от ответственности: у меня нет полного представления о Rust, так что я могу ошибаться). Это похоже на очень распространенный сценарий: вы пишете какую-то функцию, которая принимает определенный тип, а затем вы понимаете, что можете использовать их для большего количества вещей. Поэтому вы создаете Trait и заменяете (с некоторым синтаксисом) Type for the Trait в определениях функций. Синтаксис, который делает его работу, не очень эргономичен. – Hernan
@Hernan Он работает в первом случае, потому что 'z1' имеет тип' X', поэтому '& z1' имеет тип' & X'. Когда вы вызываете 'f1', компилятор сообщает, что' & T = & X' поэтому 'T = X'. Когда вы вызываете 'f2' с' & x', он получает '& T = && X', поэтому' T = & X', а '& X' не реализует' XT'. –
Спасибо за объяснение. Я получаю это сейчас. Я бы сказал, что создание синтаксиса для признаков, равных синтаксису типов, было бы более эргономичным, но, я думаю, я пропускаю важные вещи о языке. – Hernan