Как вернуть &str из функции?


#1

Здравствуйте!
Споткнулся на ровном месте и не могу понять в чём причина.
Суть - нужно на основании параметра функции сформировать строку и вернуть её. Но компилятор постоянно ругается на то, что я пытаюсь вернуть заимствованное значение. .clone и to_owned не помогают.
Вот немного упрощенный код

pub fn new(redirect_port: u16) -> Self {
        let mut url = "http://127.0.0.1:".to_string();
        url.push_str(&redirect_port.to_string());
        Authorizer {
            redirect_url: url.to_owned().as_str()
        }
    }

Сейчас выдаёт ошибку

59 | |             redirect_url: url.to_owned().as_str()
   | |                           -------------- temporary value created here
60 | |         }
   | |_________^ returns a value referencing data owned by the current function

Но почему это временное значение? Я так понимаю, url.to_owned создаёт копию String и передаёт владение вызывающей стороне, а as_str - возвращает просто указатель на неё. По идее, должно всё работать.

Спасибо.


#2

А где здесь происходит эта часть?

и передаёт владение вызывающей стороне

Владение, это, грубо говоря, где-то существующая переменная типа String с нужным текстом. И не просто в стеке, как создаёт to_owned(). Потому, что стек очистится при выходе из функции.
Может вам не нужно хранить ссылку на строку, а нужно хранить всю строку, но потом уже передавать на неё ссылку куда-то ещё?


#3

но само значение никому во владение не отдается. Значение остается temporary (временным) и удаляется в конце функции. Можно убрать to_str() и поменять тип redirect_url на String - в этом случае владение перейдет к структуре Authorizer.


#4

Может я чего-то не понимаю, но &str это ж по сути ссылка.
Т.е. возвращать надо либо структуру (String), либо ссылку на объект чьё время жизни лежит за пределами функции.
А так ты возвращаешь ссылку на элемент структуры String которая уничтожится по выходу из функции.


#5

А разве to_owned создаёт копию в стеке?

Как-так? Я же и возвращаю копию!

Так я же возвращаю структуру, в которой содержится ссылка на строку. Можно, конечно, хранить там String, но хочу прояснить момент со &str.

Нет, я возвращаю всю структуру. Немного неправильно сформулировал вопрос, наверное.


#7

А где хранится сама строка? Прально, нигде. Она по выходу из функции уничтожается.
Creates owned data from borrowed data, usually by cloning. (цы)
У тебя String на стеке создан и никуда не девается из функции.


#8

Неважно в чём ты возвращаешь ссылку. Сам объект ты не возвращаешь.


#9

Ну вот я предполагаю, что владельцем должна быть структура. Причём должна владеть именно &str, а не String.
Похоже, так вообще не получится, т.к. чистый объект str - это строка созданная при компиляции. А &str - это уже срез от какой-то сроки. Т.е. невладеющая ссылка. Но как-то я не уверен…


#10

Вот теперь правильно мыслите :slight_smile:


#11

Да, это слайс и владеть он не может.
Rust has only one string type in the core language, which is the string slice str that is usually seen in its borrowed form &str . (цы)


#12

Всем спасибо! :slight_smile: