swift tatuape estrutura vs classe em linguagem rápida




swift tatuape (9)

Do livro da Apple "Uma das diferenças mais importantes entre estruturas e classes é que as estruturas são sempre copiadas quando são passadas no seu código, mas as classes são passadas por referência."

Alguém pode me deixar entender o que isso significa, para mim classe e struct parece ser o mesmo.


Geralmente (na maioria das linguagens de programação), os objetos são blocos de dados que são armazenados no heap e, em seguida, uma referência (normalmente um ponteiro) para esses blocos contém um name está sendo usado para acessar esses blocos de dados. Esse mecanismo permite compartilhar objetos no heap copiando o valor de suas referências (ponteiros). Este não é o caso de tipos básicos de dados, como Integers, e isso ocorre porque a memória necessária para criar uma referência é quase a mesma que o objeto (nesse caso, valor inteiro). Assim, eles serão passados ​​como valores não como referência no caso de objetos grandes.

Swift usa struct para melhorar o desempenho mesmo com objetos String e Array.

Uma boa leitura aqui


As respostas acima estão corretas Espero que minha resposta ajude alguém que não entende as respostas acima.

Bem, em Swift Existem dois tipos de objetos

  1. Struct
  2. Classe

A principal diferença entre eles é

  • Estruturar é tipo de valor
  • Classe é tipo de referência

Por exemplo aqui código para entender bem.

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

Esta foi a principal diferença, mas também temos sub diferenças.

Classe

  1. Deve declarar o inicializador (constructer)
  2. Tem deinitialisers
  3. Pode herdar de outras classes

Struct

  1. Tem inicializador livre para você, você não tem que declarar o capital inicial se você fizer o inicializador livre será sobrescrito pelo seu inicializador declarado
  2. Não tem desinicializador
  3. Não é possível herdar de outra estrutura

struct são tipos de valor. Isso significa que, se você copiar a instância da estrutura para outra variável, ela será copiada para a variável.

Exemplo para o tipo de valor

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

Classes são tipos de referência. Isso significa que, se você atribuir uma instância da classe a uma variável, ela armazenará apenas a referência à instância e não a cópia .


Se você olhar mais no manual da Apple, você verá esta seção: “Estruturas e enumerações são tipos de valor”

Nesta seção você verá isto:

“Let hd = resolução (largura: 1920, altura: 1080) var cinema = hd Este exemplo declara uma constante chamada hd e a define como uma resolução instância inicializada com a largura e a altura do vídeo em full HD (1920 pixels de largura por 1080 pixels de altura).

Em seguida, ele declara uma variável chamada cinema e a configura para o valor atual de hd. Como resolução é uma estrutura, uma cópia da instância existente é feita e essa nova cópia é atribuída ao cinema. Mesmo que o hd e o cinema tenham agora a mesma largura e altura, eles são duas instâncias completamente diferentes nos bastidores.

Em seguida, a propriedade de largura do cinema é alterada para ser a largura do padrão 2K ligeiramente mais amplo usado para projeção de cinema digital (2048 pixels de largura e 1080 pixels de altura):

Cinema .wid = 2048 Verificando a propriedade de largura do cinema mostra que ele realmente mudou para ser 2048:

Println ("cinema é agora (cinema. Largura) pixels de largura") // imprime "cinema agora tem 2048 pixels de largura. No entanto, a propriedade width da instância hd original ainda tem o antigo valor de 1920:

println ("hd ainda (largura em hd) pixels de largura") // imprime "hd ainda tem 1920 pixels de largura"

Quando o cinema recebeu o valor atual de hd, os valores armazenados em hd foram copiados para a nova instância de cinema. O resultado final é duas instâncias completamente separadas, que por acaso contêm os mesmos valores numéricos. Como são instâncias separadas, a configuração da largura do cinema para 2048 não afeta a largura armazenada em hd. ”

Trecho de: Apple Inc. "A linguagem de programação Swift." IBooks. https://itun.es/us/jEUH0.l

Essa é a maior diferença entre estruturas e classes. As estruturas são copiadas e as classes são referenciadas.


Aqui está um exemplo com uma class . Observe como quando o nome é alterado, a instância referenciada pelas duas variáveis ​​é atualizada. Bob é agora Sue , em todos os lugares que Bob foi referenciado.

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"

