#swift #swiftui #uikit
#swift #swiftui #uikit
Вопрос:
В следующем примере вы можете видеть, что словарь в экземпляре MyStruct не возвращается по ссылке в функции getDictionary(). Следовательно, любые изменения, внесенные в возвращаемый словарь, вносятся только в копию. Как вы можете вернуть словарь по ссылке?
struct myStruct {
func getDictionary() -> [Int:String] {
return dictionary
}
private var dictionary = [1:"one"]
}
let c = myStruct()
var sameDict = c.getDictionary()
sameDict[2] = "two"
print(c.getDictionary(), sameDict)
[1: «один»] [1: «один», 2: «два»]
Комментарии:
1. Вы можете сделать
c.dictionary = ...
илиc.dictionary[2] = "two"
2. @pawello2222 конечно, но это не то, что я спрашивал
3. В соответствии с соглашением об именовании Swift ваши протоколы, структуры и классы называются с заглавной буквы.
4. Откуда вы знаете? И почему вы думаете
inout
, что это более «эффективно»? Даже сinout
вы назначаете совершенно новый словарь каждый раз, когда вызываете этот метод.5. Ну да, но Swift — это не C. Он не ведет себя как C, и ваш код не взаимодействует с C. Можно представить себе определенный вид «эффективности», но не касаясь реальности того, как работает Swift, независимо от того, используем ли мы
inout
или устанавливаем значение в словаре.
Ответ №1:
Словарь — это тип значения, это не ваш выбор, делать какой-либо тип структуры данных ссылкой или значением, это выбор Swift. В качестве ссылки могут использоваться только замыкание, класс и функции
В Swift массив, строка и словарьhttps://developer.apple.com/swift/blog/?id=10
Комментарии:
1. Значит, это тупик?
2. ДА. Они не могут быть использованы в качестве ссылки. Но на самом деле у вас есть абстрактная задача, которая вызывает like — я хочу сделать это как ссылку. В реальном приложении вам не нужно делать это со словарями
3.
struct
Типы @Rage могут передаваться по ссылке с помощьюinout
ключевого слова. Взгляните на мой ответ.4. Его можно изменить как inout, но это не то же самое, что ссылка
5. Когда вы используете inout, то в начале функции у вас есть КОПИЯ глобальной переменной, после модификации этой копии внутри функции, перед возвратом, измененная копия БУДЕТ присвоена глобальной переменной. Это не изменение ссылки на переменную — это ПОЛНОЕ присвоение. (Надеюсь, вы поняли, что я пытаюсь сказать, извините за плохой английский)
Ответ №2:
Поскольку Dictionary
это struct
тип, единственный способ сделать это — передать его в функцию с помощью inout
ключевого слова (указывает, что параметр будет изменен) следующим образом:
struct MyStruct {
func getDictionary() -> [Int: String] {
return dictionary
}
mutating func updateDictionary(block: (inout [Int: String]) -> Void) {
block(amp;dictionary)
}
private var dictionary = [1:"one"]
}
var c = MyStruct()
c.updateDictionary {
$0[2] = "two"
}
print(c.getDictionary())
Обновление: После модификации копии внутри функции, перед возвратом, измененная копия БУДЕТ присвоена глобальной переменной. @AlexanderNikolaychuk и @matt указали на это в комментариях. Поведение можно увидеть, если запустить следующий код на игровой площадке:
struct MyStruct {
var some = 1
}
var myStruct = MyStruct() {
didSet {
print("didSet")
}
}
func pass(something: inout MyStruct) {
something.some = 2
print("After change")
}
pass(something: amp;myStruct)
это выведет:
After change
didSet
Просто говорю.
Комментарии:
1. В соответствии с соглашением об именовании Swift ваши протоколы, структуры и классы называются с заглавной буквы.
2. @LeoDabus вы абсолютно правы. Просто скопировал код из вопроса :). Обновление сейчас.
3. Как я уже сказал, это не ссылка в значении Swift, это присвоение новой измененной переменной старой глобальной )
4. @AlexanderNikolaychuk спасибо за знания. Я только что обновил свой ответ.
Ответ №3:
Похоже, вы не совсем поняли разницу между struct
и class
.
Когда вы инициализируете struct
и назначаете его c
, у вас есть его первая копия. Затем вы инициализируете новую переменную, вызывая ее sameDict
и копируя в нее значение c
dictionary
. Затем вы изменяете вызываемую копию. sameDict
Словарь c
все тот же.
Проверьте этот документ:https://docs.swift.org/swift-book/LanguageGuide/ClassesAndStructures.html
Stuct's
передаются путем их копирования. classes
получить ссылку.
Комментарии:
1. Я это полностью понимаю, я пытаюсь использовать функцию getDictionary для возврата словаря структуры по ссылке.
2. @Rage вам нужен NSDictionary (класс)