structure vs classe en langage swift
Depuis Apple book "L'une des différences les plus importantes entre les structures et les classes est que les structures sont toujours copiées quand elles sont passées dans votre code, mais les classes sont passées par référence."
Quelqu'un peut-il me laisser comprendre ce que cela signifie, pour moi la classe et la structure semblent être les mêmes.
12 réponses
Voici un exemple avec un class
. Notez comment lorsque le nom est modifié, l'instance référencée par les deux variables est mise à jour. Bob
est maintenant Sue
, partout où Bob
a été référencé.
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"
Et maintenant, avec un struct
, nous voyons que les valeurs sont copiées et chaque variable maintient son propre ensemble de valeurs. Lorsque nous définissons le nom sur Sue
, la structure Bob
dans aStruct
n'est pas modifiée.
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"
Donc, pour représenter une entité complexe avec État, un class
est génial. Mais pour les valeurs ce sont simplement une mesure ou des bits de données connexes, un struct
a plus de sens afin que vous puissiez facilement les copier et calculer avec eux ou modifier les valeurs sans crainte d'effets secondaires.
La classe et la structure peuvent faire:
- Définir les propriétés pour stocker les valeurs
- Définir des méthodes pour fournir des fonctionnalités
- , Être étendu
- se conformer aux protocoles
- Définir les initialiseurs
- Définir des indices pour donner accès à leurs variables
Seule la classe peut faire:
- Héritage
- Type coulée
- Définir les désinitialiseurs
- autoriser le comptage des références pour plusieurs références.
struct
sont des types de valeur. Cela signifie que si vous copiez l'instance de la structure dans une autre variable, elle est simplement copiée dans la variable.
Exemple de type de valeur
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
Les Classes sont des types de référence. Cela signifie que si vous attribuez une instance de la classe à une variable, il ne conservera que la référence à l'instance et pas la copie.
Différences majeures entre les Structures et les Classes:
- Les Structures ne peuvent pas hériter d'autres types. Les Classes
- utilisent la conversion de type pour traiter une classe comme une superclasse ou une sous-classe, ainsi que pour vérifier l'adoption du protocole. Les structures ne peuvent utiliser que la partie d'adoption du protocole.
- Les Structures n'ont pas de désinitialiseurs.
- Les Structures ne peuvent pas avoir plusieurs références à la même instance
Si vous regardez plus loin dans le manuel apple, vous verrez cette section: "Les structures et les énumérations sont des Types de valeurs"
Dans cette section, vous verrez ceci:
"laissez-hd = Résolution(largeur: 1920, hauteur: 1080), var cinéma = hd Cet exemple déclare une constante appelée hd et le définit à une instance de résolution initialisée avec la largeur et la hauteur de full Vidéo HD (1920 pixels de large par 1080 pixels de haut).
Il déclare alors une variable appelé cinema et le définit sur le courant la valeur de la hd. Parce que la Résolution est une structure, une copie de l'existant l'instance est créée, et cette nouvelle copie est affectée à cinema. Quoique hd et le cinéma ont maintenant la même largeur et la hauteur, ils sont deux des instances complètement différentes dans les coulisses.
Ensuite, la propriété width de cinema est modifiée pour être la largeur du norme 2K légèrement plus large utilisée pour la projection de cinéma numérique (2048 pixels de large et 1080 pixels haut):
Cinéma.width = 2048 vérification de la propriété width des émissions de cinéma qu'il a effectivement changé pour être 2048:
Println ("le cinéma est maintenant (cinéma.largeur) pixels large") // imprime " cinéma est maintenant 2048 pixels de large cependant, la propriété width de l'instance hd d'origine a toujours l'ancienne valeur de 1920:
Println ("hd est toujours (hd.largeur) pixels large") / / imprime " hd est toujours 1920 pixels de large "
Lorsque le cinéma a été valeur actuelle de hd, les valeurs stockées dans hd ont été copiés dans la nouvelle instance de cinéma. Le résultat final est deux des instances complètement séparées, qui contenaient la même chose des valeurs numériques. Parce qu'ils sont des instances distinctes, la définition de la largeur du cinéma à 2048 n'affecte pas la largeur stockée en hd."
Extrait De: Apple Inc. "Le Langage De Programmation Swift."iBooks. https://itun.es/us/jEUH0.l
C'est la plus grande différence entre structures et classes. Les structures sont copiées et les classes sont référencées.
Les réponses ci-dessus sont correctes j'espère que ma réponse aidera quelqu'un qui ne comprend pas les réponses ci-dessus.
Eh bien dans Swift il y a deux types d'objets
- Struct
- Classe
La principale différence entre eux est
- Struct est valeur de type
- La classe est référence type
Par exemple, voici le code pour bien comprendre.
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
C'était la différence principale mais nous avons aussi sous différence.
De Catégorie
- Doit déclarer initialiser (constructeur)
- a des désinitialiseurs
- peut hériter d'autres classes
Struct
- Il a un initialiseur libre pour vous, vous n'avez pas à déclarer initaliser si vous le faites, l'initialiseur libre sera écrasé par votre initialiseur déclaré
- Ne pas avoir deinitialiser
- ne peut pas hériter d'une autre structure
Cette question semble être dupliquée mais quoi qu'il en soit, ce qui suit répondrait à la plupart des cas d'utilisation:
L'Une des différences les plus importantes entre les structures et les classes est-ce que les structures sont des types de valeur et sont toujours copiées quand elles sont passés dans votre code, et les classes sont le type de référence et sont passés par référence.
En outre, les classes ont un héritage qui permet à une classe d'hériter du caractéristiques de l'autre.
Les propriétés Struct sont stockées sur la pile et les instances de classe sont stockées sur tas par conséquent, parfois la pile est drastiquement plus rapide qu'un classe.
Struct obtient automatiquement un initialiseur par défaut alors qu'en classe, nous devez les initialiser.
Struct est thread-safe ou singleton, à tout moment.
Et aussi, Pour résumer la différence entre les structures et les classes, il est nécessaire de comprendre différence entre les types de valeur et de référence.
- Lorsque vous effectuez une copie d'un type de valeur, il copie toutes les données la chose que vous copiez dans la nouvelle variable. Ils sont 2 séparés les choses et changer l'une n'affecte pas l'autre.
- Lorsque vous faites une copie d'un type de référence, la nouvelle variable se réfère à le même emplacement que la chose que vous copiez. Cela signifie que changer l'un va changer l'autre car ils se réfèrent tous les deux à la même emplacement de mémoire. Échantillon le code ci-dessous pourrait être pris comme référence.
/ / sampleplayground.aire de jeux
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)
Sortie:
Current Name: John
Modified Name John
*************************
myStructExistingValue: Animation
myStructNewValue: Thriller
Habituellement (dans la plupart des langages de programmation), les objets sont des blocs de données qui sont stockés sur le tas, puis une référence (normalement un pointeur) à ces blocs, contient un name
utilise pour accéder à ces blocs de données. Ce mécanisme permet de partager des objets dans le tas en copiant la valeur de leurs références (pointeurs). Ce n'est pas le cas des types de données de base tels que les entiers, et c'est parce que la mémoire nécessaire pour créer une référence est presque la même que l'objet (dans ce cas entier valeur). Ainsi, ils seront passés en tant que valeurs et non en tant que référence dans le cas d'objets volumineux.
Swift utilise struct afin d'améliorer les performances même avec des objets String et Array.
Afin de comprendre la différence entre les structures et les Classes, nous devons connaître la principale différence entre les types de valeur et de référence. Les structures sont des types de valeur et cela signifie que chaque changement sur eux modifiera simplement cette valeur, les Classes sont des types de référence et chaque changement dans un type de référence modifiera la valeur allouée dans cet endroit de mémoire ou de référence. Par exemple:
Commençons par une classe, cette classe est conforme à Equatable juste pour pouvoir comparer des instances, nous créer une instance appelée pointClassInstanceA
et autre appelée {[3] } nous assignons la classe A à la Classe B, maintenant l'assertion dit qu'ils sont les mêmes...
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, que s'est-il passé ici pourquoi si nous venons de changer la valeur x de pointsClassInstanceB cela a également changé la valeur x de pointClassInstanceA? Eh bien, cela montre comment fonctionnent les types de référence, lorsque nous assignons l'instance A, en tant que valeur de l'instance B, puis nous modifions X de L'un d'eux, cela changera les deux X car ils partagent la même référence et ce qui a changé était la valeur de cette référence.
Faisons la même chose mais avec une structure
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
Nous avons fondamentalement la même structure que notre classe mais maintenant vous pouvez voir que lorsque vous imprimez la valeur X de pointStructInstanceA ce cas, il n'a pas changé, et c'est parce que les types de valeur fonctionnent différemment et chaque changement sur une de leurs instances sera "indépendant" et n'affectera pas l'autre.
Swift suggère d'utiliser plus de types de valeur et vous pouvez dire que leurs bibliothèques sont basées sur structs pour éviter les problèmes que les types de référence apportent, comme modifier involontairement une valeur, etc. Les structures sont la voie à suivre sur Swift. Espérons que cela aide.
Voici un exemple qui montre la différence entre struct et class précisément.
Capture d'écran de code écrit dans l'aire de jeux
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
Déjà il y a beaucoup écrit à ce sujet, je voudrais ajouter une analogie là-bas. J'espère que vous n'aurez jamais de doute à l'esprit après cela: Bas de ligne: Les classes sont passées par référence alors que les structures sont passées par valeur.
Supposons que vous partagiez une feuille google doc avec votre ami. Maintenant, s'il change quoi que ce soit en cela, vous verrez également que les changements sur votre google doc, signifie que votre copie est également affectée. C'est essentiellement "passé par référence".
Mais supposons, si vous avez un .XLS fie enregistré dans votre machine. Vous fournissez ce fichier donner à votre ami. Maintenant, s'il fait un changement dans ce fichier, votre fichier ne sera pas foiré/effectué parce que vous avez votre propre copie. C'est essentiellement "passé par la valeur". Vous avez déjà plusieurs programmes simples pour vérifier cette analogie dans 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"