Каково время жизни аргументов FromSql :: from_sql? - PullRequest
2 голосов
/ 23 мая 2019

Я использую Diesel с Postgres и хочу запросить поле text как *const str. Дизель имеет реализацию FromSql для *const str.

Документация описывает:

Возвращенный указатель только действителен в течение времени жизни аргумента from_sql.

Какова продолжительность жизни до аргумента from_sql? Это то же самое, что и время жизни соединения?

1 Ответ

1 голос
/ 23 мая 2019

from_sql примет Option<&'a DB::RawValue> и вернет Result<*const str>.

Без необработанных указателей (и с явным временем жизни) определение функции будет выглядеть примерно так:

fn from_sql<'a>(bytes: Option<&'a DB::RawValue>) -> Result<&'a str>

что время жизни выхода для входа здесь очевидно и проверено статически - но с необработанными указателями это не так:

fn from_sql<'a>(bytes: Option<&'a DB::RawValue>) -> Result<*const str>

предупреждение просто указывает на то, что полученный вами указатель гарантированно будет действителен только в течение жизненного цикла &'a DB::RawValue, который вы передаете в функцию. Предупреждение было бы ненужным без необработанных указателей, потому что компилятор гарантировал бы, что &str живет только столько, сколько на него ссылаются.

Это реализация from_sql:

fn from_sql(bytes: Option<&DB::RawValue>) -> deserialize::Result<Self> {
    use std::str;
    let string = str::from_utf8(not_none!(bytes))?;
    Ok(string as *const _)
}

Причина, по которой время жизни выходного файла зависит от аргумента bytes, заключается в том, что str::from_utf8 просто выполняет проверку UTF-8 и выполняет небезопасное приведение bytes к &str - по сути, вы просто возвращаете введите обратно как другой тип. Результат from_sql - это просто указатель на те же данные, которые вы передали в него, так что указатель действителен только до тех пор, пока эти входные данные действительны.

...