2016-11-01 4 views
2

Я пытаюсь создать структуру в Rust, которая сама по себе является общей для других общих структур. Это довольно запутанные и надеюсь, этот пример будет делает вещи яснее:Создайте структуру, которая является общей для другой общей структуры.

use std::ops::Deref; 
use std::rc::Rc; 

struct Foo<T: Deref> { 
    val: T<i32>, 
    other: i32, 
} 

impl<T> Foo<T> { 
    pub fn new(&self, val: T<i32>, other: i32) -> Self { 
     Foo {val: val, other: other} 
    } 
} 

fn main() { 
    let foo = Foo::new(Rc::new(0), 0); 
} 

playground

Я хотел бы быть в состоянии создать Foo объект, вызвав new либо Rc<i32> объектов или Arc<i32> объектов в зависимости от того, нужно ли нить безопасности или нет. Я получаю следующую ошибку, когда я пытаюсь это сделать: error[E0109]: type parameters are not allowed on this type, поскольку компилятор жалуется на i32 в val: T<i32>,. Возможно ли это в Rust? Если да, могу ли я безопасно вызывать методы на i32, предполагая, что он автоматически разыгрывает его?

+1

В отличие от некоторых других языков, к сожалению, Rust не имеет более высоких типов, поэтому параметры типа должны быть конкретными. Однако в этом случае я согласен с @Shepmaster, что вам это не нужно. –

ответ

3

Этот синтаксис не имеет смысла, но эта версия компилирует:

use std::ops::Deref; 
use std::rc::Rc; 
use std::sync::Arc; 

struct Foo<T> { 
    val: T, 
    other: i32, 
} 

impl<T> Foo<T> 
    where T: Deref<Target = i32> 
{ 
    pub fn new(val: T, other: i32) -> Self { 
     Foo { 
      val: val, 
      other: other, 
     } 
    } 
} 

fn main() { 
    let foo = Foo::new(Rc::new(0), 0); 
    let foo = Foo::new(Arc::new(0), 0); 
} 

Обратите внимание, как черта, ограничивает следующим образом: T: Deref<Target = i32> «Любой T, который реализует Deref с Target из в i32».

Вы можете реализовать методы, которые разыменовать val:

fn sum(&self) -> i32 { 
    *self.val + self.other 
} 

В целом, понятие о чем-то вроде

struct Foo<T> { 
    val: T<i32>, 
} 

не окажется полезным. Просто потому, что что-то параметризуется над i32, это не значит, что вы можете сделать что-нибудь с этим i32. Аналогично, тип может быть параметризован чем-то, кроме i32 (или вообще нет), и по-прежнему дает вам доступ к i32.

+0

Удивительный, спасибо за помощь! Идти, чтобы попробовать это сейчас. Я бы подумал, что это будет более распространенный метод, чтобы быстро получить общую структуру, которая может быть потокобезопасной или не зависит от ваших потребностей, вы видите это много? – jeromefroe

Смежные вопросы