Как реализовать черту, которой я не владею, для типа, которым я не владею?
3152 просмотра
2 ответа
Я хотел реализовать эту Shl
черту Vec
, код ниже. Это сделало бы такие вещи vec << 4
возможными, что было бы неплохо для сахара vec.push(4)
.
use std::ops::Shl;
impl<T> Shl<T> for Vec<T> {
type Output = Vec<T>;
fn shl(&self, elem: &T) -> Vec<T> {
self.push(*elem);
*self
}
}
fn main() {
let v = vec![1, 2, 3];
v << 4;
}
Компиляция завершается со следующей ошибкой:
не может обеспечить реализацию расширения, в которой в этом ящике не определены ни признак, ни тип [E0117]
или же
параметр типа
T
должен использоваться в качестве параметра типа для некоторого локального типа (напримерMyStruct<T>
); только параметры, определенные в текущем ящике, могут быть реализованы для параметра типа [E0210]
Насколько я понимаю, мне пришлось бы залатать stdlib, а точнее collections::vec
ящик. Есть ли другой способ изменить этот код для успешной компиляции?
Ответы (2)
35 плюса
Хотя вы не можете сделать это точно, обычный обходной путь заключается в том, чтобы просто обернуть нужный вам тип в свой собственный тип и реализовать в нем черту.
use somecrate::FooType;
use somecrate::BarTrait;
struct MyType(FooType);
impl BarTrait for MyType {
fn bar(&self) {
// use `self.0` here
}
}
Автор: Luqman
Размещён: 20.08.2014 10:10
12 плюса
Это сделало бы такие вещи
vec << 4
возможными, что было бы неплохо для сахараvec.push(4)
.
Хотя это может быть сделано, обычно плохая идея реализовать оператор с неожиданной семантикой.
Вот пример того, как это можно сделать:
use std::ops::Shl;
struct BadVec<T>(Vec<T>);
impl<T> Shl<T> for BadVec<T> {
type Output = BadVec<T>;
fn shl(mut self, elem: T) -> Self::Output {
self.0.push(elem);
self
}
}
fn main() {
let mut v = BadVec(vec![1, 2, 3]);
v = v << 4;
assert_eq!(vec![1, 2, 3, 4], v.0)
}
Если вы реализуете Deref
( DerefMut
):
use std::ops::{Deref, DerefMut};
impl<T> Deref for BadVec<T> {
type Target = Vec<T>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T> DerefMut for BadVec<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
Вы можете вызвать Vec
методы:
fn main() {
let mut v = BadVec(vec![1, 2, 3]);
v = v << 4;
v.truncate(2);
assert_eq!(2, v.len());
}
Взгляните на newtype_derive
ящик, он может сгенерировать некоторый шаблонный код для вас.
Вопросы из категории :
- rust Розетки в Русте
- rust Как вы делаете диапазон в Rust?
- rust Сопоставление ржавчины с вектором
- rust Программы бенчмаркинга в Rust
- rust Что такое мономорфизация с контекстом на C ++?
- rust Как получить доступ к параметрам командной строки?
- rust Можем ли мы создать пользовательские Rust-операторы?
- rust Как обрабатывать длительные вызовы внешних функций, такие как блокировка ввода-вывода в Rust?
- rust Возможно ли сделать рекурсивное замыкание в Rust?
- rust Создание кроссплатформенного приложения (с использованием Rust)
- traits графические интерфейсы / библиотеки Python, подходящие для программ анализа данных
- traits Тип черта для строк
- traits Черты против интерфейсов
- traits Как перегрузить конструктор класса в чертах в PHP> = 5.4
- traits Why PHP Trait can't implement interfaces?
- traits Узнайте, может ли объект C ++ вызываться
- traits Могу ли я иметь статическую заимствованную ссылку на объект черты?
- traits Scala реализация одного метода интерфейса
- traits Как реализовать черту, которой я не владею, для типа, которым я не владею?
- traits Как мне реализовать черту Add для ссылки на структуру?