Ответы пользователя по тегу Rust
  • Как оптимизировать код в rust при помощи trait?

    Trame2771
    @Trame2771
    Как я понял, дать гарантии компилятору, для того, чтобы сделать то, что вы хотите, пока нельзя, или сделать это будет очень неочевидно. Гарантии нужны потому что язык безопасный. Возможно когда добавят кастомные маркеры в язык, тогда можно будет чё-то гарантировать. А пока можно пользоваться макросами. Это не так плохо как кажеться. Это не нагружает бинарник, нагружает только компилятор. Причем линейно. Нагрузка на компилятор будет составлять (Количество типов * количество функций). Правда если будет использоваться больше одного типа в структуре, тогда будет применятся комбинаторика для определения нагрузки на компилятор. То есть само приложение будет таким же производительным, правда из-за нагрузки на компилятор, он может перестать немного оптимизировать код. Вот решение чтобы не дублировать код:
    mod float_trait {
        pub trait Float {}
        impl Float for f32 {}
        impl Float for f64 {}
    }
    
    use crate::float_trait::Float;
    
    mod float_struct {
        use crate::float_trait::Float;
    
        #[derive(Debug)]
        pub struct FloatStruct<T: Float>
        {
            _a: i8,
            _b: String,
            pub c: T,
        }
        
        macro_rules! impl_float_struct {
            ($($type:ty),*) => {
                $(
                    impl FloatStruct<$type> {
                        pub fn new() -> Self {
                            Self {
                                _a: 2,
                                _b: String::from("hi"),
                                c: 0.3,
                            }
                        }
                    }
                )*
            }
        }
        
        impl_float_struct![f32, f64];
    }
    
    fn main() {
        let fs = float_struct::FloatStruct::<f32>::new();
        println!("{:#?}", fs.c)
    }


    Другое решение, очевидно нагружающее само приложение, и лёгкое для компилятора
    mod float_trait {
        pub trait Float {}
        impl Float for f32 {}
        impl Float for f64 {}
    }
    
    mod float_struct {
        use crate::float_trait::Float;
    
        #[derive(Debug)]
        pub struct FloatStruct<T: std::str::FromStr + Float>
        {
            _a: i8,
            _b: String,
            pub c: T,
        }
    
        impl<T: std::str::FromStr + Float> FloatStruct<T> {
            pub fn new() -> Self {
                Self {
                    _a: 2,
                    _b: String::from("hi"),
                    c: {
                        let Ok(r) = "0.3".parse::<T>()
                            else {unreachable!()};
                        r
                    }
                }
            }
        }
    }
    
    fn main() {
        let fs = float_struct::FloatStruct::<f32>::new();
        println!("{:#?}", fs.c)
    }
    Ответ написан
    1 комментарий
  • Почему атрубут из extern prelude не работает при re-export-е в модуль?

    Trame2771
    @Trame2771 Автор вопроса
    Я кажеться понял. Это вопрос больше не к языку, а к либе. По сообщаемой компилятором ошибке мне кажеться, что атрибут не из модуля с целевым типом каким-то образом видит этот тип с префиксом пути к типу и его алгоритм парсинга ломается. Он считает часть описания типа, которая относиться к пути до него, частью самого типа и не может сапоставить такой тип с указанными атомарными у себя
    Ответ написан