Trame2771
@Trame2771

Как объявить тип, который является коллекцией значений разных типов, которые можно конвертировать в другие типы ❌️с помощью trait-а Into❌️?

Мне нужен Vec<&dyn Into<JsValue>>
Используя его, компилятор ругается, что он не object safe (Сам Into, потому что требует Self: Sized)
Как мне это исправить? Дублировать реализацию для каждого нужного мне типа, реализуещего Into, так, чтобы компилятор не ругался (правда я не понимаю почему Into требует Self: Sized, поэтому возможно так нельзя сделать)? Или есть нормальное решение?

Edit#1:
Если что вот код, где мне нужен такой вектор (я его использую как varargs):
mod my_prelude {
    pub use ::wasm_bindgen::JsValue;
}

mod additions {
    use crate::my_prelude::*;
    
    pub mod console {
        use crate::my_prelude::*;
        
        pub fn log(v: &Vec<&dyn Into<JsValue>>) {
            let len = v.len();
            let arr = ::js_sys::Array::new_with_length(len as u32);
            let mut index: usize = 0; while index < len {
                arr.set(index as u32, v[index].clone().into());
                index += 1;
            }
            
            ::web_sys::console::log(&arr);
        }
    }
}

У меня плохое предчувствие. Если я узнаю, что я не могу сделать varargs через Vec, то я разочаруюсь в rust... Предчувствие у меня такое потому, что в либе, которую я использую, тоже нет функции console::log с таким своеобразным varargs. Только log1, log2, и т.д. Так же потому, что в поисковике нет результатов на запрос "the trait `Into` cannot be made into an object". Если всё упирается в object safe, тогда rust нифига не гибкий язык, и чем тогда он отличается от противного C? (Ладно, не C, а C++. В С++ такое бы сработало, но он не безопасный. Для меня нет смысла в такой безопасности в Rust, если его полиморфизм не позволяет делать нужного мне типа varargs. Это вообще тогда никакой не полиморфизм и dyn не замена ООП в других языках)

EDIT#2:
Блин, у меня вопрос совсем безнадёжный. Я думал конвертация только с помощью trait-a Into происходит, или с помощью TryInto,что по сути одно и тоже, но нет. Оказываеться есть ещё AsRef. Правильный вопрос был бы, если бы в конце было бы: "которые можно конвертировать в другие типы с помощью имеющихся trait-ов" Только вот я не понимаю как AsRef работает. И ещё проблема в том, что AsRef имплементации для примитивных типов нет. Хотя есть trait-ы From<Для каждого примитива> в wasm_bingen::JsValue. Как мне запихивать в мою коллекцию примитивы?
Частично исправленный код:
mod my_prelude {
    pub use ::wasm_bindgen::{JsValue, };
}

mod additions {
    use crate::my_prelude::*;
    
    pub mod console {
        use crate::my_prelude::*;
        
        pub fn log(varargs: &Vec<&dyn AsRef<JsValue>>) {
            let len = varargs.len();
            let arr = ::js_sys::Array::new_with_length(len as u32);
            let mut index: usize = 0; while index < len {
                arr.set(index as u32, varargs[index].as_ref().clone());
                index += 1;
            }
            
            ::web_sys::console::log(&arr);
        }
    }
}

fn main() {
    additions::console::log(vec![&canvas, &2]); // &2 не имеет AsRef. Но оно имеет Into. А Into не проходит в dyn. Как использовать примитивы в моём векторе?
}
  • Вопрос задан
  • 107 просмотров
Решения вопроса 1
vabka
@vabka Куратор тега Rust
В твоём случае тебе нужно завести новый trait, который будет брать ссылку на оригинальный объект, в отличие от Into. Потом ты сможешь сделать blanket implementation наподобие
impl<T: Clone + Into<JsValue>> MyIntoJsValue for T {
    fn into_jsvalue(&self) -> JsValue{
        self.clone().into()   
    }
}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы