структура против класса на языке swift



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



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

1001   12  

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 на Bob struct in 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"

Итак, для представления комплекса с состоянием сущность,class это круто. Но для значений, которые являются просто измерением или битами связанных данных, a struct больше смысла, так что вы можете легко скопировать их и работать с ними или изменить значения, не опасаясь побочных эффектов.

как класс, так и структура могут делать:

  • определить свойства для хранения ценностей
  • определить методы для обеспечения функциональности
  • быть продлен
  • соответствуют протоколам
  • определить 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 есть два типа объектов

  1. Struct
  2. класс

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

  • структура стоимостью тип
  • класс ссылка тип

например здесь код для понимания что ж.

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

Это было основное различие, но у нас есть и суб различия.

класс

  1. должен объявить инициализатор (конструктор)
  2. имеет deinitialisers
  3. могут наследовать от других классов

Struct

  1. у него есть бесплатный инициализатор для вас , вам не нужно объявлять initaliser, если вы делаете бесплатный инициализатор будет перезаписан вашим объявленным для инициализации тестов
  2. нет deinitialiser
  3. не может наследовать от другой структуры

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

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

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

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

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

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

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

  1. когда вы делаете экземпляр типа значения, он копирует все данные из что вы копируете в новую переменную. Они являются 2 отдельными вещи и изменение одного не влияет на другой.
  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.

скриншот написанного кода на игровой площадке
screenshot of written code in playground

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

    Ничего не найдено.