Невозможно назначить 'X' в 'Y' в Swift
У меня есть словарь с Structs
в этом. Я пытаюсь присвоить значения struct
когда я перебираю dictionary
, Свифт говорит мне cannot assign to 'isRunning' in 'blockStatus'
, Я не смог найти ничего в документах об этой неизменности dictionaries
или же structs
,
Прямо с детской площадки:
import Cocoa
struct BlockStatus{
var isRunning = false
var timeGapForNextRun = UInt32(0)
var currentInterval = UInt32(0)
}
var statuses = ["block1":BlockStatus(),"block2":BlockStatus()]
for (block, blockStatus) in statuses{
blockStatus.isRunning = true
}
cannot assign to 'isRunning' in 'blockStatus'
blockStatus.isRunning = true
Это работает, если я изменю struct
к class
,
Я предполагаю, что это как-то связано с тем, что структуры копируются, а на классы всегда ссылаются?
РЕДАКТИРОВАТЬ: Таким образом, даже если он копирует это.. Почему я не могу изменить это? Это дало бы мне неверный результат, но вы можете изменить члены константы, но не сами константы. Например, вы можете сделать это:
class A {
var b = 5
}
let a = A()
a.b = 6
3 ответа
Ваше предположение верно.
Получив доступ blockStatus
Вы создаете его копию, в данном случае это постоянная копия (итераторы всегда постоянны).
Это похоже на следующее:
var numbers = [1, 2, 3]
for i in numbers {
i = 10 //cannot assign here
}
Рекомендации:
В приведенном выше примере индекс - это константа, значение которой автоматически устанавливается в начале каждой итерации цикла.
Тип значения - это тип, который копируется, когда он присваивается переменной или константе или когда он передается в функцию. [...] Все структуры и перечисления являются типами значений в Swift
Структуры и перечисления являются типами значений. По умолчанию свойства типа значения не могут быть изменены из его методов экземпляра.
Однако, если вам нужно изменить свойства вашей структуры или перечисления в конкретном методе, вы можете выбрать мутацию поведения для этого метода. Затем метод может видоизменять (то есть изменять) свои свойства изнутри метода, и любые изменения, которые он вносит, записываются обратно в исходную структуру после завершения метода. Метод также может назначить совершенно новый экземпляр своему неявному свойству self, и этот новый экземпляр заменит существующий, когда метод завершится.
Вы можете включить это поведение, поместив ключевое слово mutating перед ключевым словом func для этого метода:
Вы можете перебрать массив с индексом
for index in 0..<statuses.count {
// Use your array - statuses[index]
}
это должно работать без получения "не могу назначить"
Если "Y" в этом случае является протоколом, подкласс вашего протокола class
, У меня был протокол:
protocol PlayerMediatorElementProtocol {
var playerMediator:PlayerMediator { get }
}
и попытался установить playerMediator
из моего посредника игрока:
element.playerMediator = self
Который превратился в ошибку cannot asign 'playerMediator' in 'element'
Изменение моего протокола для наследования от класса исправило эту проблему:
protocol PlayerMediatorElementProtocol : class {
var playerMediator:PlayerMediator { get }
}
Почему это должно наследовать от класса?
Причина, по которой это должно наследоваться от class
потому что компилятор не знает, какой тип вашего протокола унаследован. Структуры также могут наследовать этот протокол, и вы не можете присвоить свойству постоянной структуры.