Я не знаю точного обоснования, но предположительно let ptr = &index
не разрешено, потому что нет никакой гарантии, что вы можете разыменовать ptr
, не вызывая неопределенное поведение (при условии, что index
неглобальная или static
хранимая переменная - единственные случаи, когда Swift гарантирует стабильные и уникальные значения указателя.
В отличие от других языков, Swift не гарантирует, что локальная переменная останется инициализированной до конца области видимости.он объявлен в - оптимизатор может деинициализировать его раньше.Поэтому, допустив let ptr = &index
, можно было бы слишком легко писать неправильный код.
Стоит отметить, что ваш пример:
func point(num: UnsafePointer<Int32>) -> UnsafePointer<Int32> {
return num
}
let ptr = point(num: &index)
также неэффективен.Попытка разыменования ptr
из let ptr = point(num: &index)
является неопределенным поведением, поскольку преобразование аргумента inout-to-pointer создает временный указатель, действительный только на время вызова функции.
Если вы хотите scoped временный указатель на значение, вы можете использовать withUnsafePointer(to:)
- например:
func baz() {
var foo = 5
withUnsafePointer(to: &foo) { ptr in
// use `ptr` here – do not escape it!
}
// In Swift 4.2 you can also use `withUnsafePointer(to:)` on let constants.
let bar = 5
withUnsafePointer(to: bar) { ptr in
// use `ptr` here – do not escape it!
}
}
Обратите внимание, что указатель действителен только на время закрытия - попыткавыход из него приведет к неопределенному поведению.