swift - metáfora - metafora juridica ejemplos
estructura vs clase en lenguaje rápido (12)
Del libro de Apple "Una de las diferencias más importantes entre estructuras y clases es que las estructuras siempre se copian cuando se pasan en su código, pero las clases se pasan por referencia".
¿Alguien me puede dejar entender lo que eso significa? Para mí, la clase y la estructura parecen ser las mismas.
Aquí hay un ejemplo con una class
. Observe cómo cuando se cambia el nombre, la instancia a la que hacen referencia ambas variables se actualiza. Bob
es ahora Sue
, en todas partes donde Bob
alguna vez se hizo referencia.
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"
Y ahora con una struct
vemos que los valores se copian y cada variable mantiene su propio conjunto de valores. Cuando establecemos el nombre para Sue
, la estructura de Bob
en aStruct
no cambia.
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"
Entonces, para representar una entidad compleja con estado, una class
es asombrosa. Pero para los valores que son simplemente una medida o bits de datos relacionados, una struct
tiene más sentido para que pueda copiarlos fácilmente y calcular con ellos o modificar los valores sin temor a los efectos secundarios.
Aquí hay un ejemplo que muestra la diferencia entre struct y class con precisión.
captura de pantalla del código escrito en el patio de recreo
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
Esta pregunta parece estar duplicada, pero a pesar de todo, la respuesta siguiente sería la mayor parte del caso de uso:
Una de las diferencias más importantes entre estructuras y clases es que las estructuras son tipos de valores y siempre se copian cuando se pasan en su código, y las clases son del tipo de referencia y se pasan por referencia.
Además, las clases tienen herencia, lo que permite que una clase herede las características de otra.
Las propiedades de Struct se almacenan en Stack y las instancias de Class se almacenan en Heap, por lo tanto, a veces la pila es drásticamente más rápida que una clase.
Struct obtiene un inicializador predeterminado de forma automática, mientras que en Class, tenemos que inicializar.
Struct es seguro para hilos o singleton en cualquier punto del tiempo.
Y también, para resumir la diferencia entre estructuras y clases, es necesario entender la diferencia entre el valor y los tipos de referencia.
- Cuando realiza una copia de un tipo de valor, copia todos los datos de la cosa que está copiando en la nueva variable. Son 2 cosas separadas y cambiar una no afecta a la otra.
- Cuando realiza una copia de un tipo de referencia, la nueva variable hace referencia a la misma ubicación de memoria que la que está copiando. Esto significa que cambiar uno cambiará el otro ya que ambos se refieren a la misma ubicación de memoria. El código de ejemplo a continuación podría tomarse como referencia.
// 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)
Salida:
Current Name: John
Modified Name John
*************************
myStructExistingValue: Animation
myStructNewValue: Thriller
Las respuestas anteriores son correctas. Espero que mi respuesta ayude a alguien que no entiende las respuestas anteriores.
Bien en Swift Hay dos tipos de objetos
- Struct
- Clase
La principal diferencia entre ellos es
- Struct es un tipo de valor
- La clase es tipo de referencia
Por ejemplo aquí código para entender bien.
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 fue la diferencia principal, pero también tenemos sub diferencias.
Clase
- Debe declarar initialiser (constructer)
- Tiene desinicializadores
- Puede heredar de otras clases
Struct
- Tiene un inicializador gratuito para usted, no tiene que declarar el inicializador si el inicializador declarado sobrescribe el inicializador gratuito.
- No tener desinciador
- No puede heredar de otra estructura
Para comprender la diferencia entre Estructuras y Clases, necesitamos saber la diferencia principal entre el valor y los tipos de referencia. Las estructuras son tipos de valores y eso significa que cada cambio en ellas simplemente modificará ese valor, las clases son tipos de referencia y cada cambio en un tipo de referencia modificará el valor asignado en ese lugar de memoria o referencia. Por ejemplo:
Comencemos con una clase, esta clase se ajusta a Equatable solo para poder comparar instancias, creamos una instancia llamada pointClassInstanceA
y otra llamada pointClassInstanceB
asignamos clase A a clase B, ahora la afirmación dice que son las mismas ...
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
Bien, ¿qué pasó aquí? ¿Por qué si simplemente cambiamos el valor de x de pointsClassInstanceB también cambió el valor de x de pointClassInstanceA? bueno, esto muestra cómo funcionan los tipos de referencia, cuando asignamos la instancia A, como un valor de la instancia B y luego modificamos X de uno de ellos, cambiará ambas X porque comparten la misma referencia y lo que cambió fue el valor de esa referencia.
Hagamos lo mismo pero con una estructura
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
Básicamente tenemos la misma estructura que nuestra clase, pero ahora puede ver que cuando imprime el valor x de pointStructInstanceA este caso no cambió, y esto se debe a que los tipos de valores funcionan de manera diferente y cada cambio en una de sus instancias será " independiente "y no afectará al otro.
Swift sugiere utilizar más tipos de valores y puede decir que sus bibliotecas se basan en estructuras para evitar los problemas que traen los tipos de referencia, como modificar involuntariamente un valor, etc. Las estructuras son el camino a seguir en Swift. Espero eso ayude.
Principales diferencias entre estructuras y clases:
- Las estructuras no pueden heredar de otros tipos.
- Las clases utilizan el método de conversión de tipos para tratar una clase como una superclase o una subclase, así como para verificar la adopción del protocolo. Las estructuras solo pueden usar la parte de adopción del protocolo.
- Las estructuras no tienen desinicializadores.
- Las estructuras no pueden tener múltiples referencias a la misma instancia
Si miras más lejos en el manual de la manzana, verás esta sección: "Las estructuras y las enumeraciones son tipos de valores"
En esta sección verás esto:
"Let hd = Resolution (width: 1920, height: 1080) var cinema = hd Este ejemplo declara una constante llamada hd y la establece en una resolución instancia inicializada con el ancho y la altura del video Full HD (1920 píxeles de ancho por 1080 píxeles de alto).
A continuación, declara una variable llamada cine y la establece en el valor actual de hd. Como Resolution es una estructura, se realiza una copia de la instancia existente y esta nueva copia se asigna a cinema. Aunque el HD y el cine ahora tienen el mismo ancho y alto, son dos instancias completamente diferentes detrás de la escena.
A continuación, se modifica la propiedad de ancho del cine para que sea el ancho del estándar 2K ligeramente más amplio utilizado para la proyección de cine digital (2048 píxeles de ancho y 1080 píxeles de alto):
Cinema. Width = 2048 La comprobación de la propiedad de ancho del cine muestra que realmente ha cambiado a 2048:
Println ("el cine ahora (ancho del cine) píxeles de ancho") // imprime "el cine ahora tiene 2048 píxeles de ancho Sin embargo, la propiedad de ancho de la instancia hd original todavía tiene el antiguo valor de 1920:
println ("hd sigue siendo (ancho de hd) píxeles de ancho") // imprime "hd todavía tiene 1920 píxeles de ancho"
Cuando al cine se le dio el valor actual de hd, los valores almacenados en hd se copiaron en la nueva instancia de cine. El resultado final es dos instancias completamente separadas, que casualmente contienen los mismos valores numéricos. Debido a que son instancias separadas, establecer el ancho del cine en 2048 no afecta el ancho almacenado en hd. "
Extracto de: Apple Inc. "The Swift Programming Language". IBooks. https://itun.es/us/jEUH0.l
Esta es la mayor diferencia entre estructuras y clases. Las estructuras se copian y las clases se referencian.
Tanto la clase como la estructura pueden hacer:
- Definir propiedades para almacenar valores
- Definir métodos para proporcionar funcionalidad
- Ser extendido
- Conforme a los protocolos
- Definir intializadores
- Definir subíndices para proporcionar acceso a sus variables
Solo la clase puede hacer:
- Herencia
- Tipo de fundición
- Definir desinicializadores
- Permita el conteo de referencias para múltiples referencias.
Usualmente (en la mayoría de los lenguajes de programación), los objetos son bloques de datos que se almacenan en el montón, y luego una referencia (normalmente un puntero) a estos bloques, contiene un name
se usa para acceder a estos bloques de datos. Este mecanismo permite compartir objetos en el montón al copiar el valor de sus referencias (punteros). Este no es el caso de los tipos de datos básicos, como los enteros, y eso se debe a que la memoria necesaria para crear una referencia es casi la misma que el objeto (en este caso, valor entero). Por lo tanto, se pasarán como valores no como referencia en el caso de objetos grandes.
Swift usa struct para mejorar el rendimiento incluso con objetos String y Array.
Ya hay mucho escrito sobre esto, me gustaría agregar una analogía allí. Espero que nunca tenga dudas en mente después de esto: En pocas palabras: las clases se pasan por referencia, mientras que las estructuras se pasan por valor.
Supongamos que está compartiendo una hoja de documento de Google con su amigo. Ahora, si cambia algo de eso, también verá que los cambios en su documento de Google significa que su copia también se verá afectada. Eso es básicamente " pasado por referencia ".
Pero supongamos, si tiene un .XLS fie guardado en su máquina. Usted proporciona ese archivo a su amigo. Ahora, si está haciendo algún cambio en ese archivo, su archivo no se arruinará porque tendrá su propia copia. Eso es básicamente " pasado por valor ". Tienes múltiples programas simples que ya están allí para verificar esta analogía en patios de juego rápidos.
struct
son tipos de valores. Significa que si copia la instancia de la estructura a otra variable, simplemente se copia a la variable.
Ejemplo para el 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
Las clases son tipos de referencia. Significa que si asigna una instancia de la clase a una variable, contendrá solo la referencia a la instancia y no a la copia .
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"