Указатели в Swift

Я пытаюсь понять использование указателей в Swift, в частности: Unsafe[Mutable]Pointer и UnsafeRaw[Mutable]Pointer. У меня есть несколько вопросов по теме.

  1. Является ли UnsafePointer <T> равным const T * Pointer в ? и UnsafeMutablePointer <T> равно T * Pointer в C?

  2. В чем разница между Unsafe[Mutable]Pointer и UnsafeRaw[Mutable]Pointer?

  3. Почему это компилируется

func receive(pointer: UnsafePointer<Int> ) {
    print("param value is: \(pointer.pointee)")
}

var a: Int = 1
receive(pointer: &a) // prints 1

but this gives me an error?

var a: Int = 1
var pointer: UnsafePointer<Int> = &a // error : Cannot pass immutable value of type 'Int' as inout argument

person emacos    schedule 22.02.2017    source источник


Ответы (1)


  1. Является ли UnsafePointer <T> равным const T * Pointer в ? и UnsafeMutablePointer <T> равно T * Pointer в C?

Что ж, используйте заголовок моста в приложении Swift, чтобы увидеть, как соединяются указатели C:

const int *myInt;
int *myOtherInt;

мосты к

var myInt: UnsafePointer<Int32>!
var myOtherInt: UnsafeMutablePointer<Int32>!
  1. В чем разница между Unsafe[Mutable]Pointer и UnsafeRaw[Mutable]Pointer?

В Swift 3 добавлен API UnsafeRawPointer для замены тип Unsafe[Mutable]Pointer<Void>. Преобразование между указателями другого типа больше не разрешено в Swift. Вместо этого API предоставляет интерфейсы (.assumingMemoryBound(to:) или .bindMemory(to:capacity:)) для привязки памяти к типу.

Что касается вопроса 3, амперсанд означает, что переменная inout. Я не думаю, что вы можете объявить переменную как inout, если только она не используется функцией, которая напрямую изменяет базовую память, но я позволю экспертам меня исправить. Вместо этого используйте withUnsafePointer.

Благодаря полезному комментарию Мартина этот синтаксис никогда не был допустимым в Swift, и не существует безопасного способа создания «свободных указателей» на переменные Swift.

person JAL    schedule 22.02.2017
comment
var pointer: UnsafePointer<Int> = &a никогда не был действительным, и ваш обходной путь небезопасен: указатель, переданный замыканию withUnsafePointer, действителен только во время выполнения замыкания. Он не должен выходить за пределы укупорочного средства. – Вы не можете (безопасно) свободно передавать указатели на переменные Swift. - person Martin R; 22.02.2017
comment
@MartinR Спасибо, я отредактирую свой ответ. Не совсем понятно, чего хотел ОП, поэтому я не был уверен, хотят ли они безопасного/небезопасного поведения. Но ясно, что они плохо знакомы с указателями, лучше просто полностью удалить любое небезопасное поведение. - person JAL; 22.02.2017