Pourquoi Choisir Struct Plus De Classe?
Jouer avec Swift, venant de Java fond, pourquoi voudriez-vous choisir une Structure plutôt qu'une Classe? Semble qu'ils sont la même chose, avec une Structure offrant moins de fonctionnalités. Pourquoi choisir alors?
les Structures sont toujours copiés quand ils sont passés dans votre code, et ne pas utiliser de comptage de référence. source: developer.apple.com/library/prerelease/ios/documentation/swift/...
Je dirais que les structures sont plus appropriées pour contenir les données, et pas logique. Pour parler en Java conditions, imaginer des structures comme des "Objets de Valeur".
Je suis étonné de voir dans toute cette conversation, il n'y a pas de mention directe de copy-on-write une.k.un. paresseux copie. Des préoccupations au sujet de struct copier les performances sont tout à fait discutable sur le compte de cette conception.
Le choix d'une structure sur une classe n'est pas une question d'opinion. Il existe des raisons spécifiques à choisir l'un ou l'autre.
Je recommande fortement de voir Pourquoi le Tableau n'est pas thread-safe. C'est lié car les Tableaux & les Structures sont à la fois des types de valeur. Toutes les réponses ici mentionner qu'avec les structures/tableaux/types de valeur n'auront jamais de fil problème de Sécurité, mais il est un coin de cas dans lequel vous allez.
Je dirais que les structures sont plus appropriées pour contenir les données, et pas logique. Pour parler en Java conditions, imaginer des structures comme des "Objets de Valeur".
Je suis étonné de voir dans toute cette conversation, il n'y a pas de mention directe de copy-on-write une.k.un. paresseux copie. Des préoccupations au sujet de struct copier les performances sont tout à fait discutable sur le compte de cette conception.
Le choix d'une structure sur une classe n'est pas une question d'opinion. Il existe des raisons spécifiques à choisir l'un ou l'autre.
Je recommande fortement de voir Pourquoi le Tableau n'est pas thread-safe. C'est lié car les Tableaux & les Structures sont à la fois des types de valeur. Toutes les réponses ici mentionner qu'avec les structures/tableaux/types de valeur n'auront jamais de fil problème de Sécurité, mais il est un coin de cas dans lequel vous allez.
OriginalL'auteur bluedevil2k | 2014-06-15
Vous devez vous connecter pour publier un commentaire.
Selon le très populaire de la WWDC 2015 parler Protocole de la Programmation Orientée dans Swift (vidéo, transcription), Swift fournit un certain nombre de caractéristiques qui en font des structures de mieux que de classes dans de nombreuses circonstances.
Les structures sont préférables si elles sont relativement petites et copiables parce que la copie est plus sûr que d'avoir de multiples références à la même instance, comme il arrive avec les classes. Ceci est particulièrement important lors du passage autour d'une variable à un grand nombre de classes et/ou dans un environnement multithread. Si vous pouvez toujours envoyer une copie de votre variable à d'autres endroits, vous n'aurez jamais à vous soucier de l'autre endroit en changeant la valeur de votre variable au-dessous de vous.
Avec les Structures, il y a beaucoup moins besoin de s'inquiéter à propos des fuites de mémoire ou plusieurs threads de course à consulter/modifier une seule instance d'une variable. (Pour les plus techniques d'esprit, l'exception à cela est lors de la capture d'une structure à l'intérieur d'une fermeture parce que c'est en fait la capture d'une référence à l'instance, sauf si vous explicitement de marquer pour être copié).
Classes peuvent également devenir énorme parce qu'une classe ne peut hériter que d'une seule super-classe. Ce qui nous encourage à créer d'énormes super-classes qui englobe de nombreuses différentes capacités qui ne sont que faiblement liées. En utilisant des protocoles, en particulier avec les extensions de protocole où vous pouvez fournir des implémentations de protocoles, permet d'éliminer la nécessité pour les classes à réaliser ce genre de comportement.
Le discours énonce ces scénarios où les classes sont privilégiées:
Il implique que les structures devrait être la valeur par défaut et les classes devrait être une solution de repli.
D'autre part, Le Langage De Programmation Swift la documentation est un peu contradictoire:
Ici, c'est de prétendre que nous devrions valeur par défaut à l'aide de classes et d'utiliser les structures que dans des circonstances particulières. En fin de compte, vous avez besoin de comprendre le monde réel implication des types de valeur contre les types référence, puis vous pouvez prendre une décision éclairée sur l'utilisation de structures ou classes. Aussi, gardez à l'esprit que ces concepts sont toujours en évolution et La Swift Langage de Programmation de la documentation a été écrite avant le Protocole de la Programmation Orientée conférence a été donnée.
Qui semble être exactement le contraire de ce qu'il dit. Il était en train de dire qu'une classe doit être la valeur par défaut que vous utilisez, et non pas une structure
In practice, this means that most custom data constructs should be classes, not structures.
Pouvez-vous m'expliquer comment, après avoir lu cela, vous obtenez que la plupart des ensembles de données devraient être des structures et non des classes? Ils ont donné à un ensemble spécifique de règles quand quelque chose doit être une structure (struct) et assez bien dit "tous les autres scénarios, une classe, c'est mieux."Dernière ligne devrait dire, "Mon conseil personnel est à l'opposé de la documentation:"... et puis c'est une grande réponse!
Swift 2.2 livre toujours dit d'utiliser les classes dans la plupart des situations.
Struct plus de Classe est certainement à réduire la complexité. Mais quelle est l'incidence sur l'utilisation de la mémoire lorsque les structures devient le choix par défaut. Quand les choses deviennent copié partout au lieu de référence, il devrait augmenter l'utilisation de la mémoire par l'application. N'est-ce pas?
OriginalL'auteur drewag
Depuis struct instances sont allouées sur la pile, et des instances de classe sont alloués sur le tas, les structures peuvent parfois être considérablement plus rapide.
Cependant, vous devez toujours en mesure de vous-même et de se prononcer sur votre cas d'utilisation.
Prenons l'exemple suivant, qui montre 2 stratégies d'emballage
Int
type de données à l'aide destruct
etclass
. Je suis à l'aide des 10 valeurs répétées sont de mieux refléter le monde réel, où vous avez de multiples domaines.La Performance est mesurée à l'aide de
Code peut être trouvé à https://github.com/knguyen2708/StructVsClassPerformance
Mise à JOUR (27 mars 2018):
De Swift 4.0, Xcode, 9.2, l'exécution de la Libération de construire sur iPhone 6S, iOS 11.2.6, Swift Compilateur paramètre est
-O -whole-module-optimization
:class
version a pris 2.06 secondesstruct
version a pris 4.17 e-08 secondes (50 000 000 de fois plus rapide)(Je n'ai plus moyen de multiples pistes, car les écarts sont très faibles, moins de 5%)
Note: la différence est beaucoup moins dramatique sans module d'optimisation. Je serais heureux si quelqu'un peut préciser ce que l'indicateur ne fait.
Mise à JOUR (7 Mai 2016):
De Swift 2.2.1, Xcode, 7.3, l'exécution de la Libération de construire sur iPhone 6S, iOS 9.3.1, en moyenne sur 5 fonctionne, Swift Compilateur paramètre est
-O -whole-module-optimization
:class
version a pris 2.159942142 sstruct
version a pris 5.83 E-08s (37,000,000 fois plus rapide)Note: comme il a été mentionné que dans des scénarios du monde réel, il n'y aura probablement plus de 1 champ dans une structure (struct), j'ai ajouté des tests pour les structures/classes avec 10 champs au lieu de 1. Étonnamment, les résultats ne varient pas beaucoup.
RÉSULTATS ORIGINAUX (1 juin 2014):
(Ran sur struct/classe avec 1 terrain, et non pas 10)
De Swift 1.2, Xcode, 6.3.2, l'exécution de la Libération de construire sur l'iPhone 5S, iOS 8.3, en moyenne sur 5 fonctionne
class
version a pris 9.788332333 sstruct
version a pris 0.010532942 s (900 fois plus rapide)Les ANCIENS RÉSULTATS (de temps inconnu)
(Ran sur struct/classe avec 1 terrain, et non pas 10)
Avec la version de build sur mon MacBook Pro:
class
version a pris 1.10082 secstruct
version a pris 0.02324 sec (50 fois plus rapide)-1 Ce test n'est pas un bon exemple car il n'existe qu'un seul var sur les struct. Notez que si vous ajoutez plusieurs valeurs et un objet ou deux, la structure de la version devient comparable à la version de la classe. Plus de vars vous ajoutez, le ralentissement de la structure de la version se.
obtenu votre point, mais, par exemple, est "bon" ou non dépend de la situation spécifique. Ce code a été extrait à partir de ma propre application, de sorte qu'il est valide d'un cas d'utilisation, et en utilisant les structures n'ont massivement améliore les performances de mon application. C'est juste probablement pas une commune de cas d'utilisation (ainsi, la commune de cas d'utilisation est, pour la plupart des applications, personne ne se soucie de la façon dont rapidement les données peuvent être transmises, car le goulot d'étranglement qui se passe ailleurs, par exemple, les connexions réseau, de toute façon, l'optimisation n'est pas que critique lorsque vous avez GHz les appareils avec l'Abg ou RAM).
Autant je comprends la copie dans la swift est optimisé pour arriver à ÉCRIRE le temps. Ce qui signifie qu'il n'existe pas de copie de mémoire effectué, à moins que la nouvelle copie est sur le point d'être modifié.
Cette réponse montre un exemple extrêmement trivial, au point d'être irréaliste et donc erronée pour de nombreux cas. Une meilleure réponse serait "ça dépend".
OriginalL'auteur Khanh Nguyen
Similitudes entre les structures et les classes.
J'ai créé gist pour cela avec des exemples simples.
https://github.com/objc-swift/swift-classes-vs-structures
Et les différences
1. De l'héritage.
structures ne peuvent pas hériter de swift. Si vous voulez
Aller pour une classe.
2. Passer Par
Swift structures passage par valeur et des instances de classe passage par référence.
Différences Contextuelles
Struct constantes et les variables
Exemple (Utilisé lors de la WWDC 2014)
Définit une structure appelée Point.
Maintenant, si j'essaie de modifier le x. Ses une expression valide.
Mais si je définis un point en tant que constante.
Dans ce cas tout le point est immuable constante.
Si j'ai utilisé une classe Point au lieu de cela est une expression valide. Parce que dans une classe immuable constante, c'est la référence à la classe elle-même pas ses variables d'instance (à Moins que ces variables définies comme constantes)
Le ci-dessus essentiel est de savoir comment nous pouvons atteindre l'héritage de saveurs pour les struct. Vous verrez une syntaxe semblable. A: B. Il est struct appelé implémente le protocole appelé B. la documentation d'Apple mentionner clairement la structure ne supporte pas pur héritage et il ne le fait pas.
l'homme du dernier paragraphe de la vôtre a été grande. J'ai toujours su que vous pouviez changer les constantes...mais de temps en temps, j'ai vu que vous ne pouviez pas si j'ai été déconcerté. Cette distinction visible
OriginalL'auteur MadNik
Voici quelques autres raisons à prendre en compte:
structs obtenir automatiquement un initialiseur que vous n'avez pas à maintenir dans le code.
Pour obtenir ce dans une classe, vous devrez ajouter de l'initialiseur, et maintenir la intializer...
Collection de base des types comme
Array
sont des structures. Le plus vous les utilisez dans votre propre code, plus vous obtiendrez utilisé pour le passage par valeur, par opposition à la référence. Par exemple:Apparemment immutabilité contre la mutabilité est un vaste sujet, mais beaucoup de gens intelligents pensent immutabilité -- les structures dans ce cas, est préférable. Mutable vs des objets immuables
internal
portée.confirmée - stackoverflow.com/a/26224873/8047 -- et l'homme qui est ennuyeux.
il y a de bonnes raisons pour tout à l'Swift, mais à chaque fois que quelque chose est vrai dans un endroit et pas à un autre, le développeur n'a pas à connaître plus de choses. Je suppose que c'est ici que je suis censé dire "c'est passionnant de travailler dans de tels défis de la langue!"
Puis-je aussi ajouter que ce n'est pas l'immutabilité des structures qui les rend utiles (bien que c'est une très bonne chose). Vous pouvez muter les structures, Mais vous devez marquer les méthodes
mutating
de sorte que vous êtes clair sur ce que les fonctions de changer leur état. Mais leur nature types de valeur est-ce qui est important. Si vous déclarez une structure aveclet
vous ne pouvez pas appeler toute la mutation des fonctions. La WWDC 15 de la vidéo sur Meilleurs programmes par le biais des types de valeur est une excellente ressource sur cette.Merci @Abizern, je n'ai jamais vraiment compris, et avant la lecture de votre commentaire. Pour les objets, laissez vs var n'est pas beaucoup de différence, mais pour les structs c'est énorme. Merci de souligner ce point.
OriginalL'auteur Dan Rosenstark
En supposant que nous savons Struct est un type de valeur et Classe est un type de référence.
Si vous ne savez pas quel type de valeur et un type de référence sont ensuite voir Quelle est la différence entre le passage par référence vs passage par valeur?
Basé sur mikeash post:
En outre, n'utilisez pas de classe lorsque vous devez remplacer chaque instance d'une fonction ie eux de ne pas avoir tout partagé fonctionnalité.
Alors au lieu d'avoir plusieurs sous-classes d'une classe. L'utilisation de plusieurs structures qui sont conformes à un protocole.
OriginalL'auteur Honey
Certains avantages:
Assurez-vous. Je peux également joindre une mise en garde pour elle. Le but de la dynamique de l'expédition est de choisir une mise en œuvre lorsque vous ne savez pas à l'avant. En Swift, qui peuvent être soit en raison de l'héritage (peut être redéfinie dans une sous-classe), ou en raison de la fonction générique (vous ne savez pas ce que le paramètre générique). Les structures ne peuvent pas être héritée de et le module d'optimisation de + générique de spécialisation pour la plupart élimine l'inconnue génériques, afin que les méthodes peuvent être appelées directement plutôt que d'avoir à chercher comment l'appeler. Non spécialisé génériques toujours répartition dynamique de structures bien
Merci, bonne explication. Nous nous attendons à plus de temps d'exécution de la vitesse, ou du moins d'ambiguïté à partir d'un IDE point de vue, ou les deux?
La plupart de l'ancien.
Juste une remarque que les méthodes ne sont pas statiquement distribué si vous vous référez à la structure par l'intermédiaire d'un protocole.
OriginalL'auteur Catfish_Man
Structure est beaucoup plus rapide que de Classe. Aussi, si vous avez besoin d'héritage, alors vous devez utiliser la Classe. Point le plus important est que la Classe est le type de référence alors que la Structure est de type valeur. par exemple,
maintenant permet de créer une instance à la fois.
maintenant laisse passer ces exemple de deux fonctions qui modifient l'identification, la description, la destination, etc..
aussi,
donc,
maintenant, si on imprime le flightA de l'id et la description, nous obtenons
Ici, nous pouvons voir l'id et la description de FlightA a changé car le paramètre passé à la méthode de modification renvoie l'adresse mémoire de flightA objet(type de référence).
maintenant, si nous avons l'impression que l'id et la description de FLightB exemple on se,
Ici, nous pouvons voir que la FlightB instance n'est pas modifié parce que dans modifyFlight2 méthode, l'instance réelle de Flight2 est passe plutôt que de référence ( valeur type).
il n'y a pas de flightB classe ....
alors pourquoi parlez-vous de FlightB bro?
Here we can see that the FlightB instance is not changed
grande réponse. Je voulais simplement faire remarquer que vous avez déclaré flightA deux fois quand je pense que vous avez voulu déclarer FlightA, puis FlightB.
OriginalL'auteur Manoj Karki
De répondre à la question du point de vue des types de valeur vs types de référence, à partir de cette Pomme post de blog il semble très simple:
Comme mentionné dans l'article, une classe sans écriture propriétés se comportent de la même manière avec une struct, avec (je vais ajouter) une mise en garde: les structures sont les meilleurs pour thread-safe modèles -- de plus en plus imminente exigence dans l'app moderne de l'architecture.
OriginalL'auteur David James
Avec les classes que vous obtenez de l'héritage et sont passés par référence, les structures n'ont pas d'héritage, et sont passés par valeur.
Il y a de grandes WWDC sessions sur Swift, cette question est posée dans le détail étroit dans l'un d'eux. Assurez-vous de regarder ceux qui, comme elle, vous obtiendrez jusqu'à la vitesse beaucoup plus rapidement, le guide de Langue ou de l'iBook.
Pour moi c'est un bon début ici: github.com/raywenderlich/...
Il est probablement parler de cette grande session: Protocole de la Programmation Orientée en Swift. (Les liens: vidéo, transcription)
OriginalL'auteur Joride
Je ne dirais pas que les structures offrent moins de fonctionnalités.
Sûr, l'auto est immuable, sauf dans la mutation de la fonction, mais c'est tout.
L'héritage fonctionne très bien aussi longtemps que vous vous en tenez à la bonne vieille idée que chaque classe doit être abstraite, finale ou la finale.
Mettre en œuvre les classes abstraites que des protocoles et final classes structs.
La bonne chose à propos des structures est que vous pouvez faire vos champs mutables sans créer partagé mutable l'état parce que la copie sur écriture qui s'en occupe 🙂
C'est pourquoi les propriétés des champs dans l'exemple suivant sont tous mutable, que je ne ferais pas en Java ou en C# ou swift classes.
Exemple de structure d'héritage avec un peu de sale et simple d'utilisation en bas dans la fonction nommée "exemple":
OriginalL'auteur yeoman
Creational Modèle:
Dans swift, Struct est une types de valeur qui sont automatiquement dupliqués. Par conséquent, nous obtenons le comportement requis pour mettre en œuvre le prototype de modèle pour gratuit.
Alors que classes sont le type de référence, ce qui n'est pas automatiquement clonés au cours de la mission. Pour mettre en œuvre le prototype de modèle, les classes doivent adopter les
NSCopying
protocole.Copie superficielle doublons seulement la référence, que des points à ceux des objets, alors que copie en profondeur les doublons de référence de l'objet.
La mise en œuvre de copie en profondeur pour chaque type de référence est devenu une tâche fastidieuse. Si les classes d'inclure d'autres type de référence, nous avons à mettre en œuvre un prototype de modèle pour chacune des références propriétés. Et puis nous avons à copier la totalité de l'objet graphique par la mise en œuvre de la
NSCopying
protocole.En utilisant les structures et les énumérations,, nous avons fait notre code plus simple puisque nous n'avons pas à mettre en œuvre la copie de la logique.
OriginalL'auteur Balasubramanian
De nombreux Cacao Api requièrent NSObject sous-classes, ce qui vous force à l'aide de la classe. Mais à part cela, vous pouvez utiliser la suite de cas d'Apple, Swift blog de décider si l'utilisation d'un struct /valeur d'enum type ou une classe de type de référence.
https://developer.apple.com/swift/blog/?id=10
OriginalL'auteur akshay
Structs
sontvalue type
etClasses
sontreference type
plusieurs threads peuvent muter l'instance sans avoir à se soucier
sur les conditions de course ou de blocages
est pas de fuites de mémoire.
Utiliser un
value
type:code sur plusieurs threads
Utiliser un
reference
type:D'autres informations peuvent également être trouvées dans la documentation d'Apple
https://docs.swift.org/swift-book/LanguageGuide/ClassesAndStructures.html
Des Informations Supplémentaires
Swift types de valeur sont conservés dans la pile. Dans un processus, chaque thread a son propre espace de pile, de sorte qu'aucun autre thread ne sera en mesure d'accéder à votre type de valeur directement. Par conséquent, aucune des conditions de course, des serrures, des blocages ou liés à la synchronisation des threads complexité.
Types de valeur n'ont pas besoin d'allocation dynamique de la mémoire ou de comptage de référence, qui sont des opérations coûteuses. Dans le même temps, des méthodes sur des types de valeur sont envoyés de manière statique. Celles-ci créent un énorme avantage en faveur des types de valeur en termes de performances.
Comme un rappel ici est une liste de Swift
Types de valeur:
Types de référence:
OriginalL'auteur casillas
Un point de ne pas obtenir l'attention de ces réponses est qu'une variable contenant une classe vs une structure peut être un
let
tout en permettant des modifications sur les propriétés de l'objet, tandis que vous ne pouvez pas faire cela avec une struct.Ceci est utile si vous ne voulez pas la variable à jamais point à un autre objet, mais a encore besoin de modifier l'objet, c'est à dire dans le cas d'avoir beaucoup de variables d'instance que vous souhaitez mettre à jour l'un après l'autre. Si c'est une struct, vous devez autoriser la variable à réinitialiser un autre objet avec
var
pour ce faire, depuis une valeur constante de type rapide correctement permet à zéro mutation, tandis que les types de référence (les classes) ne se comportent pas de cette façon.OriginalL'auteur johnbakers
Comme struct sont des valeurs types et vous pouvez créer la mémoire très facilement, ce qui les stocke dans la pile.Struct peut être facilement accessible et d'après l'étendue du travail, il est facilement libéré à partir de la pile de la mémoire par le biais de la pop à partir du haut de la pile.
Sur l'autre main de la classe est un type de référence qui stocke dans le tas et les modifications apportées à un objet de classe aura un impact sur d'autres objets, car ils sont étroitement liés et le type de référence.Tous les membres d'une structure publique, alors que tous les membres d'une classe sont privés.
Les inconvénients de la structure est qu'elle ne peut pas être héritée .
OriginalL'auteur Tapash Mollick
De la Structure et de la classe utilisateur a défié les types de données
Par défaut, la structure est un public tandis que la classe est privée
Classe implémente le directeur de l'encapsulation
Les objets d'une classe sont créés sur le segment de mémoire
Classe est utilisé pour re convivialité tandis que la structure est utilisé pour le regroupement
les données dans la même structure
Structure de données des membres ne peut pas être initialisé directement, mais ils peuvent être
attribué par l'extérieur de la structure
Membres de données de classe peuvent être initialisées directement par le paramètre moins
constructeur et attribué par le constructeur paramétré
Absolument incorrect
OriginalL'auteur Ridaa Zahra