Я ожидаю, что результатом будет словарь, но доступ к нему осуществляется как к свойству... почему?

У меня есть этот JSON, поступающий с сервера...

{
  "cars": [
    {
      "name": "Ferrari",
      "price": "100"
    },
    {
      "name": "Lamborghini",
      "price": "200"
    },
    {
      "name": "Ford Pinto",
      "price": "1"
    }
  ]
}

Этот JSON представляет собой словарь под названием cars, который содержит массив автомобилей, верно?

Тогда у меня есть эта структура...

struct Cars: Codable {
    let cars: [Car]
}


struct Car: Codable, Hashable, Identifiable {
    let id = UUID()
    let name: String
    let price: String
}

и я декодирую JSON, используя это:

let (data, _) = try await urlSession.data(from: url)
let result = try JSONDecoder().decode(Cars.self, from: data)
let listOfCars = result.cars

Это то, чего я не понимаю.

в result.cars, cars — это свойство result, объявленное как массив в структуре Cars. Не словарь.

Я ожидал получить к нему доступ с помощью result["cars"].

Это почему?

Если мы аннотируем результат как let result: Cars, тогда он становится более понятным. result — это не словарь, это структура типа Cars.

Alladinian 06.12.2022 13:51
Как сделать HTTP-запрос в Javascript?
Как сделать HTTP-запрос в Javascript?
В JavaScript вы можете сделать HTTP-запрос, используя объект XMLHttpRequest или более новый API fetch. Вот пример для обоих методов:
3
1
69
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

В вашем коде здесь...

let (data, _) = try await urlSession.data(from: url)
let result = try JSONDecoder().decode(Cars.self, from: data)
let listOfCars = result.cars

result является экземпляром Struct Cars. Ваш установочный код сообщил Swift, как преобразовать словарь JSON в ваш собственный Struct.

Таким образом, доступ ко всему внутри result осуществляется так же, как и в следующем...

let result = Cars(cars: [
  Car(name: "Ford", price: "£10,000")
])

print(result.cars)

Единственная разница в том, как вы его создаете. Вместо использования метода инициализации, подобного этому, вы используете декодирование JSON для декодирования некоторого JSON в ваш собственный тип.

Ясно спасибо. Удивительное объяснение.

Duck 06.12.2022 15:01

Как сказано в комментариях и ответах, он принимает тип результата в соответствии с вашей стратегией декодирования. В вашем коде result type is Cars не dictionary. Таким образом, вы получаете доступ к свойствам с помощью result.cars

Если вы хотите что-то вместо словаря, вам нужно декодировать его как

let result = try decode.decode([String : [Car]].self, from: data)

Теперь вы можете получить к ним доступ как к словарю

print(result["cars"]?.first?.name) // Optional("Ferrari")

аааа, теперь вижу. Swift, если творит здесь какую-то магию и манипулирует исходным JSON. Но в оригинальном JSON появится словарь, верно?

Duck 06.12.2022 14:59

Да, это @Duck

Omer Tekbiyik 06.12.2022 15:06

Другие вопросы по теме