LINUX.ORG.RU

Простой конструктор.

 


0

5

Начал изучать RUST. Как в этом вашем RUST сделать некий аналог конструктора бы возвращал уже собранный объект по ссылке. Например

struct A {
    c: String
}
impl A {
    fn new() ->  A {
      A {c:String::from("TEST1")}
    }
}

тут у нас как я понимаю у нас будет одно лишняя копия объекта А. а как сделать что бы не было лишнего копирования.

ну на подобии:

struct B<'b> {
    c: &'b String,
}

impl<'b> B<'b> {
    fn new() -> &mut B<'b> {
        &B { c: String::from("TEST2") }
    }
}

И так не будет лишней копии. По ссылке не нужно. В расте ссылки не могут заменить указатель и ведут себя по другому.

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

А так

А в такой реализации будет создана копия?

struct A {
    c: String
}
impl A {
    fn new() ->  A {
        let a= A {c:String::from("TEST1")};
        return a;
    }
}
Я правильно понимаю что ссылки в RUST подобны ссылка в С++, не могу существовать без уже созданного объекта?

Loafter
() автор топика
Ответ на: А так от Loafter

В этом коде можно статически доказать что копия не нужна и ее не будет.

Да, ссылки похожи на с++ ссылки.

Можно создать владеющую ссылку Box<A> если очень нужна ссылка. Но в таком случае будет как раз копия.

    fn new() ->  Box<A> {
        return Box::new(A {c:String::from("TEST1")});
    }

Структура A будет создана на стеке, а потом скопированна в динамически выделенную память.

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

можно без return, так более «функционально» выглядит

    fn new() ->  Box<A> {
        Box::new(A {c:String::from("TEST1")})
    }

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

В расте ссылки не могут заменить указатель и ведут себя по другому.

Если под «по другому» ты подразумеваешь, что они не дадут взять адрес на переменную на стеке функции, которой после возврата не будет, и выстрелить себе в ногу — то да

ТС, тебе не нужен Box тут. Box — выделение памяти под объект в куче. При возврате объекта работает мув-семантика, никакого копирования нет. Точнее есть, но побитовое и тебя это волновать не должно от слова совсем: лишние копирования LLVM срежет.

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

Хорошо одни вопрос плавно перетек в другой вопрос

use std::path::Path;
pub struct Walker {
    cur: Path
}
impl Walker {
    pub fn new() -> Walker {
        Walker {
            cur: Path::new("foo.txt")
        }
    }
}
mod path_walker;
use path_walker::walker::Walker;
fn main() {
    let p=Walker::new();
}

the trait bound `[u8]: std::marker::Sized` is not satisfied in `path_walker::walker::Walker` let p=Walker::new(); | ^ `[u8]` does not have a constant size known at compile-time

Loafter
() автор топика
Ответ на: комментарий от quantum-troll

Хорошо но это не ответ на вопрос

я не совсем понимаю по чему просто создать объект

let path = Path::new("/tmp/foo/bar.txt");
в стеке можно? а как поле структуры уже нет?

Loafter
() автор топика
Ответ на: комментарий от mersinvald

Сходу не нашёл статью, но «ссылки» в rust != ссылки в C++. В Rust & - это оператор заимствования. В C++ же это скорее константный указатель.

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

Зависит от того как смотреть на вопрос: семантически растовые ссылки более ограничены (и фичасты).

На низком уровне — те же указатели.

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

Стало уже понятней.

Я могу интерпретировать:

Объект, размер которого неизвестен во время компиляции не можно >возвращать из функции.

Нельзя ввернуть ссылку &str на объект так как не известен размер объекта?

но ведь в примере

cur: Path::new("foo.txt")
это же строковая константа и размер ее известен компилятору.

Loafter
() автор топика
Ответ на: Стало уже понятней. от Loafter

Path содержит OsStr и размера не имеет. А вот &Path имеет размер машинного слова. Ну и в довесок, Path::new возвращает как раз таки &Path, а не Path.

use std::path::Path;
pub struct Walker<'a> {
    cur: &'a Path
}
impl<'a> Walker<'a> {
    pub fn new() -> Walker<'a> {
        Walker {
            cur: Path::new("foo.txt")
        }
    }
}
И всё это уже давно описали, обсудили и задокументировали.

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

Можно создать владеющую ссылку Box<A> если очень нужна ссылка. Но в таком случае будет как раз копия.

В релиз-билде не будет, компилятор это оптимизирует.

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