Структура против класса в быстром языке

Из книги 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
  • Класс

Основное различие между ними -

  • Тип структуры значение
  • Класс ссылочный тип

Например, здесь код хорошо понимает.

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

Этот вопрос кажется дублирующим, но, тем не менее, следующее ответит на большинство случаев использования:

  1. Одним из наиболее важных различий между структурами и классами является то, что структуры являются типами значений и всегда копируются, когда они передаются в вашем коде, а классы являются ссылочным типом и передаются по ссылке.

  2. Кроме того, у классов есть Наследование, которое позволяет одному классу наследовать характеристики другого.

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

  4. Struct автоматически получает инициализатор по умолчанию, тогда как в Class мы должны инициализировать.

  5. Struct является потокобезопасным или одноэлементным в любой момент времени.

А также, чтобы подвести итог разницы между структурами и классами, необходимо понимать разницу между типом value и ссылочным типом.

  1. Когда вы создаете копию типа значения, она копирует все данные из объекта, который вы копируете, в новую переменную. Это две разные вещи, и изменение одного не влияет на другое.
  2. Когда вы создаете копию ссылочного типа, новая переменная ссылается на ту же область памяти, что и копируемая вещь. Это означает, что изменение одного изменит другое, поскольку они оба ссылаются на одну и ту же область памяти. Пример кода ниже может быть взят в качестве ссылки.

//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, сохраненный на вашем компьютере. Вы передаете этот файл своему другу. Теперь, если он вносит какие-либо изменения в этот файл, ваш файл не будет испорчен/поврежден, потому что у вас есть собственная копия. Это в основном " передано по стоимости ". У вас есть несколько простых программ, чтобы проверить эту аналогию на быстрых игровых площадках.