Вопрос или проблема
- нет поля
main
в типеimpl Future<Output = Result<WeatherData, reqwest::Error>>
неизвестное поле [E0609]
#[derive(Debug, Deserialize, Clone)]
struct WeatherData {
main: Main,
}
#[derive(Debug, Deserialize, Clone)]
struct Main {
temp: Vec<f32>,
}
async fn get_weather() -> Result<WeatherData, reqwest::Error> {
reqwest::get("https://api.openweathermap.org/data/2.5/weather?q=neftekamsk&units=metric&cnt=8&appid=apikeyhere")
.await?
.json::<WeatherData>()
.await
}
fn test() {
get_weather().main.temp
}
Проверьте ваш тип данных, видимость и асинхронную функцию
#[derive(Debug, Deserialize, Clone)]
struct WeatherData {
pub main: Main,
// ^
// Убедитесь, что поле, к которому вы хотите получить доступ, является общедоступным
}
#[derive(Debug, Deserialize, Clone)]
struct Main {
pub temp: Vec<f32>,
}
async fn test() {
get_weather().await.unwrap().main.temp
// ^ ^
// | L тип возвращаемого значения - Result<WeatherData, reqwest::Error>,
// | необходимо развернуть перед доступом.
// |
// L get_weather() является асинхронным, вам нужно будет использовать .await, чтобы дождаться его завершения
}
Ответ или решение
Почему я не могу получить доступ к полю (нет поля в типе)
Ошибка, с которой вы столкнулись: "no field main
on type impl Future<Output = Result<WeatherData, reqwest::Error>>
", возникает по ряду причин, связанных с особенностями работы с асинхронными функциями в языке Rust, а также с доступностью полей структуры. Давайте детально разберемся в ситуации и выясним, что необходимо исправить в вашем коде.
1. Структуры и Доступность Полей
В языке Rust по умолчанию поля структур являются приватными. Это значит, что доступ к полям структур возможен только в пределах самого модуля, где эти структуры объявлены. Чтобы сделать поле доступным из других модулей или файлов, необходимо явно пометить его как pub
. В вашем случае это касается поля main
в структуре WeatherData
и поля temp
в структуре Main
. Исправьте код следующим образом:
#[derive(Debug, Deserialize, Clone)]
struct WeatherData {
pub main: Main,
}
#[derive(Debug, Deserialize, Clone)]
struct Main {
pub temp: Vec<f32>,
}
Добавив ключевое слово pub
, вы делаете эти поля доступными для внешнего кода.
2. Асинхронные Функции и Обработка Результатов
Поскольку функция get_weather()
объявлена как асинхронная, возвращаемое ею значение обернуто в impl Future
. Это означает, что результат выполнения функции нужно дождаться, вызывая .await
. Таким образом, когда вы пытаетесь обратиться к полю main
без использования await
, компилятор не может найти поле, так как функция еще не завершила выполнение.
Исправьте функцию test
, чтобы она была также асинхронной, и убедитесь, что вы используете .await
:
async fn test() {
let weather_data = get_weather().await.unwrap();
let temperature = weather_data.main.temp;
}
Поскольку метод unwrap
используется для получения значения, возвращаемого в случае успеха, вы извлечете доступ к полю temp
структуры Main
.
3. Ожидание и Ожидание Вызовов
Важно понимать, что асинхронный код требует специального подхода к вызову. Например, вам нужно будет запускать вашу асинхронную функцию в контексте, который поддерживает асинхронное выполнение, например, с использованием tokio
или async-std
. Убедитесь, что у вас есть соответствующий обработчик для запуска асинхронного кода.
Пример с tokio
:
#[tokio::main]
async fn main() {
test().await;
}
4. Вывод
Итак, основная причина ошибки заключалась в том, что:
- Поля структуры не были помечены как
pub
, что ограничивало к ним доступ. - Необходимо было использовать
.await
для асинхронной функции, чтобы дождаться результата выполнения.
Следуя вышеуказанным шагам, вы сможете устранить данную ошибку и успешно получить доступ к необходимым полям структуры. Rust требует строгости в обращении с типами и доступностью полей, что делает его мощным инструментом, но и создает определенные сложности при использовании.