структура против класса на языке swift
из книги Apple
"Одно из важнейших различий между структурами и классами заключается в том, что структуры всегда копируются, когда они передаются в коде, но классы передаются по ссылке."
может ли кто-нибудь дать мне понять, что это значит, для меня класс и структура, похоже, одинаковы.
12 ответов:
вот пример
class. Обратите внимание, как при изменении имени обновляется экземпляр, на который ссылаются обе переменные.BobТеперьSue, повсюдуBobникогда не ссылаются.class SomeClass { var name: String init(name: String) { self.name = name } } var aClass = SomeClass(name: "Bob") var bClass = aClass // aClass and bClass now reference the same instance! bClass.name = "Sue" println(aClass.name) // "Sue" println(bClass.name) // "Sue"С
structмы видим, что значения копируются и каждая переменная сохраняет свой собственный набор ценностей. Когда мы устанавливаем имя вSueнаBobstruct inaStructне изменяется.struct SomeStruct { var name: String init(name: String) { self.name = name } } var aStruct = SomeStruct(name: "Bob") var bStruct = aStruct // aStruct and bStruct are two structs with the same value! bStruct.name = "Sue" println(aStruct.name) // "Bob" println(bStruct.name) // "Sue"Итак, для представления комплекса с состоянием сущность,
classэто круто. Но для значений, которые являются просто измерением или битами связанных данных, astructбольше смысла, так что вы можете легко скопировать их и работать с ними или изменить значения, не опасаясь побочных эффектов.
как класс, так и структура могут делать:
- определить свойства для хранения ценностей
- определить методы для обеспечения функциональности
- быть продлен
- соответствуют протоколам
- определить intialisers
- определите индексы, чтобы обеспечить доступ к их переменным
только класс может сделать:
- наследование
- тип литья
- определить deinitialisers
- разрешить подсчет ссылок для нескольких ссылок.
structтипы значений. Это означает, что если вы копируете экземпляр структуры в другую переменную, он просто копируется в переменную.пример для типа
struct Resolution { var width = 2 var height = 3 } let hd = Resolution(width: 1920, height: 1080) var cinema = hd //assigning struct instance to variable println("Width of cinema instance is \(cinema.width)")//result is 1920 println("Width of hd instance is \(hd.width)")//result is 1920 cinema.width = 2048 println("Width of cinema instance is \(cinema.width)")//result is 2048 println("Width of hd instance is \(hd.width)")//result is 1920классы являются ссылочными типами. Это означает, что если вы назначите экземпляр класса переменной, он будет содержать только ссылка к примеру и не скопировать.
основные различия между структурами и классами:
- структуры не могут наследовать от других видов.
- классы используют приведение типов для обработки класса как суперкласса или подкласса, а также проверки принятия протокола. Структуры могут использовать только часть принятия протокола.
- структуры не имеют деинициализаторов.
- структуры не могут иметь несколько ссылок на один и тот же экземпляр
Если вы посмотрите дальше в руководстве apple, вы увидите этот раздел: "Структуры и перечисления являются типами значений"
в этом разделе вы увидите это:
" пусть hd = разрешение (ширина: 1920, высота: 1080) var cinema = hd в этом примере объявляется константа с именем hd и устанавливается она к примеру разрешение инициализации с ширины и высоты полных HD видео (1920 пикселей в ширину и 1080 пикселей в высоту).
Это затем объявляет переменную с именем cinema и устанавливает ее в текущее значение стоимость HD-качестве. Поскольку разрешение-это структура, копия существующей экземпляр сделан,и эта новая копия назначена кино. Даже если hd и кино теперь имеют такую же ширину и высоту, они 2 совершенно разные экземпляры за кулисами.
затем, свойство ширины кино изменено для того чтобы быть шириной слегка более широкий стандарт 2K, используемый для цифровой кинопроекции (2048 пикселы ширину и 1080 пикселей в высоту):
кино.ширина = 2048 проверка ширины собственность киносеансы что он действительно изменился, чтобы быть 2048:
println ("кино сейчас (кино.ширина) пикселей в ширину") // печатает " кино теперь 2048 пикселов широко однако, свойство ширины исходный экземпляр hd по-прежнему имеет старое значение 1920:
println ("hd все еще (hd.ширина) пиксели широко") / / печатает " hd еще 1920 пикселей широкий"
когда кино было дано текущее значение hd, значения, сохраненные в hd были скопированы в новый экземпляр кино. Конечный результат-два совершенно разные экземпляры, которые просто случайно содержат одно и то же числовое значение. Поскольку они являются отдельными экземплярами, установка ширины кино до 2048 не влияет на ширину, сохраненную в hd."
Отрывок Из: Apple Inc. "Язык Программирования Swift."iBooks. https://itun.es/us/jEUH0.l
Это самая большая разница между структурами и классами. Структуры копируются, и на них ссылаются классы.
выше ответы правильные я надеюсь, что мой ответ поможет кому-то, кто не понимает выше ответов.
Ну в Swift есть два типа объектов
- Struct
- класс
основное различие между ними
- структура стоимостью тип
- класс ссылка тип
например здесь код для понимания что ж.
struct SomeStruct { var a : Int; init(_ a : Int) { self.a = a } } class SomeClass { var a: Int; init(_ a: Int) { self.a = a } } var x = 11 var someStruct1 = SomeStruct(x) var someClass1 = SomeClass(x) var someStruct2 = someStruct1 var someClass2 = someClass1 someClass1.a = 12 someClass2.a // answer is 12 because it is referencing to class 1 property a someStruct1.a = 14 someStruct2.a // answer is 11 because it is just copying it not referencing itЭто было основное различие, но у нас есть и суб различия.
класс
- должен объявить инициализатор (конструктор)
- имеет deinitialisers
- могут наследовать от других классов
Struct
- у него есть бесплатный инициализатор для вас , вам не нужно объявлять initaliser, если вы делаете бесплатный инициализатор будет перезаписан вашим объявленным для инициализации тестов
- нет deinitialiser
- не может наследовать от другой структуры
этот вопрос, похоже, дублируется, но независимо от этого, следующее ответит на большую часть варианта использования:
одним из самых важных различий между структурами и классами является то, что структуры являются типами значений и всегда копируются, когда они передаются в вашем коде, а классы являются ссылочным типом и передаются по ссылке.
кроме того, классы наследование позволяет одному классу наследовать характеристики о другом.
свойства структуры хранятся в стеке, а экземпляры классов хранятся на куче следовательно, иногда стек значительно быстрее, чем класс.
Struct автоматически получает инициализатор по умолчанию, тогда как в классе мы нужно инициализировать.
структура является потокобезопасной или одноэлементной в любой момент времени.
, а также, Чтобы суммировать разницу между структурами и классы, необходимо понимать разницу между значениями и ссылочными типами.
- когда вы делаете экземпляр типа значения, он копирует все данные из что вы копируете в новую переменную. Они являются 2 отдельными вещи и изменение одного не влияет на другой.
- при создании копии ссылочного типа новая переменная ссылается на то же место в памяти, что и то, что вы копируете. Это средство это изменение одного изменит другое, так как они оба относятся к то же самое место в памяти. Пример кода ниже может быть взят в качестве ссылки.
// sampleplayground.детская площадка
class MyClass { var myName: String init(myName: String){ self.myName = myName; } } var myClassExistingName = MyClass(myName: "DILIP") var myClassNewName = myClassExistingName myClassNewName.myName = "John" print("Current Name: ",myClassExistingName.myName) print("Modified Name", myClassNewName.myName) print("*************************") struct myStruct { var programmeType: String init(programmeType: String){ self.programmeType = programmeType } } var myStructExistingValue = myStruct(programmeType: "Animation") var myStructNewValue = myStructExistingValue myStructNewValue.programmeType = "Thriller" print("myStructExistingValue: ", myStructExistingValue.programmeType) print("myStructNewValue: ", myStructNewValue.programmeType)выход:
Current Name: John Modified Name John ************************* myStructExistingValue: Animation myStructNewValue: Thriller
name используется для доступа к этим блокам данных. Этот механизм позволяет совместно использовать объекты в куче путем копирования значения их ссылок (указателей). Это не относится к базовым типам данных, таким как целые числа, и это связано с тем, что память, необходимая для создания ссылки, почти такая же, как и объект (в этом случае целочисленное значение.) Таким образом, они будут передаваться как значения, а не как ссылка в случае больших объектов.
Swift использует struct для повышения производительности даже со строковыми и массивными объектами.
чтобы понять разницу между структурами и классами, нам нужно знать основное различие между значениями и ссылочными типами. Структуры-это типы значений, и это означает, что каждое изменение в них просто изменит это значение, классы-ссылочные типы, и каждое изменение в ссылочном типе изменит значение, выделенное в этом месте памяти или ссылки. Например:
давайте начнем С класса, этот класс соответствует Equatable только для того, чтобы иметь возможность сравнивать экземпляры, мы создаем экземпляр с именем
pointClassInstanceAи другие называютpointClassInstanceBмы присваиваем класс A классу B, теперь утверждение говорит, что они одинаковы...class PointClass: Equatable { var x: Double var y: Double init(x: Double, y: Double) { self.x = x self.y = y } static func == (lhs: PointClass, rhs: PointClass) -> Bool { return lhs.x == rhs.x && lhs.y == rhs.y } } var pointClassInstanceA = PointClass(x: 0, y: 0) var pointClassInstanceB = pointClassInstanceA assert(pointClassInstanceA==pointClassInstanceB) pointClassInstanceB.x = 10 print(pointClassInstanceA.x) //this prints 10хорошо, что здесь произошло почему, если мы просто изменили значение x pointsClassInstanceB он также изменил значение x pointClassInstanceA? ну, это показывает, как работают ссылочные типы, когда мы назначаем экземпляр A, как значение экземпляра B, а затем мы изменяем X одного из них, он изменит оба X, потому что они разделяют та же ссылка и то, что изменилось, было значением этой ссылки.
давайте сделаем то же самое, но с структуры
struct PointStruct: Equatable { var x: Double var y: Double init(x: Double, y: Double) { self.x = x self.y = y } static func == (lhs: PointStruct, rhs: PointStruct) -> Bool { return lhs.x == rhs.x && lhs.y == rhs.y } } var pointStructInstanceA = PointStruct(x: 0, y: 0) var pointStructInstanceB = pointStructInstanceA assert(pointStructInstanceA==pointStructInstanceB) pointStructInstanceB.x = 100 print(pointStructInstanceA.x) //this will print 0мы имеем в основном ту же структуру, что и наш класс, но теперь вы можете видеть, что при печати значения x pointStructInstanceA в этом случае оно не изменилось, и это связано с тем, что типы значений работают по-разному, и каждое изменение в одном из их экземпляров будет "независимым" и не повлияет на другое.
Swift предлагает использовать больше значения типы и вы можете сказать, что их библиотеки основаны на структурах, чтобы избежать проблем, которые приносят ссылочные типы, например, непреднамеренно изменить значение и т. д. Структуры-это способ идти на Swift. Надеюсь, это поможет.
вот пример, который точно показывает разницу между struct и class.
скриншот написанного кода на игровой площадке
struct Radio1{ var name:String // init(name:String) { // self.name = name // } } struct Car1{ var radio:Radio1? var model:String } var i1 = Car1(radio: Radio1(name:"murphy"),model:"sedan") var i2 = i1 //since car instance i1 is a struct and //this car has every member as struct , //all values are copied into i2 i2.radio?.name //murphy i2.radio = Radio1(name: "alpha") i2.radio?.name //alpha i1.radio?.name //murphy //since Radio1 was struct , //values were copied and thus // changing name of instance of Radio1 in i2 //did not bring change in i1 class Radio2{ var name:String init(name:String) { self.name = name } } struct Car2{ var radio:Radio2? var model:String } var i3 = Car2(radio: Radio2(name:"murphy"),model:"sedan") //var radioInstance = Radio2(name: "murphy") //var i3 = Car2(radio: radioInstance,model:"sedan") var i4 = i3 //since i3 is instance of struct //everything is copied to i4 including reference of instance of Radio2 //because Radio2 is a class i4.radio?.name //murphy i4.radio?.name="alpha" i4.radio?.name //alpha i3.radio?.name //alpha //since Radio2 was class, //reference was copied and //thus changing name of instance //of Radio2 in i4 did bring change in i3 too //i4.radio?.name //i4.radio = Radio2(name: "alpha") //i4.radio?.name // //i3.radio?.name
уже сегодня об этом много написано, Хотелось бы добавить аналогию. Надеюсь, вы никогда не будете иметь сомнения в виду после этого: Практический результат: классы передаются по ссылке, тогда как структуры передаются по значению.
Предположим, Вы делитесь листом Google doc с вашим другом. Теперь, если он что-то изменит в этом, вы также увидите, что изменения в вашем документе google, означает, что ваша копия также затронута. Это в основном "принят ссылка".
но предположим, если у вас есть .Файл XLS тьфу, сохраненные в вашем компьютере. Вы предоставляете этот файл своему другу. Теперь, если он вносит какие-либо изменения в этот файл, ваш файл не будет перепутан/выполнен, потому что у вас есть своя копия. Это в основном "передан по значению". У вас уже есть несколько простых программ, чтобы проверить эту аналогию в swift playgrounds.
1.structure is value type. = > when we assign structure variable to other variable or pass as parameter to function, it creates separate/new copy => so that changes made on one variable does not reflect on another.[We can say like **call by value** concept] Example : struct DemoStruct { var value: String init(inValue: String) { self.value = inValue } } var aStruct = DemoStruct(inValue: "original") var bStruct = aStruct // aStruct and bStruct are two structs with the same value! but references to diff location`enter code here` bStruct.value = "modified" print(aStruct.value) // "original" print(bStruct.value) // "modified" 2.class is reference type. = > when we assign structure variable to other variable or pass as parameter to function, it **does not** creates separate/new copy => so that changes made on one variable does not reflect on another.[We can say like **call by reference** concept] Example: class DemoClass { var value: String init(inValue: String) { self.value = inValue } } var aClass = DemoClass(inName: "original") var bClass = aClass // aClass and bClass now reference the same instance! bClass.value = "modified" print(aClass.value) // "modified" print(bClass.value) // "modified"

Comments