Generics 专门化一个特定泛型类型的方法

Generics 专门化一个特定泛型类型的方法,generics,rust,template-specialization,Generics,Rust,Template Specialization,我正在为一个C库编写一个包装器,我一直在编写大量的类型,比如CVecOf: 可以用稳定的编译器重写它吗 重要提示:CVec实现删除,因为它必须释放分配的数组内存,这样它就不能复制在稳定的锈迹中,特征的实现不能相交,我们不能使用负特征边界。这使得无法使用直接的实现,如: impl<T: Copy> Unpack for CVec<T> { // copies elements } impl<T: Unpack> Unpack for CVec<T>

我正在为一个C库编写一个包装器,我一直在编写大量的类型,比如
CVecOf

可以用稳定的编译器重写它吗


重要提示:
CVec
实现
删除
,因为它必须释放分配的
数组
内存,这样它就不能
复制

在稳定的锈迹中,特征的实现不能相交,我们不能使用负特征边界。这使得无法使用直接的实现,如:

impl<T: Copy> Unpack for CVec<T> { // copies elements  } 
impl<T: Unpack> Unpack for CVec<T> { // calls `unpack` for elements }

您想要稳定的解决方案吗?@VictorPolevoy,如果可能的话。然而,几乎总比什么都没有好。现在我们有了夜间解决方案,仍然在等待是否有人有稳定编译器的解决方案。您可能想了解另一种可能性,即
trait Unpack
fn Unpack(&self)
都不安全,但事实上,
CVec
公开了一个安全的界面,创建
CVec
是唯一不安全的部分(类似于
Vec::from_raw_parts
)。只是一个thought@trentcl谢谢你的评论!然而,vector是通过默认的trait创建的,trait基本上使用安全的
::std::ptr::null\u mut::()
,然后通过FFI调用填充,因为目前这些类型的所有用法都是
输出变量的类型。但是你的考虑真的很有价值。然而,如果我必须在生锈的一面填充它,我宁愿创建一个安全的构造函数,它接受
Vec
,我想这也是安全的:)
#![feature(specialization)]
#![deny(trivial_casts)]

use std::fmt::Debug;
use std::mem;

#[repr(C)]
#[derive(Debug)]
pub struct CVec<T: Sized> {
    array: *mut T,
    size: usize,
}

unsafe fn unpack_unsafe<T, R>(v: &CVec<T>) -> Vec<R> {
    (0..v.size)
        .map(|i| mem::transmute_copy(&*v.array.offset(i as isize)))
        .collect()
}

pub fn unpack<T, U, F>(v: &CVec<T>, mut f: F) -> Vec<U>
where
    F: FnMut(&T) -> U,
{
    (0..v.size)
        .map(|i| unsafe { f(&*v.array.offset(i as isize)) })
        .collect()
}

trait Unpack {
    type R: Debug;
    fn unpack(&self) -> Vec<Self::R>;
}

impl<T: Debug> Unpack for CVec<T> {
    default type R = T;
    default fn unpack(&self) -> Vec<Self::R> {
        unsafe { unpack_unsafe(self) }
    }
}

impl<T: Unpack + Debug> Unpack for CVec<T> {
    type R = Vec<T::R>;
    fn unpack(&self) -> Vec<Self::R> {
        unpack(self, |v| v.unpack())
    }
}

fn main() {
    let mut vs = [1, 2, 3];
    let mut v1 = CVec {
        array: vs.as_mut_ptr(),
        size: vs.len(),
    };
    let mut v2 = CVec {
        array: &mut v1 as *mut _,
        size: 1,
    };
    let mut v3 = CVec {
        array: &mut v2 as *mut _,
        size: 1,
    };
    let v4 = CVec {
        array: &mut v3 as *mut _,
        size: 1,
    };
    let v = v4.unpack();
    println!("{:?}", v);

    let ptr: *mut () = &mut v3 as *mut _ as *mut _;
}
impl<T: Copy> Unpack for CVec<T> { // copies elements  } 
impl<T: Unpack> Unpack for CVec<T> { // calls `unpack` for elements }
#[repr(C)]
#[derive(Debug, Clone)]
pub struct CVec<T: Sized> {
    array: *mut T,
    size: usize,
}

// Unsafe because CVec is not guaranteed to contain valid pointer and size
unsafe fn unpack<T, U, F>(v: &CVec<T>, mut f: F) -> Vec<U>
where
    F: FnMut(&T) -> U,
{
    (0..v.size)
        .map(|i| f(&*v.array.offset(i as isize)))
        .collect()
}

trait Unpack {
    type Out;
    unsafe fn unpack(&self) -> Self::Out;
}

impl<T: Unpack> Unpack for CVec<T> {
    type Out = Vec<T::Out>;
    unsafe fn unpack(&self) -> Self::Out {
        unpack(self, |e| e.unpack())
    }
}

impl<T: Copy> Unpack for T {
    type Out = T;
    unsafe fn unpack(&self) -> Self::Out {
        *self
    }
}