Я хочу передать свой Swift Array
account.chats
в качестве chatsViewController.chats
ссылки (так что , когда я добавить чат в account.chats
, по- chatsViewController.chats
прежнему указывает на account.chats
). Т.е. я не хочу, чтобы Swift разделял два массива при изменении длины account.chats
.
arrays
swift
pass-by-reference
ma11hew28
источник
источник
account
глобальную переменную и определенияchats
свойства ,ChatsViewController
как:var chats: [Chat] { return account.chats }
.Ответы:
Структуры в Swift передаются по значению, но вы можете использовать
inout
модификатор для изменения вашего массива (см. Ответы ниже). Классы передаются по ссылке.Array
аDictionary
в Swift реализованы как структуры.источник
NSArray
becauseNSArray
и Swift имеют тонкие семантические различия (например, ссылочный тип), что может привести к большему количеству ошибок.inout
со структурами?Для оператора параметра функции мы используем:
let (оператор по умолчанию, поэтому мы можем опустить let ), чтобы сделать параметр постоянным (это означает, что мы не можем изменить даже локальную копию);
var, чтобы сделать его переменной (мы можем изменить его локально, но это не повлияет на внешнюю переменную, переданную в функцию); и
inout, чтобы сделать его параметром входа -выхода. Фактически, ввод-вывод означает передачу переменной по ссылке, а не по значению. И для этого требуется не только принимать значение по ссылке, но и передавать его по ссылке, поэтому передайте его с помощью & -
foo(&myVar)
вместо простогоfoo(myVar)
Так сделайте это так:
Если быть точным, это не просто ссылка, а настоящий псевдоним для внешней переменной, поэтому вы можете проделать такой трюк с любым типом переменной, например с целым числом (вы можете присвоить ей новое значение), хотя это может не быть хорошая практика, и изменение таких примитивных типов данных может сбить с толку.
источник
inout
положение изменилось, то естьfunc addItem(localArr: inout [Int])
var
больше не доступен атрибут параметра функции.Определите себя,
BoxedArray<T>
который реализуетArray
интерфейс, но делегирует все функции сохраненному свойству. В качестве такихИспользуйте
BoxedArray
везде, где вы бы использовалиArray
. НазначениеBoxedArray
будет по ссылке, это класс, и, таким образом, изменения сохраненного свойства черезArray
интерфейс будут видны всем ссылкам.источник
String
есть подтипAny
НО, если выimport Foundation
затемString
становитесь подтипомAnyObject
.Для Swift версий 3-4 (XCode 8-9) используйте
источник
Что-то вроде
???
источник
func test(b: inout [Int])
... может быть, это старый синтаксис; Я попал в Swift только в 2016 году, а этот ответ - из 2014, так что, может быть, раньше все было иначе?Еще один вариант - попросить потребителя массива при необходимости запросить его у владельца. Например, что-то вроде:
Затем вы можете изменять массив сколько угодно внутри класса Account. Обратите внимание, что это не поможет вам, если вы хотите также изменить массив из класса контроллера представления.
источник
Использование
inout
- это одно из решений, но мне оно не кажется очень быстрым, поскольку массивы являются типами значений. Стилистически я предпочитаю вернуть мутированную копию:источник
inout
это универсально лучше, потому что это экономит батарею. На что я бы сказал, что читабельность, неизменяемость и безопасность потоков этого решения повсеместно лучше, и что inout следует использовать только в качестве оптимизации в тех редких случаях, когда этого требует вариант использования.используйте a
NSMutableArray
или aNSArray
, которые являются классамитаким образом вам не нужно внедрять какую-либо оболочку и можно использовать сборку в мосте
источник