最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

rust - possible to bound (only) supertrait? - Stack Overflow

programmeradmin3浏览0评论

Is it possible to have a supertrait, subject to its own specific where clause? For example, I've got a custom pointer trait, and I'd like it to implement From. However From requires Sized on the inner type, and I don't want to have a blanket T: Sized restriction, I'd rather that From::from is only available when T: Sized happens to be true.

Specifically, this doesn't compile

trait MyPtr: Deref + From<Self::Target> {}

and this compiles but is overly restrictive

trait MyPtr: Deref + From<Self::Target> where <Self as Deref>::Target: Sized {}

I want something like (fake syntax)

trait MyPtr: Deref + { From<Self::Target> where <Self as Deref>::Target: Sized } {}

Is this somehow possible?

Is it possible to have a supertrait, subject to its own specific where clause? For example, I've got a custom pointer trait, and I'd like it to implement From. However From requires Sized on the inner type, and I don't want to have a blanket T: Sized restriction, I'd rather that From::from is only available when T: Sized happens to be true.

Specifically, this doesn't compile

trait MyPtr: Deref + From<Self::Target> {}

and this compiles but is overly restrictive

trait MyPtr: Deref + From<Self::Target> where <Self as Deref>::Target: Sized {}

I want something like (fake syntax)

trait MyPtr: Deref + { From<Self::Target> where <Self as Deref>::Target: Sized } {}

Is this somehow possible?

Share Improve this question asked Feb 16 at 19:58 ajpajp 2,46318 silver badges23 bronze badges 1
  • 1 What would such an inconsistent super type bring you? It doesn't seem to serve a use as any trait object couldn't rely on it's implementation. When you have your original type you already can see a From implementation. – cafce25 Commented Feb 16 at 20:06
Add a comment  | 

1 Answer 1

Reset to default -1

You can use a generic param to achieve this.

make MyPtr to MyPtr<T: Sized> and add according trait bound.

then use a blanket implementation, if the implementation is universal.

You named the trait pointer, makes me think that you want to use it as some kind of smart pointer, you might want to consider Rc/Arc for this kind of application, which already implemented Deref<Target=T> and From<T>.

I don't know your context, you might want to also consider a wrapper struct, to achieve "super trait".

use std::{ops::Deref, rc::Rc};

trait MyPtr<T: Sized>: Deref<Target = T> + From<T> {
    fn print(&self) {
        println!("printing . . .")
    }
}

// Example Struct
struct MyStruct(i32);
impl Deref for MyStruct {
    type Target = i32;
    fn deref(&self) -> &Self::Target {
        &self.0
    }
}
impl From<i32> for MyStruct {
    fn from(value: i32) -> Self {
        MyStruct(value)
    }
}
// impl MyPtr<i32> for MyStruct {}

// // impl for Rc
// impl<T> MyPtr<T> for Rc<T> {}

// a blanket implementation
impl<T, P> MyPtr<T> for P where P: Deref<Target = T> + From<T> {}

// // Generic Wrapper Struct
// // this might be a good option instead of using a super trait.
// struct MyWrap<T>(T);
// impl<T> Deref for MyWrap<T> {
//     type Target = T;
//     fn deref(&self) -> &Self::Target {
//         &self.0
//     }
// }
// impl<T> From<T> for MyWrap<T> {
//     fn from(value: T) -> Self {
//         MyWrap(value)
//     }
// }
// impl MyWrap<T> {
// // impl your super trait fn here . . .
// }

fn main() {
    MyStruct(0).print();
    let a = Rc::new(0);
    a.print();
}

trait MyPtr {
    fn print(self: Rc<Self>){
        println!("printing . . .");
    }
}
发布评论

评论列表(0)

  1. 暂无评论