Является точной передачи по значению или пройти по ссылке


Я действительно Новичок в Swift и я просто читал, что классы передаются по ссылке и массивы/строки и т. д. копируются.

является ли передача по ссылке таким же образом, как и в Objective-C или Java, где вы фактически передаете ссылку "a" или это правильный переход по ссылке?

6 72

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);

классы передаются по ссылкам, а другие передаются по значению по умолчанию. Вы можете передать по ссылке с помощью inout ключевое слово.