Невозможно назначить '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 потому что компилятор не знает, какой тип вашего протокола унаследован. Структуры также могут наследовать этот протокол, и вы не можете присвоить свойству постоянной структуры.

Другие вопросы по тегам