Экземпляр обязательно обрабатывается как тип значения в расширениях протоколов, не связанных с классом - PullRequest
0 голосов
/ 20 сентября 2018

Вот код:

protocol A {
  var a: Int { get set }
}

extension A {
  var convenientAccessor: Int {
    get { return a }
    set { a = newValue }
  }
}

class B: A {
  var a: Int = 0
}

func acceptsB (instance: B) {
  instance.a = 1                     // This compiles
  instance.convenientAccessor = 2    // This does not
}

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

1 Ответ

0 голосов
/ 20 сентября 2018

Давайте начнем со сводки: convenientAccessor является записываемым свойством, поэтому любое присвоение ему приведет к мутации.И эта мутация происходит внутри вашей функции.

Дело в том, что при использовании свойства convenientAccessor компилятор обрабатывает instance как протокол A, а аргументы функции являются let, он не допускает мутаций на них, так как в этот момент протокол может быть реализован также с помощью значения типа.

Два решения, которые мне приходят в голову:

  1. ограничить протокол A только классами:

    protocol A: class 
    

    Это информирует компилятор о том, что только классы могут соответствовать протоколу, что допускает мутацию переменных любого типа (let или var)

  2. сделать параметр функции inout:

    func acceptsB (instance: inout B)
    

    Это создает «дыру для записи», так как теперь instance доступна для записи, поэтому любые изменения в нейраспространяются обратно вверх по течению, даже если B является типом значения.

Лично я бы пошел с # 1, если вы планируете использовать только классы, как вы упомянули в вопросе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...