кто может объяснить изменение ключевого слова SWIFT? смущенный - PullRequest
0 голосов
/ 02 июля 2018

почему я должен поместить "мутирование" перед реализацией метода в структуре при принятии протоколов, тогда как мне не нужно, когда я делаю то же самое в классе.

Ответы [ 3 ]

0 голосов
/ 02 июля 2018

Классы являются ссылочными типами. Это означает, что переменная, типизированная для класса:

let someObject = SomeClass()

просто содержит указатель на память этого класса, под капотом. Содержимое и данные класса могут изменяться без изменения исходного указателя, потому что это просто ссылка.

Структуры, с другой стороны, являются типами значений. Если у вас есть переменная, содержащая что-то, имеющее тип struct:

var someStruct = SomeStruct()

сама переменная фактически содержит все данные структуры. Изменение внутреннего состояния структуры на самом деле включает в себя переназначение переменной - так что в приведенном выше примере что-то вроде someStruct.foo = "bar" фактически приведет к переназначению переменной someStruct, как если бы вы набрали:

someStruct = SomeStruct(foo: "bar", otherStuff: someStruct.otherStuff) // or something of this nature

Именно поэтому вы должны объявлять структуры, используя var, если вы планируете что-то в них изменить, тогда как с классами это не так.

Что касается протоколов, они могут представлять типы struct или class, поэтому, если вы имеете дело с экзистенциальным протоколом, вы не можете выполнять над ним операции, предполагающие, что это класс (если только протокол не ограничен как таковой).

0 голосов
/ 02 июля 2018

Будучи значениями, структуры типа являются неизменяемыми. Значение других переменных не может изменить значения экземпляра структуры в любой заданной точке.

Мутантное слово требуется для ТОЛЬКО изменения значений собственных переменных внутри функции структуры.

Для получения. например,

struct MyStruct {
    var abc: String = "initila value"

    func changeValue() {
        abc = "some other value". //Compile time error: Cannot assign to property: 'self' is immutable. Mark method 'mutating' to make 'self' mutable.
    }
}

Здесь, когда мы пытаемся изменить значение переменной abc внутри функции, объявленной в самой struct, мы получаем ошибку времени компиляции.

Итак, здесь нам нужно изменить функцию, чтобы изменить ее значение внутри структуры. Следовательно, правильный код будет:

struct MyStruct {
    var abc: String = "initila value"

    mutating func changeValue() {
        abc = "some other value"
   }
}

EDIT:

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

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

Из документов:

Если вы определяете требование метода экземпляра протокола, предназначенное для изменения экземпляров любого типа, который принимает протокол, пометьте метод с помощью ключевого слова mutating как часть определения протокола. Это позволяет структурам и перечислениям принимать протокол и удовлетворять этому требованию метода.

Если вы помечаете требование метода экземпляра протокола как изменяющееся, вам не нужно писать ключевое слово с мутацией при написании реализации этого метода для класса. Ключевое слово mutating используется только структурами и перечислениями.

Ссылка

Надеюсь, это очистит ваше сомнение.

0 голосов
/ 02 июля 2018

Мутирующее ключевое слово требуется только в том случае, если вы изменяете любое состояние, содержащееся в структуре. Поскольку структуры Swift являются неизменяемыми объектами, вызов мутантной функции фактически возвращает новую структуру на месте (очень похоже на передачу параметра inout в функцию). Ключевое слово mutating позволяет вызывающим абонентам знать, что метод собирается изменить значение. Лучший способ осмыслить это - думать о своей структуре так же, как о числе; если вы выполняете операцию 4 + 1, 4 не становится 5, вы только что получили новое значение после выполнения операции. Мутирующие функции работают по тому же принципу. Если вы сделаете тип значения константой (например, let someStruct = SomeStruct ()), вы не сможете вызывать мутирующие функции для него: они могут вызываться только для переменной.

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