Подтвердить что ты не робот

Невозможно назначить "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
4b9b3361

Ответ 1

Ваше предположение верно.

Получив доступ к blockStatus, вы создаете его копию, в этом случае это постоянная копия (итераторы всегда постоянны).

Это похоже на следующее:

var numbers = [1, 2, 3]

for i in numbers {
   i = 10  //cannot assign here
}

Литература:

Контроль потока

В приведенном выше примере индекс является константой константой, значение которой автоматически устанавливается в начале каждой итерации цикла.

Классы и структуры

Тип значения - это тип, который копируется, когда ему присваивается переменная или константа или когда она передается функции. [...] Все структуры и перечисления являются типами значений в Swift

Methods

Структуры и перечисления представляют собой типы значений. По умолчанию свойства типа значения не могут быть изменены из его методов экземпляра.

Однако, если вам нужно изменить свойства вашей структуры или перечисления в определенном методе, вы можете выбрать способ изменения для этого метода. Затем этот метод может мутировать (то есть изменять) его свойства внутри метода, и любые изменения, которые он делает, записываются обратно в исходную структуру, когда метод заканчивается. Этот метод также может назначить полностью новый экземпляр его неявному свойству self, и этот новый экземпляр заменит существующий, когда метод завершится.

Вы можете выбрать это поведение, поставив ключевое слово mutating перед ключевым словом func для этого метода:

Ответ 2

Вы можете пропустить массив с индексом

for index in 0..<statuses.count {
    // Use your array - statuses[index]
}

который должен работать, не получив "невозможно назначить"

Ответ 3

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