Я новичок в Swift и только что прочитал, что классы передаются по ссылке, а массивы / строки и т. Д. Копируются.
Проход по ссылке такой же, как в Objective-C или Java, где вы фактически передаете ссылку, или это правильный проход по ссылке?
swift
pass-by-reference
pass-by-value
pass-by-pointer
gran_profaci
источник
источник
Ответы:
Типы вещей в Swift
Правило такое:
Экземпляры класса являются ссылочными типами (т.е. ваша ссылка на экземпляр класса фактически является указателем )
Функции являются ссылочными типами
Все остальное тип значения ; «все остальное» просто означает экземпляры структур и экземпляры перечислений, потому что это все, что есть в Swift. Например, массивы и строки являются экземплярами структур. Вы можете передать ссылку на одну из этих вещей (в качестве аргумента функции), используя
inout
и взяв адрес, как указал newacct. Но тип сам по себе является типом значения.Что для вас значат ссылочные типы
На практике объект ссылочного типа является особенным, потому что:
Простое присвоение или передача функции может дать несколько ссылок на один и тот же объект.
Сам объект является изменяемым, даже если ссылка на него является константой (
let
явной или подразумеваемой).Мутация объекта влияет на этот объект с точки зрения всех ссылок на него.
Это может быть опасно, так что берегитесь. С другой стороны, передача ссылочного типа явно эффективна, потому что копируется и передается только указатель, что тривиально.
Какие типы значений значат для вас
Ясно, что передача типа значения «безопаснее» и
let
означает то, о чем говорится: вы не можете изменить экземпляр структуры или экземпляр перечисления черезlet
ссылки. С другой стороны, безопасность достигается созданием отдельной копии значения, не так ли? Разве это не делает передачу типа значения потенциально дорогостоящей?Ну да и нет. Это не так плохо, как вы думаете. Как сказал Нейт Кук, передача типа значения не обязательно подразумевает копирование, потому что
let
(явное или подразумеваемое) гарантирует неизменность, поэтому нет необходимости что-либо копировать. И даже переход вvar
ссылку не означает, что вещи будут скопированы, только то, что они могут быть при необходимости (потому что есть мутация). В документации особо не советуют выкручивать трусики.источник
inout
от типа. Является ли что-то передаваемым по ссылке, ортогонально типам.Это всегда передается по значению, если параметр не
inout
.Если параметр имеет значение, он всегда передается по ссылке
inout
. Однако это несколько усложняется тем фактом, что вам нужно явно использовать&
оператор для аргумента при передаче вinout
параметр, поэтому он может не соответствовать традиционному определению передачи по ссылке, где вы передаете переменную напрямую.источник
inout
)inout
на самом деле не передается по ссылке, а только с копированием. Он гарантирует только то, что после вызова функции измененное значение будет присвоено исходному аргументу. In-Out ПараметрыВсе в Swift по умолчанию передается "копией", поэтому, когда вы передаете тип значения, вы получаете копию значения, а когда вы передаете ссылочный тип, вы получаете копию ссылки со всем, что подразумевается. (То есть копия ссылки по-прежнему указывает на тот же экземпляр, что и исходная ссылка.)
Я использую пугающие кавычки вокруг «копии» выше, потому что Swift много оптимизирует; везде, где это возможно, он не копируется, пока не произойдет мутация или возможность мутации. Поскольку параметры по умолчанию неизменяемы, это означает, что в большинстве случаев копирования фактически не происходит.
источник
Вот небольшой пример кода для передачи по ссылке. Избегайте этого, если у вас нет для этого веской причины.
Назовите это так
источник
inout
это оператор копирования в, копирование из. Сначала он скопирует объект, а затем перезапишет исходный объект после возврата из функции. Хотя это может показаться одинаковым, между ними есть небольшие различия.В блоге Apple Swift Developer есть пост под названием Value and Reference Types. котором содержится четкое и подробное обсуждение этой самой темы.
Цитировать:
Сообщение в блоге Swift продолжает объяснять различия с примерами и предлагает, когда вы могли бы использовать одно вместо другого.
источник
По умолчанию классы передаются по ссылкам, а другие по значению. Вы можете передать по ссылке, используя
inout
ключевое слово.источник
inout
это оператор копирования в, копирование из. Сначала он скопирует объект, а затем перезапишет исходный объект после возврата из функции. Хотя это может показаться одинаковым, между ними есть небольшие различия.Когда вы используете inout с инфиксным оператором, например + =, то символ адреса & можно игнорировать. Полагаю, компилятор предполагает передачу по ссылке?
origDictionary + = newDictionaryToAdd
И хорошо, что этот словарь 'add' записывает только одну запись в исходную ссылку, так что отлично подходит для блокировки!
источник
Классы и структуры
Одно из наиболее важных различий между структурами и классами заключается в том, что структуры всегда копируются, когда они передаются в вашем коде, но классы передаются по ссылке.
Закрытие
Если вы назначаете замыкание свойству экземпляра класса, и замыкание захватывает этот экземпляр, ссылаясь на экземпляр или его члены, вы создадите цикл сильных ссылок между замыканием и экземпляром. Swift использует списки захвата, чтобы разорвать эти сильные ссылочные циклы
ARC (автоматический подсчет ссылок)
Подсчет ссылок применяется только к экземплярам классов. Структуры и перечисления являются типами значений, а не ссылочными типами, и не хранятся и не передаются по ссылке.
источник