E agora, com uma struct , vemos que os valores são copiados e cada variável mantém seu próprio conjunto de valores. Quando definimos o nome para Sue , a estrutura de Bob no aStruct não é alterada.

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"

Então, para representar uma entidade complexa com estado, uma class é incrível. Mas para valores que são simplesmente uma medida ou bits de dados relacionados, uma struct faz mais sentido para que você possa copiá-los facilmente e calcular com eles ou modificar os valores sem medo de efeitos colaterais.


Esta questão parece ser duplicada, mas independentemente disso, o seguinte responderia a maior parte do caso de uso:

  1. Uma das diferenças mais importantes entre estruturas e classes é que as estruturas são tipos de valor e são sempre copiadas quando são passadas em seu código, e as classes são do tipo de referência e são passadas por referência.

  2. Além disso, as classes possuem uma herança que permite que uma classe herde as características de outra.

  3. As propriedades da estrutura são armazenadas nas instâncias Stack e Class são armazenadas no heap, portanto, às vezes, a pilha é drasticamente mais rápida que uma classe.

  4. Struct recebe um inicializador padrão automaticamente, enquanto na classe, temos que inicializar.

  5. Struct é thread safe ou singleton a qualquer momento.

E também, para resumir a diferença entre estruturas e classes, é necessário entender a diferença entre os tipos de valor e referência.

  1. Quando você faz uma cópia de um tipo de valor, ele copia todos os dados da coisa que você está copiando para a nova variável. São duas coisas separadas e a mudança de uma não afeta a outra.
  2. Quando você faz uma cópia de um tipo de referência, a nova variável refere-se ao mesmo local de memória da coisa que você está copiando. Isso significa que a mudança de um mudará o outro, já que ambos se referem ao mesmo local de memória. O código de exemplo abaixo pode ser tomado como referência.

// 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)

Saída:

Current Name:  John
Modified Name John
*************************
myStructExistingValue:  Animation
myStructNewValue:  Thriller

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"

Para entender a diferença entre Structs e Classes, precisamos conhecer a principal diferença entre os tipos de valor e referência. Estruturas são tipos de valores e isso significa que cada mudança neles apenas modificará esse valor, Classes são tipos de referência e cada alteração em um tipo de referência modificará o valor alocado naquele local de memória ou referência. Por exemplo:

Vamos começar com uma Classe, essa classe está em conformidade com o Equatorial apenas para poder comparar instâncias, criamos uma instância chamada pointClassInstanceA e outra chamada pointClassInstanceB atribuímos a classe A à classe B, agora a asserção diz que eles são os mesmos ...

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

Ok, o que aconteceu aqui porque se nós apenas mudamos o valor x de pointsClassInstanceB ele também mudou o valor de x de pointClassInstanceA? bem, isso mostra como os tipos de referência funcionam, quando atribuímos a instância A, como um valor da instância B e depois modificamos X de um deles, isso mudará ambos os Xs porque eles compartilham a mesma referência e o que mudou foi o valor daquele referência.

Vamos fazer o mesmo, mas com uma estrutura

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

Temos basicamente a mesma estrutura que a nossa classe, mas agora você pode ver que quando você imprime o valor x de pointStructInstanceA este caso não mudou, e isso ocorre porque os tipos de valor funcionam de forma diferente e cada alteração em uma das instâncias será " independente "e não afetará o outro.

Swift sugere usar mais tipos de valor e você pode dizer que suas bibliotecas são baseadas em estruturas para evitar os problemas que os tipos de referência trazem, como modificar um valor acidentalmente etc. As estratégias são o caminho a seguir no Swift. Espero que ajude.


Alreday há muito escrito sobre isso, eu gostaria de acrescentar uma analogia lá. Espero que você nunca tenha dúvidas em mente depois disso: Conclusão: as classes são passadas por referência, enquanto as estruturas são passadas por valor.

Suponha que você esteja compartilhando uma planilha do google doc com seu amigo. Agora, se ele mudar alguma coisa, você também verá que as alterações no seu google doc significam que sua cópia também será afetada. Isso é basicamente " passado por referência ".

Mas suponha, se você tiver um arquivo .XLS salvo em sua máquina. Você fornece esse arquivo para seu amigo. Agora, se ele estiver fazendo alguma alteração nesse arquivo, seu arquivo não será cancelado / afetado porque você tem sua própria cópia. Isso é basicamente " passado por valor ". Você já tem vários programas simples para verificar essa analogia em playgrounds rápidos.







swift