Структура против класса в быстром языке
Из книги Apple
"Одно из самых важных различий между структурами и классами состоит в том, что структуры всегда копируются, когда они передаются в вашем коде, но классы передаются по ссылке".
Может ли кто-нибудь дать мне понять, что это значит, для меня класс и структура кажутся одинаковыми.
Ответы
Ответ 1
Вот пример с 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
, структура Bob
в aStruct
не изменяется.
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"
Итак, для представления сложной сущности, a class
является удивительным. Но для значений, которые являются просто измерением или битами связанных данных, a struct
имеет больше смысла, так что вы можете легко скопировать их и вычислить с ними или изменить значения, не опасаясь побочных эффектов.
Ответ 2
Оба класса и структуры могут выполнять:
- Определить свойства для хранения значений
- Определить методы для обеспечения функциональности
- Расширить
- Соответствует протоколам
- Определить intialisers
- Определить индексы для предоставления доступа к их переменным
Только класс может выполнять:
- Наследование
- Тип литья
- Определение деинициализаторов
- Разрешить подсчет ссылок для нескольких ссылок.
Ответ 3
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
Классы являются ссылочными типами. Это означает, что если вы присвойте экземпляр класса переменной, он будет содержать только ссылку для экземпляра и , а не копию.
Ответ 4
Основные различия между структурами и классами:
- Структуры не могут наследовать от других типов.
- Классы используют тип-литье для обработки класса в качестве суперкласса или подкласса, а также для принятия протокола проверки. Структуры могут использовать только часть принятия протокола.
- Структуры не имеют деинициализаторов.
- Структуры не могут иметь несколько ссылок на один и тот же экземпляр
Ответ 5
Выше правильные ответы Я надеюсь, что мой ответ поможет кому-то, кто не понимает выше ответов.
Хорошо в Swift Есть два типа объектов
Основное различие между ними -
- Тип структуры значение
- Класс ссылочный тип
Например, здесь код хорошо понимает.
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
- Невозможно наследовать от другой структуры
Ответ 6
Этот вопрос кажется дублирующим, но, тем не менее, следующее ответит на большинство случаев использования:
-
Одним из наиболее важных различий между структурами и классами является то, что структуры являются типами значений и всегда копируются, когда они передаются в вашем коде, а классы являются ссылочным типом и передаются по ссылке.
-
Кроме того, у классов есть Наследование, которое позволяет одному классу наследовать характеристики другого.
-
Свойства структуры хранятся в стеке, а экземпляры классов хранятся в куче, следовательно, иногда стек значительно быстрее, чем класс.
-
Struct автоматически получает инициализатор по умолчанию, тогда как в Class мы должны инициализировать.
-
Struct является потокобезопасным или одноэлементным в любой момент времени.
А также, чтобы подвести итог разницы между структурами и классами, необходимо понимать разницу между типом value и ссылочным типом.
- Когда вы создаете копию типа значения, она копирует все данные из объекта, который вы копируете, в новую переменную. Это две разные вещи, и изменение одного не влияет на другое.
- Когда вы создаете копию ссылочного типа, новая переменная ссылается на ту же область памяти, что и копируемая вещь. Это означает, что изменение одного изменит другое, поскольку они оба ссылаются на одну и ту же область памяти. Пример кода ниже может быть взят в качестве ссылки.
//sampleplayground.playground
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
Ответ 7
Если вы посмотрите дальше в справочнике Apple, вы увидите этот раздел:
"Структуры и перечисления являются типами значений"
В этом разделе вы увидите следующее:
"let hd = Разрешение (ширина: 1920, высота: 1080) var Cinema = hd Этот пример объявляет константу hd и устанавливает ее к экземпляру разрешения, инициализированному шириной и высотой полного HD-видео (1920 пикселей в ширину и 1080 пикселей).
Затем он объявляет переменную, называемую кино, и устанавливает ее на текущий значение hd. Поскольку Резолюция представляет собой структуру, копию существующей экземпляр, и эта новая копия назначается кинотеатру. Хотя hd и кино теперь имеют одинаковую ширину и высоту, они два совершенно разные экземпляры за кулисами.
Далее, свойство ширины кинематографа изменяется как ширина чуть более широкий стандарт 2K, используемый для проекции цифрового кино (2048 пикселей в ширину и 1080 пикселей):
кинотеатр. width = 2048 Проверка свойства ширины кинозалов что он действительно изменился на 2048:
println (" сейчас кинотеатр (ширина кинематографа) ")// prints" теперь имеет ширину 2048 пикселей. Однако свойство ширины исходный экземпляр hd по-прежнему имеет старое значение 1920:
println ( "hd по-прежнему (ширина hd.) пикселей в ширину" )//печатает "hd все еще 1920 пикселей в ширину"
Когда в кинотеатре было задано текущее значение hd, значения, сохраненные в hd были скопированы в новый экземпляр кинотеатра. Конечным результатом является два полностью отдельные экземпляры, которые, как оказалось, содержали одно и то же числовые значения. Поскольку они являются отдельными экземплярами, задавая ширину от кинематографа до 2048 не влияет на ширину, сохраненную в hd. "
Отрывок из: Apple Inc." Быстрый язык программирования ". интерактивные книги. https://itun.es/us/jEUH0.l
Это самая большая разница между структурами и классами. Структуры копируются, и классы ссылаются.
Ответ 8
Обычно (в большинстве языков программирования) объекты представляют собой блоки данных, которые хранятся в куче, а затем ссылка (обычно указатель) на эти блоки, содержащая name
, используется для доступа к этим блокам данных. Этот механизм позволяет обмениваться объектами в куче, копируя значение их ссылок (указателей). Это не относится к базовым типам данных, таким как целые, и это связано с тем, что память, необходимая для создания ссылки, почти такая же, как и объект (в этом случае целочисленное значение). Таким образом, они будут переданы как значения не как ссылка в случае больших объектов.
Swift использует структуру для повышения производительности даже с объектами String и Array.
Очень хорошее чтение здесь
Ответ 9
Вот пример, который показывает разницу между структурой и классом.
снимок экрана с письменного кода на игровой площадке
![снимок экрана с письменного кода на игровой площадке]()
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
Ответ 10
Чтобы понять разницу между структурами и классами, нам нужно знать основное различие между значениями и ссылочными типами. Структуры представляют собой типы значений, а это означает, что каждое изменение на них просто изменит это значение, классы - это ссылочные типы, и каждое изменение ссылочного типа изменит значение, выделенное в этом месте памяти или ссылки. Например:
Давайте начнем с класса, этот класс будет соответствовать 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 pointClassInstanceB, оно также изменило значение 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.
Надеюсь, что это поможет.
Ответ 11
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"
Ответ 12
![]()
Value Type
: при копировании типа значения (т.е. когда он назначается, инициализируется или передается в функцию), каждый экземпляр сохраняет уникальную копию данных. Если вы измените один экземпляр, другой тоже не изменится. Храниться в памяти стека.
![enter image description here]()
Reference Type
: при копировании ссылочного типа каждый экземпляр передает данные. Сама ссылка копируется, но не данные, на которые она ссылается. Когда вы меняете один, другой тоже меняется. Храниться в управляемой памяти кучи.
![enter image description here]()
Когда следует использовать структуры?
Рекомендуется использовать struct по умолчанию.
Используйте структуры для простых типов данных. Подумайте об объектах базы данных, которые вы хотите передать в своем коде, таких как NewsItem, Task или User. Поскольку они так четко определены и зачастую не требуют согласования сложных отношений между объектами, проще использовать структуры.
В многопоточной среде, например, с подключением к базе данных, которое открыто в другом потоке, структуры более безопасны. Они могут быть скопированы из одного потока в другой поток без риска возникновения состояния гонки или тупика. Классы не имеют этой присущей безопасности, если только они не сделаны преднамеренно поточно-ориентированными.
Когда свойства структуры в основном тоже являются типами значений, например String, имеет смысл заключить их в структуру вместо класса.
Когда вы должны использовать классы?
Рекомендуется использовать класс, если вам нужны его особенности.
- Классы могут наследовать от другого класса, что нельзя сделать со структурами.
- Классы могут быть деинициализированы.
- Классы идут со встроенным понятием идентичности, потому что они являются ссылочными типами. С помощью оператора идентификации
===
вы можете проверить наличие двух ссылок (ссылаются на один и тот же объект).
- Если вам нужна совместимость
Objective-C
, вам нужно использовать классы.
Изменчивость[About]
Источники здесь
Ответ 13
Сегодня об этом много написано, я бы хотел добавить аналогию. Надеюсь, что после этого у вас никогда не возникнет сомнений: Итог: классы передаются по ссылке, а структуры передаются по значению.
Предположим, вы поделились листом Google Doc со своим другом. Теперь, если он что-то изменит в этом, вы также увидите, что изменения в вашем документе Google, означает, что ваша копия также влияет. Это в основном " передано по ссылке ".
Но предположим, что если у вас есть файл .XLS, сохраненный на вашем компьютере. Вы передаете этот файл своему другу. Теперь, если он вносит какие-либо изменения в этот файл, ваш файл не будет испорчен/поврежден, потому что у вас есть собственная копия. Это в основном " передано по стоимости ". У вас есть несколько простых программ, чтобы проверить эту аналогию на быстрых игровых площадках.