LINUX.ORG.RU

Изучая Rust...

 , ,


1

4

Здравствуйте. Пытаюсь реализовать список на Rust. Вот что у меня получилось:

use std::fmt;

struct Node {
    value: i32,
    link: Option<Box<Node>>,
}

impl Node {
    fn new(value: i32) -> Node {
        Node { value: value, link: None, }
    }

    fn append(&mut self, value: i32) {
        match self.link {
            Some(ref mut node) => node.append(value),
            None => self.link = Some(Box::new(Node::new(value))),
        }
    }

    fn length(&self) -> i32 {
        match self.link {
            Some(ref node) => node.length() + 1,
            None => 1,
        }
    }

    fn insert_after(&mut self, value: i32, after: i32) -> bool {
        if self.value == after {
            self.link = Some(Box::new(Node { value: value, link: self.link.take() }));
            true
        }
        else {
            match self.link {
                Some(ref mut node) => node.insert_after(value, after),
                None => false,
            }
        }
    }
}

impl fmt::Display for Node {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.value)
        while
    }
}

fn main() {
    let mut stack = Node::new(1024);

     stack.append(67);

     println!("{}", stack);
}

Подскажите, как можно напечатать все элементы списка? В текущей реализации выводится только первый элемент.


Ответ на: комментарий от anonymous

И зачем тут выпячивание указателя?

Потому что указатель можно использовать как optional. А что тут даст CoW?

DarkEld3r ★★★★★
()
Ответ на: комментарий от DarkEld3r

«Затраты» - это у тебя память? Потому что мы говорили именно о ней.

И она тоже. Повторюсь, шарить имеет смысл только целый стиль, который может повторятся в рамках одного документа, все остальное - попытка сэкономить на спичках.

И ты серьёзно думаешь, что ничего не измерялось и тут ты такой прибегаешь и предлагаешь «решение всех проблем»?

Я лишь предлагаю не решать те проблемы, которые не являются проблемами.

Естественно, но такого я и не утверждал. Ок, пусть это было недопонимание.

Окей. Правда к чему тогда было «И да, «выпячивать указатели» удобно - свойства могут задаваться на разных уровнях. В итоге резолвинг выглядит как-то так: берём дефолтные свойства и проходимся по «уровням» и если свойство имеется - заменяем»? Если у тебя свойства не в виде указателей, нет оберток вроде QString, и нет optional - как ты по ним проходишься? Хранишь флаги?

Выступаешь против расшивания мелких сущностей и при этом предлагаешь использовать QString с CoW внутри. Зачем?

Затем, что CoW абсолютно бесплатен в плане кода, наоборот, он делает его проще. И он безопасен. А ручной shared_ptr - и глаза мозолит, и забота о пустых указателях всегда на тебе.

anonymous
()
Ответ на: комментарий от DarkEld3r

Потому что указатель можно использовать как optional. А что тут даст CoW?

Безопасность и краткость. Я уже приводил выше пример.

anonymous
()
Ответ на: комментарий от DarkEld3r

Выступаешь против расшивания мелких сущностей и при этом предлагаешь использовать QString с CoW внутри. Зачем?

CoW + строки = красивый API

use std::borrow::Cow;

struct Foo<'a> {
    s: Cow<'a, str>
}
impl<'a> Foo<'a> {
    fn new<S: Into<Cow<'a, str>>>(string: S) -> Self {
        Foo {
            s: string.into()
        }
    }
    fn show(&self) {
        println!("{}", self.s);
    }
}

fn main() {
    let s1 = "123"; // &str
    let s2 = String::from("123"); // String
    
    let foo1 = Foo::new(s1);
    let foo2 = Foo::new(s2);
    
    foo1.show();
    foo2.show();
}

shaiZaigh
()

Подумал, не залить ли своё поделие на crates.io - а там логин только через github. Анальненько.

anonymous
()
Ответ на: комментарий от anonymous

Потому что where надо использовать.

anonymous
()
Ответ на: комментарий от anonymous

Повторюсь, шарить имеет смысл только целый стиль

Как скажешь.

Просто представь на секунду, что это не я в одиночку велосипед пилю. И что всё посчитано и измерено.

Свойства могут быть заданы на уровне всего документа или параграфа или рана (или строки в таблице и т.д.). Свойства - это (для простоты) набор флажков, которые в optional как раз завёрнуты. В итоге у всех сущностей есть указатель на свойства и одинаковые свойства шарятся. Куда тут и зачем втыкать CoW?

«Ручной shared_ptr» слабо отличается от optional, кстати. И чем поможет CoW, если иметь «пустое» значение необходимо?

У меня такое ощущение, что мы о разном говорим просто. Давай как-то к общему знаменателю прийдём, а то толку не будет.

DarkEld3r ★★★★★
()
Ответ на: комментарий от anonymous

Безопасность и краткость. Я уже приводил выше пример.

Он крайне неубедителен. Во первых, «похерить шрифт во всей программе» случайно нельзя - доступ на чтение и модификацию разделён. Во вторых, «пустая строка» от «пустого указателя» принципиально не отличается, если нам нужно конкретное значение. Если не нужно, то опять же, обе ситуации изображают «отсутствие значения».

DarkEld3r ★★★★★
()
Ответ на: комментарий от shaiZaigh

CoW + строки = красивый API

Про std::borrow::Cow в расте в курсе, но это как раз отдельная штука, которую нужно сознательно применять, а не размазанная по (практически) всем классам «фича» как в Qt.

И согласись, что твой пример несколько надуман - зачастую мы заранее знаем нужно ли структуре владеть данными или нет. И стандартная библиотека, вроде, не обмазана всюду CoW, нет?

DarkEld3r ★★★★★
()
Ответ на: комментарий от anonymous

а там логин только через github. Анальненько.

Ну они пишут, что это может и измениться. Да и разве это такая большая проблема?

DarkEld3r ★★★★★
()
Ответ на: комментарий от DarkEld3r

И согласись, что твой пример несколько надуман - зачастую мы заранее знаем нужно ли структуре владеть данными или нет. И стандартная библиотека, вроде, не обмазана всюду CoW, нет?

Преобразовать &str в String можно двумя методами: .to_owned() и .to_string(). Второй способ охватывает большее количество типов и предполагает лишние аллокации, в итоге приходится выбирать: пара лишних байт оверхеда и защита от дурака в случае с CoW, либо с помощью многословия предоставить пользователю возможность сделать неэффективно. Высокоуровневым фреймворкам незачем экономить на спичках.

shaiZaigh
()
Ответ на: комментарий от shaiZaigh

Преобразовать &str в String можно двумя методами: .to_owned() и .to_string(). Второй способ охватывает большее количество типов и предполагает лишние аллокации

Это до тех пор пока специализации не допилят.

Но я так и не понял что ты предлагаешь.

DarkEld3r ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.