LINUX.ORG.RU

История изменений

Исправление balsoft, (текущая версия) :

такое можно «провернуть» только со структурами, у которые в полях простые типы.

В таком случае у тебя функция будет возвращать по значению, а не по ссылке. Вернуть по ссылке объект на стеке просто нельзя, потому что фрейм пропадет после завершения функции и останется ссылка на мусор.

Если тебе очень хочется вернуть именно по ссылке, то нужно делать объект (который struct A внутри твоего struct B) на куче, а не на стеке. Внизу уже скинули Box, который делает именно это.

Например, так:

use std::boxed::Box;

struct A {
    i: i64,
}

struct B {
    a: Box<A>,
}

fn create_b(i: i64) -> B {

    let a = Box::new(A { i, });

    let b = B {
        a,
    };

    b
}

Если тебя устраивает утекающая память, то можно так:

use std::boxed::Box;

struct A {
    i: i64,
}

struct B<'a> {
    a: &'a A,
}

fn create_b<'a>(i: i64) -> B<'a> {

    let a = Box::<A>::leak(Box::new(A { i }));

    let b = B {
        a,
    };

    b
}

Но вообще обычно в таких случаях (когда ну очень нужно инициализировать объект по ссылке в функции, ради оптимизации например), то используют MaybeUninit: https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#out-pointers

Исправление balsoft, :

такое можно «провернуть» только со структурами, у которые в полях простые типы.

В таком случае у тебя функция будет возвращать по значению, а не по ссылке. Вернуть по ссылке объект на стеке просто нельзя, потому что фрейм пропадет после завершения функции и останется ссылка на мусор.

Если тебе очень хочется вернуть именно по ссылке, то нужно делать объект (который struct A внутри твоего struct B) на куче, а не на стеке. Внизу уже скинули Box, который делает именно это.

Например, так:

use std::boxed::Box;

struct A {
    i: i64,
}

struct B {
    a: Box<A>,
}

fn create_b(i: i64) -> B {

    let a = Box::new(A { i, });

    let b = B {
        a,
    };

    b
}

Если тебя устраивает утекающая память, то можно так:

use std::boxed::Box;

struct A {
    i: i64,
}

struct B<'a> {
    a: &'a A,
}

fn create_b<'a>(i: i64) -> B<'a> {

    let a = Box::<A>::leak(Box::new(A { i }));

    let b = B {
        a,
    };

    b
}

Но вообще обычно в таких случаях (когда ну очень нужно инициализировать объект по ссылке в функции) используют MaybeUninit: https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#out-pointers

Исправление balsoft, :

такое можно «провернуть» только со структурами, у которые в полях простые типы.

В таком случае у тебя функция будет возвращать по значению, а не по ссылке. Вернуть по ссылке объект на стеке просто нельзя, потому что фрейм пропадет после завершения функции и останется ссылка на мусор.

Если тебе очень хочется вернуть именно по ссылке, то нужно делать объект (который struct A внутри твоего struct B) на куче, а не на стеке. Внизу уже скинули Box, который делает именно это.

Например, так:

use std::boxed::Box;

struct A {
    i: i64,
}

struct B {
    a: Box<A>,
}

fn create_b(i: i64) -> B {

    let a = Box::new(A { i, });

    let b = B {
        a,
    };

    b
}

Если тебя устраивает утекающая память, то можно так:

use std::boxed::Box;

#[derive(Debug)]
struct A {
    i: i64,
}

#[derive(Debug)]
struct B<'a> {
    a: &'a A,
}

fn create_b<'a>(i: i64) -> B<'a> {

    let a = Box::<A>::leak(Box::new(A { i }));

    let b = B {
        a,
    };

    b
}

Но вообще обычно в таких случаях (когда ну очень нужно инициализировать объект по ссылке в функции) используют MaybeUninit: https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#out-pointers

Исправление balsoft, :

такое можно «провернуть» только со структурами, у которые в полях простые типы.

В таком случае у тебя функция будет возвращать по значению, а не по ссылке. Вернуть по ссылке объект на стеке просто нельзя, потому что фрейм пропадет после завершения функции и останется ссылка на мусор.

Если тебе очень хочется вернуть именно по ссылке, то нужно делать объект (который struct A внутри твоего struct B) на куче, а не на стеке. Внизу уже скинули Box, который делает именно это.

Но вообще обычно в таких случаях (когда ну очень нужно инициализировать объект в функции) используют MaybeUninit: https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#out-pointers

Исправление balsoft, :

такое можно «провернуть» только со структурами, у которые в полях простые типы.

В таком случае у тебя функция будет возвращать по значению, а не по ссылке. Вернуть по ссылке объект на стеке просто нельзя, потому что фрейм пропадет после завершения функции и останется ссылка на мусор.

Если тебе очень хочется вернуть именно по ссылке, то нужно делать объект на куче, а не на стеке. Внизу уже скинули Box, который делает именно это.

Но вообще обычно в таких случаях (когда ну очень нужно инициализировать объект в функции) используют MaybeUninit: https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#out-pointers

Исходная версия balsoft, :

такое можно «провернуть» только со структурами, у которые в полях простые типы.

В таком случае у тебя функция будет возвращать по значению, а не по ссылке. Вернуть по ссылке объект на стеке просто нельзя, потому что фрейм пропадет после завершения функции и останется ссылка на мусор.

Если тебе очень хочется вернуть именно по ссылке, то нужно делать объект на куче, а не на стеке. Внизу уже скинули Box, который делает именно это.