Является точной передачи по значению или пройти по ссылке
Я действительно Новичок в Swift и я просто читал, что классы передаются по ссылке и массивы/строки и т. д. копируются.
является ли передача по ссылке таким же образом, как и в Objective-C или Java, где вы фактически передаете ссылку "a" или это правильный переход по ссылке?
6 ответов:
типы вещей в Swift
правила:
экземпляров класса ссылка типа (т. е. код ссылка на экземпляр класса эффективно указатель)
функции являются ссылочными типами
все остальное тип значения; "все остальное" просто означает экземпляры структур и экземпляров перечислений, потому что это все есть в Свифте. Массивы и строки являются экземплярами структуры, например. Ты можете передайте ссылку на одну из этих вещей (в качестве аргумента функции) с помощью
inoutи принимая адрес,как newacct указал. Но тип сам по себе является типом значения.Какие Ссылочные Типы Означают Для Вас
объект ссылочного типа является особенным на практике, потому что:
простое назначение или передача функции может дайте несколько ссылок на один и тот же объект
сам объект является изменяемым, даже если ссылка на него является константой (
let, явный или подразумеваемый).мутация объекта влияет на этот объект, как видно из всех ссылок на него.
это может быть опасно,так что следите. С другой стороны, передача ссылочного типа явно эффективна, потому что копируется и передается только указатель, который является тривиальный.
Какие Типы Значений Означают Для Вас
очевидно, что передача типа значения "безопаснее" и
letозначает то, что он говорит: Вы не можете мутировать экземпляр struct или экземпляр enum черезletссылка. С другой стороны, эта безопасность достигается путем создания отдельной копии ценности, не так ли? Разве это не делает передачу типа значения потенциально дорогостоящей?и да, и нет. Это не так плохо, как вы думаете. Как сказал Нейт Кук, передавая значение типа не обязательно подразумевает копирование, потому что
let(явный или подразумеваемый) гарантирует неизменность, поэтому нет необходимости копировать что-либо. И даже переходя вvarссылка не означает, что вещи будет копируются, только что они можете при необходимости (потому что есть мутации). Врачи специально советуют вам не получить ваши трусики в поворот.
это всегдапередача значением если параметр не
inout.это всегдаpass-by-reference если параметр
inout. Однако, это несколько осложняется тем, что вам нужно явно использовать&оператор на аргументе при переходе кinoutпараметр, поэтому он может не соответствовать традиционному определению pass-by-reference, где вы передаете переменную напрямую.
все в Swift передается по умолчанию "copy", поэтому при передаче типа значения вы получаете копию значения, а при передаче ссылочного типа вы получаете копию ссылки со всеми вытекающими отсюда последствиями. (То есть копия ссылки по-прежнему указывает на тот же экземпляр, что и исходная ссылка.)
Я использую кавычки паники вокруг "копии" выше, потому что Swift делает много оптимизации; везде, где это возможно, он не копирует, пока нет мутации или возможности мутация. Поскольку параметры по умолчанию неизменяемы, это означает, что в большинстве случаев копирование не происходит.
The Apple Swift Developer в блоге есть сообщение под названием значения и ссылочные типы это обеспечивает четкое и подробное обсуждение этой самой темы.
цитата:
типы в Swift попадают в одну из двух категорий: во-первых, "типы значений ", где каждый экземпляр хранит уникальную копию своих данных, обычно определенных в качестве ключевого слова struct, enum, или кортеж. Второй, "ссылочные типы", где экземпляры совместно используют одну копию данные, и тип обычно определяется как класс.
сообщение в блоге Swift продолжает объяснять различия с примерами и предлагает, когда вы будете использовать один над другим.
вот небольшой пример кода для передачи по ссылке. Избегайте этого, если у вас нет веской причины.
func ComputeSomeValues(_ value1: inout String, _ value2: inout Int){ value1 = "my great computation 1"; value2 = 123456; }назовем это так
var val1: String = ""; var val2: Int = -1; ComputeSomeValues(&val1, &val2);