как указать, что я хочу, чтобы тип generi c поддерживал "новый" - PullRequest
2 голосов
/ 03 августа 2020

Я хочу иметь фабричный метод, вызываемый из C

#[no_mangle]
pub extern "C" fn make<T>() -> *mut T{
        Box::into_raw(Box::new(T::new()))
}

, это не работает, потому что rust не знает, существует ли T :: new. Я знаю, что сделал бы черту, если бы хотел знать, что тип поддерживает функцию foo, которую я определил, но new уже существует.

Ответы [ 2 ]

2 голосов
/ 03 августа 2020

new не является так называемой «чертой» в Rust , потому что соглашение по дизайну является неограниченным; некоторые конструкторы new принимают аргументы, другие - нет, некоторые могут дать сбой, другие безошибочны. new - чисто условное имя; в противном случае он не имеет существенного значения в Rust . По соглашению они называются constructors, но это обычный метод stati c.

Типаж, который вы, кажется, ищете, - это Default, который определен для типов, для которых имеет смысл создавать новое значение без дополнительных аргументов, создающее разумное значение по умолчанию, такое как число 0, или логическое false, или пустую коллекцию.

В качестве альтернативы, если вы хотите преобразовать из одного аргумент, черта From - это то, что вы желаете:

#[no_mangle]
pub extern "C" fn make<T: Default>() -> *mut T{
    Box::into_raw(Box::new(T::default()))
}

Или:

#[no_mangle]
pub extern "C" fn make_from<X, T: From<X>>(x: X) -> *mut T{
    Box::into_raw(Box::new(T::from(x)))
}

Ограничение Type: Trait сообщает системе типов, что тип должен удовлетворять данной характеристике.

Если вы еще не знакомы с чертами в Rust , то они являются важной частью программирования на Rust, которую нужно освоить.

2 голосов
/ 03 августа 2020

В отличие от C ++, Rust не имеет таких функций, как неявный интерфейс на уровне шаблона, поэтому его нужно делать явно, например,

fn main() {
    make(|| Test::new);
}

pub fn make<T>(cl: impl Fn() -> T) -> *mut T
where {
        Box::into_raw(Box::new(cl()))
}

struct Test;

impl Test{
    fn new() -> Test {
        Test
    }
}

игровая площадка

Кроме того, атрибут no_mangle бесполезен с функциями generi c. Подробнее см. В соответствующем github issue .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...