Я играл со Swift's Data
в следующем маленьком коде:
var d = Data(count: 10)
d[5] = 3
let d2 = d[5..<8]
print("\(d2[0])")
К моему удивлению, этот код создает исключение для print()
, тогда как следующий код этого не делает:
var d = Data(count: 10)
d[5] = 3
let d2 = d.subdata(in: 5..<8)
print("\(d2[0])")
Я как-то понимаю, почему это происходит, но я не понимаю, почему это так устроено. Когда я использую subdata()
, я получаю полную копию диапазона, поэтому индексирование действует с 0
. Но когда я использую диапазон подписки []
, я получаю доступ к запрошенному диапазону, в то время как индексирование такое же, как и раньше. Так что в моем первом примере d2[5]
это 3
.
Но мне интересно, почему он так устроен? Я не хочу делать копии моих данных, используя метод subdata()
. Я просто хотел получить доступ к части моих данных с лучшей индексацией.
Это особенно создает неожиданное поведение, если вы передаете его функции. Например, следующий код создает неожиданные результаты и исключения, и вы не можете легко выяснить, почему:
func testit(idata: Data) {
if idata.count > 0 {
print("\(idata.count)")
print("\(idata[0])")
}
}
//...
var d = Data(count: 10)
d[5] = 3
let d2 = d[5..<8]
testit(idata: d2)
Этот код действительно странный. Потому что если вы отлаживаете свой код, вы увидите, что print("\(idata.count)")
печатает 3
размером idata
, что правильно, но доступ к нему с помощью idata[0]
создает исключение.
Есть ли причина для этого дизайна? Я ожидал, что смогу получить доступ к Data
из начального индекса подписки 0, хотя это не так. Могу ли я сделать это без использования subdata()
, который создает копию данных или использования дополнительных аргументов для передачи базы среза данных?