Swift - Guide rapide
Swift 4 est un nouveau langage de programmation développé par Apple Inc pour le développement iOS et OS X. Swift 4 adopte le meilleur de C et Objective-C, sans les contraintes de compatibilité C.
Swift 4 utilise des modèles de programmation sûrs.
Swift 4 offre des fonctionnalités de programmation modernes.
Swift 4 fournit une syntaxe similaire à Objective-C.
Swift 4 est un moyen fantastique d'écrire des applications iOS et OS X.
Swift 4 offre un accès transparent aux frameworks Cocoa existants.
Swift 4 unifie les parties procédurale et orientée objet du langage.
Swift 4 n'a pas besoin d'une importation de bibliothèque distincte pour prendre en charge des fonctionnalités telles que l'entrée / sortie ou la gestion des chaînes.
Swift 4 utilise le même environnement d'exécution que le système Obj-C existant sur Mac OS et iOS, ce qui permet aux programmes Swift 4 de s'exécuter sur de nombreuses plates-formes iOS 6 et OS X 10.8 existantes.
Swift 4 est livré avec une fonctionnalité de terrain de jeu où les programmeurs Swift 4 peuvent écrire leur code et l'exécuter pour voir les résultats immédiatement.
La première version publique de Swift est sortie en 2010. Il a fallu Chris Lattnerpresque 14 ans pour arriver à la première version officielle, et plus tard, elle a été soutenue par de nombreux autres contributeurs. Swift 4 a été inclus dans la version bêta de Xcode 6.
Les concepteurs de Swift ont pris des idées de divers autres langages populaires tels que Objective-C, Rust, Haskell, Ruby, Python, C # et CLU.
Configuration de l'environnement local
Swift 4 fournit une plate-forme Playground à des fins d'apprentissage et nous allons configurer la même chose. Vous avez besoin du logiciel xCode pour démarrer votre codage Swift 4 dans Playground. Une fois que vous êtes à l'aise avec les concepts de Swift 4, vous pouvez utiliser xCode IDE pour le développement d'applications iOS / OS x.
Pour commencer, nous considérons que vous avez déjà un compte sur le site Web des développeurs Apple. Une fois connecté, accédez au lien suivant - Télécharger pour les développeurs Apple
Cela listera un certain nombre de logiciels disponibles comme suit -
Sélectionnez maintenant xCode et téléchargez-le en cliquant sur le lien donné près de l'image du disque. Après avoir téléchargé le fichier dmg, vous pouvez l'installer en double-cliquant simplement dessus et en suivant les instructions données. Enfin, suivez les instructions données et déposez l'icône xCode dans le dossier Application.
Vous avez maintenant installé xCode sur votre machine. Ensuite, ouvrez Xcode à partir du dossier Application et continuez après avoir accepté les termes et conditions. Si tout va bien, vous obtiendrez l'écran suivant -
Sélectionner Get started with a playgroundet entrez un nom pour le terrain de jeu et sélectionnez iOS comme plate-forme. Enfin, vous obtiendrez la fenêtre Playground comme suit -
Voici le code extrait de la fenêtre Swift 4 Playground par défaut.
import UIKit
var str = "Hello, playground"
Si vous créez le même programme pour le programme OS X, il inclura l'importation de Cocoa et le programme ressemblera à ceci:
import Cocoa
var str = "Hello, playground"
Lorsque le programme ci-dessus est chargé, il devrait afficher le résultat suivant dans la zone de résultats Playground (côté droit).
Hello, playground
Félicitations, vous avez votre environnement de programmation Swift 4 prêt et vous pouvez continuer avec votre véhicule d'apprentissage "Tutorials Point".
Nous avons déjà vu un morceau du programme Swift 4 lors de la configuration de l'environnement. Commençons encore une fois par ce qui suitHello, World! programme créé pour le terrain de jeu OS X, qui comprend import Cocoa comme indiqué ci-dessous -
/* My first program in Swift 4 */
var myString = "Hello, World!"
print(myString)
Si vous créez le même programme pour iOS Playground, il inclura import UIKit et le programme ressemblera à ceci -
import UIKit
var myString = "Hello, World!"
print(myString)
Lorsque nous exécutons le programme ci-dessus en utilisant un terrain de jeu approprié, nous obtiendrons le résultat suivant -
Hello, World!
Voyons maintenant la structure de base d'un programme Swift 4, afin qu'il vous soit facile de comprendre les éléments de base du langage de programmation Swift 4.
Importer dans Swift 4
Vous pouvez utiliser le importpour importer n'importe quel framework Objective-C (ou bibliothèque C) directement dans votre programme Swift 4. Par exemple, ce qui précèdeimport cocoa rend toutes les bibliothèques, API et environnements d'exécution Cocoa qui forment la couche de développement pour l'ensemble d'OS X, disponibles dans Swift 4.
Cocoa est implémenté en Objective-C, qui est un sur-ensemble de C, il est donc facile de mélanger C et même C ++ dans vos applications Swift 4.
Jetons dans Swift 4
Un programme Swift 4 se compose de divers jetons et un jeton est soit un mot-clé, un identificateur, une constante, une chaîne littérale ou un symbole. Par exemple, l'instruction Swift 4 suivante se compose de trois jetons -
print("test!")
The individual tokens are:
print("test!")
commentaires
Les commentaires sont comme des textes d'aide dans votre programme Swift 4. Ils sont ignorés par le compilateur. Les commentaires sur plusieurs lignes commencent par / * et se terminent par les caractères * / comme indiqué ci-dessous -
/* My first program in Swift 4 */
Les commentaires sur plusieurs lignes peuvent être imbriqués dans Swift 4. Voici un commentaire valide dans Swift 4 -
/* My first program in Swift 4 is Hello, World!
/* Where as second program is Hello, Swift 4! */ */
Les commentaires sur une seule ligne sont écrits en utilisant // au début du commentaire.
// My first program in Swift 4
Point virgule
Swift 4 ne vous oblige pas à taper un point-virgule (;) après chaque instruction de votre code, bien que ce soit facultatif; et si vous utilisez un point-virgule, le compilateur ne s'en plaindra pas.
Cependant, si vous utilisez plusieurs instructions sur la même ligne, il est nécessaire d'utiliser un point-virgule comme délimiteur, sinon le compilateur lèvera une erreur de syntaxe. Vous pouvez écrire ce qui précède Hello, World! programme comme suit -
/* My first program in Swift 4 */
var myString = "Hello, World!"; print(myString)
Identifiants
Un identifiant Swift 4 est un nom utilisé pour identifier une variable, une fonction ou tout autre élément défini par l'utilisateur. Un identificateur commence par un alphabet A à Z ou a à z ou un trait de soulignement _ suivi de zéro ou plusieurs lettres, traits de soulignement et chiffres (0 à 9).
Swift 4 n'autorise pas les caractères spéciaux tels que @, $ et% dans les identificateurs. Swift 4 est uncase sensitivelangage de programmation. Ainsi, Manpower et manpower sont deux identifiants différents dans Swift 4. Voici quelques exemples d'identifiants acceptables -
Azad zara abc move_name a_123
myname50 _temp j a23b9 retVal
Pour utiliser un mot réservé comme identifiant, vous devrez mettre un backtick (`) avant et après. Par exemple,class n'est pas un identifiant valide, mais `class`est valide.
Mots clés
Les mots-clés suivants sont réservés dans Swift 4. Ces mots réservés ne peuvent pas être utilisés comme constantes ou variables ou tout autre nom d'identifiant, à moins qu'ils ne soient échappés avec des accents inversés -
Mots clés utilisés dans les déclarations
Classe | déinit | Enum | extension |
Func | importer | Init | interne |
Laisser | opérateur | privé | protocole |
Publique | statique | struct | indice |
typealias | var |
Mots clés utilisés dans les déclarations
Pause | Cas | continuer | défaut |
faire | autre | tomber dans | pour |
si | dans | revenir | commutateur |
où | tandis que |
Mots clés utilisés dans les expressions et les types
comme | dynamicType | faux | est |
néant | soi | Soi | super |
vrai | _COLONNE_ | _FICHIER_ | _FONCTION_ |
_LIGNE_ |
Mots clés utilisés dans des contextes particuliers
associativité | commodité | dynamique | didSet |
final | avoir | infixe | inout |
paresseux | la gauche | mutant | aucun |
non mutant | optionnel | passer outre | suffixe |
priorité | préfixe | Protocole | obligatoire |
droite | ensemble | Type | sans propriétaire |
faible | willSet |
Espaces blancs
Une ligne ne contenant que des espaces, éventuellement avec un commentaire, est appelée ligne vierge et un compilateur Swift 4 l'ignore totalement.
L'espace blanc est le terme utilisé dans Swift 4 pour décrire les espaces, les tabulations, les caractères de nouvelle ligne et les commentaires. Les espaces séparent une partie d'une instruction d'une autre et permettent au compilateur d'identifier où un élément dans une instruction, comme int, se termine et où commence l'élément suivant. Par conséquent, dans la déclaration suivante -
var age
Il doit y avoir au moins un caractère d'espacement (généralement un espace) entre var et agepour que le compilateur puisse les distinguer. D'autre part, dans la déclaration suivante -
int fruit = apples + oranges //get the total fruits
Aucun espace n'est nécessaire entre les fruits et =, ou entre = et les pommes, bien que vous soyez libre d'en inclure pour une meilleure lisibilité.
L'espace des deux côtés d'un opérateur doit être égal, par exemple.
int fruit = apples +oranges //is a wrong statement
int fruit = apples + oranges //is a Correct statement
Littéraux
Un littéral est la représentation dans le code source d'une valeur d'un entier, d'un nombre à virgule flottante ou d'un type de chaîne. Voici des exemples de littéraux -
92 // Integer literal
4.24159 // Floating-point literal
"Hello, World!" // String literal
Impression dans Swift
Pour imprimer quoi que ce soit en rapide, nous avons le mot-clé «imprimer».
L'impression a trois propriétés différentes.
Items - Articles à imprimer
Separator - séparateur entre les éléments
Terminator - la valeur avec laquelle la ligne doit se terminer, voyons un exemple et la syntaxe de celle-ci.
print("Items to print", separator: "Value " , terminator: "Value")
// E.g. of print statement.
print("Value one")
// prints "Value one \n" Adds, \n as terminator and " " as separator by
default.
print("Value one","Value two", separator: " Next Value" , terminator: " End")
//prints "Value one Next Value Value two End"
Dans le code ci-dessus, la première instruction print ajoute \ n, newline Feed comme terminateur par défaut, alors que comme dans la deuxième instruction print nous avons donné "End" comme terminateur, donc il affichera "End" au lieu de \ n.
Nous pouvons donner notre séparateur et terminateurs personnalisés selon nos besoins.
Lors de la programmation dans n'importe quel langage de programmation, vous devez utiliser différents types de variables pour stocker des informations. Les variables ne sont rien d'autre que des emplacements de mémoire réservés pour stocker des valeurs. Cela signifie que lorsque vous créez une variable, vous réservez de l'espace en mémoire.
Vous pouvez souhaiter stocker des informations de différents types de données comme une chaîne, un caractère, un caractère large, un entier, une virgule flottante, une valeur booléenne, etc. En fonction du type de données d'une variable, le système d'exploitation alloue de la mémoire et décide de ce qui peut être stocké dans le fichier réservé Mémoire.
Types de données intégrés
Swift 4 offre au programmeur un riche assortiment de types de données intégrés et définis par l'utilisateur. Les types de données de base suivants sont les plus fréquents lors de la déclaration de variables -
Int or UInt- Ceci est utilisé pour les nombres entiers. Plus précisément, vous pouvez utiliser Int32, Int64 pour définir un entier signé 32 ou 64 bits, tandis que UInt32 ou UInt64 pour définir des variables d'entier non signé 32 ou 64 bits. Par exemple, 42 et -23.
Float- Ceci est utilisé pour représenter un nombre à virgule flottante de 32 bits et des nombres avec des points décimaux plus petits. Par exemple, 3.14159, 0.1 et -273.158.
Double- Ceci est utilisé pour représenter un nombre à virgule flottante de 64 bits et utilisé lorsque les valeurs à virgule flottante doivent être très grandes. Par exemple, 3.14159, 0.1 et -273.158.
Bool - Cela représente une valeur booléenne qui est vraie ou fausse.
String- Ceci est une collection ordonnée de caractères. Par exemple, "Hello, World!"
Character- Il s'agit d'une chaîne littérale à un seul caractère. Par exemple, "C"
Optional - Cela représente une variable qui peut contenir une valeur ou aucune valeur.
Tuples - Ceci est utilisé pour regrouper plusieurs valeurs en une seule valeur composée.
Nous avons répertorié ici quelques points importants liés aux types entiers -
Sur une plate-forme 32 bits, Int a la même taille que Int32.
Sur une plate-forme 64 bits, Int a la même taille que Int64.
Sur une plate-forme 32 bits, UInt a la même taille que UInt32.
Sur une plate-forme 64 bits, UInt a la même taille que UInt64.
Int8, Int16, Int32, Int64 peuvent être utilisés pour représenter les formes 8 bits, 16 bits, 32 bits et 64 bits d'entiers signés.
UInt8, UInt16, UInt32 et UInt64 peuvent être utilisés pour représenter les formes 8 bits, 16 bits, 32 bits et 64 bits d'entiers non signés.
Valeurs liées
Le tableau suivant montre le type de variable, la quantité de mémoire nécessaire pour stocker la valeur en mémoire et la valeur maximale et minimale pouvant être stockée dans ce type de variables.
Type | Largeur de bit typique | Gamme typique |
---|---|---|
Int8 | 1 octet | -127 à 127 |
UInt8 | 1 octet | 0 à 255 |
Int32 | 4 octets | -2147483648 à 2147483647 |
UInt32 | 4 octets | 0 à 4294967295 |
Int64 | 8 octets | -9223372036854775808 à 9223372036854775807 |
UInt64 | 8 octets | 0 à 18446744073709551615 |
Flotte | 4 octets | 1.2E-38 à 3.4E + 38 (~ 6 chiffres) |
Double | 8 octets | 2,3E-308 à 1,7E + 308 (~ 15 chiffres) |
Alias de type
Vous pouvez créer un nouveau nom pour un type existant en utilisant typealias. Voici la syntaxe simple pour définir un nouveau type à l'aide de typealias -
typealias newname = type
Par exemple, la ligne suivante indique au compilateur que Feet est un autre nom pour Int -
typealias Feet = Int
Maintenant, la déclaration suivante est parfaitement légale et crée une variable entière appelée distance -
typealias Feet = Int
var distance: Feet = 100
print(distance)
Lorsque nous exécutons le programme ci-dessus en utilisant Playground, nous obtenons le résultat suivant.
100
Sécurité de type
Swift 4 est un langage de type sécurisé, ce qui signifie que si une partie de votre code attend un String, vous ne pouvez pas lui passer un Int par erreur.
Comme Swift 4 est de type sécurisé, il effectue des vérifications de type lors de la compilation de votre code et marque tous les types incompatibles comme des erreurs.
var varA = 42
varA = "This is hello"
print(varA)
Lorsque nous compilons le programme ci-dessus, il produit l'erreur de compilation suivante.
main.swift:2:8: error: cannot assign value of type 'String' to type 'Int'
varA = "This is hello"
Inférence de type
L'inférence de type permet à un compilateur de déduire automatiquement le type d'une expression particulière lorsqu'il compile votre code, simplement en examinant les valeurs que vous fournissez. Swift 4 utilise l'inférence de type pour déterminer le type approprié comme suit.
// varA is inferred to be of type Int
var varA = 42
print(varA)
// varB is inferred to be of type Double
var varB = 3.14159
print(varB)
// varC is also inferred to be of type Double
var varC = 3 + 0.14159
print(varC)
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
42
3.14159
3.14159
Une variable nous fournit un stockage nommé que nos programmes peuvent manipuler. Chaque variable dans Swift 4 a un type spécifique, qui détermine la taille et la disposition de la mémoire de la variable; la plage de valeurs pouvant être stockées dans cette mémoire; et l'ensemble des opérations qui peuvent être appliquées à la variable.
Swift 4 prend en charge les types de variables de base suivants -
Int or UInt- Ceci est utilisé pour les nombres entiers. Plus précisément, vous pouvez utiliser Int32, Int64 pour définir un entier signé 32 ou 64 bits, tandis que UInt32 ou UInt64 pour définir des variables d'entier non signé 32 ou 64 bits. Par exemple, 42 et -23.
Float- Ceci est utilisé pour représenter un nombre à virgule flottante de 32 bits. Il est utilisé pour contenir des nombres avec des points décimaux plus petits. Par exemple, 3.14159, 0.1 et -273.158.
Double- Ceci est utilisé pour représenter un nombre à virgule flottante de 64 bits et utilisé lorsque les valeurs à virgule flottante doivent être très grandes. Par exemple 3.14159, 0.1 et -273.158.
Bool - Cela représente une valeur booléenne qui est vraie ou fausse.
String- Ceci est une collection ordonnée de caractères. Par exemple, "Hello, World!"
Character- Il s'agit d'une chaîne littérale à un seul caractère. Par exemple, "C"
Swift 4 permet également de définir divers autres types de variables, que nous aborderons dans les chapitres suivants, tels que Optional, Array, Dictionaries, Structures, et Classes.
La section suivante explique comment déclarer et utiliser différents types de variables dans la programmation Swift 4.
Déclaration de variable
Une déclaration de variable indique au compilateur où et combien créer le stockage pour la variable. Avant d'utiliser des variables, vous devez les déclarer en utilisantvar mot-clé comme suit -
var variableName = <initial value>
L'exemple suivant montre comment déclarer une variable dans Swift 4 -
var varA = 42
print(varA)
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
42
Annotations de type
Vous pouvez fournir un type annotationlorsque vous déclarez une variable, pour être clair sur le type de valeurs que la variable peut stocker. Voici la syntaxe -
var variableName:<data type> = <optional initial value>
L'exemple suivant montre comment déclarer une variable dans Swift 4 à l'aide d'annotation. Ici, il est important de noter que si nous n'utilisons pas d'annotation de type, il devient alors obligatoire de fournir une valeur initiale pour la variable, sinon nous pouvons simplement déclarer notre variable en utilisant l'annotation de type.
var varA = 42
print(varA)
var varB:Float
varB = 3.14159
print(varB)
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
42
3.1415901184082
Nommer les variables
Le nom d'une variable peut être composé de lettres, de chiffres et du caractère de soulignement. Il doit commencer par une lettre ou un trait de soulignement. Les lettres majuscules et minuscules sont distinctes car Swift 4 est un langage de programmation sensible à la casse.
Vous pouvez utiliser des caractères simples ou Unicode pour nommer vos variables. Les exemples suivants montrent comment vous pouvez nommer les variables -
var _var = "Hello, Swift 4!"
print(_var)
var 你好 = "你好世界"
print(你好)
Lorsque nous exécutons le programme ci-dessus en utilisant Playground, nous obtenons le résultat suivant.
Hello, Swift 4!
你好世界
Variables d'impression
Vous pouvez imprimer la valeur actuelle d'une constante ou d'une variable avec la fonction d'impression. Vous pouvez interpoler une valeur de variable en entourant le nom entre parenthèses et en l'échappant avec une barre oblique inverse avant la parenthèse ouvrante: Voici des exemples valides -
var varA = "Godzilla"
var varB = 1000.00
print("Value of \(varA) is more than \(varB) millions")
Lorsque nous exécutons le programme ci-dessus en utilisant Playground, nous obtenons le résultat suivant.
Value of Godzilla is more than 1000.0 millions
Swift 4 introduit également Optionalstype, qui gère l'absence de valeur. Les options disent soit "il y a une valeur, et elle est égale à x" ou "il n'y a pas de valeur du tout".
Un Optional est un type à part entière, en fait l'un des nouveaux enums super puissants de Swift 4. Il a deux valeurs possibles,None et Some(T), où T est une valeur associée du type de données correct disponible dans Swift 4.
Voici une déclaration facultative Integer -
var perhapsInt: Int?
Voici une déclaration de chaîne facultative -
var perhapsStr: String?
La déclaration ci-dessus équivaut à l'initialiser explicitement à nil ce qui signifie aucune valeur -
var perhapsStr: String? = nil
Prenons l'exemple suivant pour comprendre le fonctionnement des options dans Swift 4 -
var myString:String? = nil
if myString != nil {
print(myString)
} else {
print("myString has nil value")
}
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
myString has nil value
Les options sont similaires à l'utilisation nil avec des pointeurs en Objective-C, mais ils fonctionnent pour n'importe quel type, pas seulement pour les classes.
Déballage forcé
Si vous avez défini une variable comme optional, puis pour obtenir la valeur de cette variable, vous devrez unwrapil. Cela signifie simplement mettre un point d'exclamation à la fin de la variable.
Prenons un exemple simple -
var myString:String?
myString = "Hello, Swift 4!"
if myString != nil {
print(myString)
} else {
print("myString has nil value")
}
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Optional("Hello, Swift 4!")
Maintenant, appliquons le déroulement pour obtenir la valeur correcte de la variable -
var myString:String?
myString = "Hello, Swift 4!"
if myString != nil {
print( myString! )
} else {
print("myString has nil value")
}
Lorsque nous exécutons le programme ci-dessus en utilisant Playground, nous obtenons le résultat suivant.
Hello, Swift 4!
Déballage automatique
Vous pouvez déclarer des variables facultatives en utilisant un point d'exclamation au lieu d'un point d'interrogation. Ces variables optionnelles se dérouleront automatiquement et vous n'avez pas besoin d'utiliser de point d'exclamation supplémentaire à la fin de la variable pour obtenir la valeur attribuée. Prenons un exemple simple -
var myString:String!
myString = "Hello, Swift 4!"
if myString != nil {
print(myString)
} else {
print("myString has nil value")
}
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Hello, Swift 4!
Reliure facultative
Utilisez une liaison facultative pour savoir si un élément facultatif contient une valeur et, le cas échéant, pour rendre cette valeur disponible en tant que constante ou variable temporaire.
Une reliure facultative pour le if la déclaration est la suivante -
if let constantName = someOptional {
statements
}
Prenons un exemple simple pour comprendre l'utilisation de la liaison facultative -
var myString:String?
myString = "Hello, Swift 4!"
if let yourString = myString {
print("Your string has - \(yourString)")
} else {
print("Your string does not have a value")
}
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Your string has - Hello, Swift 4!
Swift 4 introduit également Tuples type, qui sont utilisés pour regrouper plusieurs valeurs dans une seule valeur composée.
Les valeurs d'un tuple peuvent être de n'importe quel type et n'ont pas besoin d'être du même type.
Par exemple, ("Tutorials Point", 123) est un tuple avec deux valeurs, l'une de type chaîne et l'autre de type entier. C'est une commande légale.
let ImplementationError = (501, "Non implémenté") est une erreur lorsque quelque chose sur le serveur n'est pas implémenté, il renvoie deux valeurs. Code d'erreur et description.
Vous pouvez créer des tuples à partir d'autant de valeurs que vous le souhaitez et de n'importe quel nombre de types de données différents.
Voici la syntaxe de la déclaration Tuple -
var TupleName = (Value1, value2,… any number of values)
Voici une déclaration Tuple -
var error501 = (501, “Not implemented”)
Vous pouvez accéder aux valeurs de tuple en utilisant les numéros d'index qui commencent à 0.
Voici un exemple d'accès aux valeurs de tuple -
print(“The code is\(error501.0)”)
print(“The definition of error is\(error501.1)”)
Vous pouvez nommer les variables d'un tuple lors de la déclaration, et vous pouvez les appeler en utilisant leurs noms
var error501 = (errorCode: 501, description: “Not Implemented”)
print(error501.errorCode) // prints 501.
Les tuples sont utiles pour renvoyer plusieurs valeurs à partir d'une fonction. Par exemple, une application Web peut renvoyer un tuple de type ("String", Int) pour indiquer si le chargement a réussi ou échoué.
En renvoyant différentes valeurs dans un tuple, nous pouvons prendre des décisions en fonction de différents types de tuple.
Note - Les tuples sont utiles pour les valeurs temporaires et ne conviennent pas aux données complexes.
Les constantes font référence à des valeurs fixes qu'un programme ne peut pas modifier lors de son exécution. Les constantes peuvent être de l'un des types de données de base comme une constante entière, une constante flottante, une constante de caractère ou une chaîne littérale . Il existe également des constantes d'énumération .
Constants sont traitées comme des variables régulières sauf le fait que leurs valeurs ne peuvent pas être modifiées après leur définition.
Déclaration des constantes
Avant d'utiliser des constantes, vous devez les déclarer en utilisant let mot-clé comme suit -
let constantName = <initial value>
Voici un exemple simple pour montrer comment déclarer une constante dans Swift 4 -
let constA = 42
print(constA)
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
42
Annotations de type
Vous pouvez fournir un type annotationlorsque vous déclarez une constante, pour être clair sur le type de valeurs que la constante peut stocker. Voici la syntaxe -
var constantName:<data type> = <optional initial value>
L'exemple suivant montre comment déclarer une constante dans Swift 4 à l'aide d'annotation. Ici, il est important de noter qu'il est obligatoire de fournir une valeur initiale lors de la création d'une constante -
let constA = 42
print(constA)
let constB:Float = 3.14159
print(constB)
Lorsque nous exécutons le programme ci-dessus en utilisant Playground, nous obtenons le résultat suivant.
42
3.1415901184082
Nommer les constantes
Le nom d'une constante peut être composé de lettres, de chiffres et du caractère de soulignement. Il doit commencer par une lettre ou un trait de soulignement. Les lettres majuscules et minuscules sont distinctes car Swift 4 est un langage de programmation sensible à la casse.
Vous pouvez utiliser des caractères simples ou Unicode pour nommer vos variables. Voici des exemples valables -
let _const = "Hello, Swift 4!"
print(_const)
let 你好 = "你好世界"
print(你好)
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Hello, Swift 4!
你好世界
Constantes d'impression
Vous pouvez imprimer la valeur actuelle d'une constante ou d'une variable en utilisant printfonction. Vous pouvez interpoler une valeur de variable en entourant le nom entre parenthèses et en l'échappant avec une barre oblique inverse avant la parenthèse ouvrante: Voici des exemples valides -
let constA = "Godzilla"
let constB = 1000.00
print("Value of \(constA) is more than \(constB) millions")
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Value of Godzilla is more than 1000.0 millions
Un littéral est la représentation dans le code source d'une valeur d'un entier, d'un nombre à virgule flottante ou d'un type de chaîne. Voici des exemples de littéraux -
42 // Integer literal
3.14159 // Floating-point literal
"Hello, world!" // String literal
Littéraux entiers
Un littéral entier peut être une constante décimale, binaire, octale ou hexadécimale. Les littéraux binaires commencent par 0b, les littéraux octaux commencent par 0o et les littéraux hexadécimaux commencent par 0x et rien pour les nombres décimaux.
Voici quelques exemples de littéraux entiers -
let decimalInteger = 17 // 17 in decimal notation
let binaryInteger = 0b10001 // 17 in binary notation
let octalInteger = 0o21 // 17 in octal notation
let hexadecimalInteger = 0x11 // 17 in hexadecimal notation
Littéraux à virgule flottante
Un littéral à virgule flottante a une partie entière, une virgule décimale, une partie fractionnaire et une partie exposant. Vous pouvez représenter des littéraux à virgule flottante sous forme décimale ou hexadécimale.
Les littéraux décimaux à virgule flottante se composent d'une séquence de chiffres décimaux suivis d'une fraction décimale, d'un exposant décimal ou des deux.
Les littéraux hexadécimaux à virgule flottante sont constitués d'un préfixe 0x, suivi d'une fraction hexadécimale facultative, suivie d'un exposant hexadécimal.
Voici quelques exemples de littéraux à virgule flottante -
let decimalDouble = 12.1875
let exponentDouble = 1.21875e1
let hexadecimalDouble = 0xC.3p0
Littéraux de chaîne
Un littéral de chaîne est une séquence de caractères entourés de guillemets doubles, avec la forme suivante -
"characters"
Les littéraux de chaîne ne peuvent pas contenir de guillemets doubles sans échappement ("), de barre oblique inverse (\), de retour chariot ou de saut de ligne. Des caractères spéciaux peuvent être inclus dans les littéraux de chaîne à l'aide des séquences d'échappement suivantes:
Séquence d'échappement | Sens |
---|---|
\ 0 | Caractère nul |
\\ | \personnage |
\ b | Retour arrière |
\F | Saut de formulaire |
\ n | Nouvelle ligne |
\ r | Retour chariot |
\ t | Onglet horizontal |
\ v | Onglet vertical |
\ ' | Simple citation |
\ " | Double citation |
\ 000 | Numéro octal de un à trois chiffres |
\ xhh ... | Nombre hexadécimal d'un ou plusieurs chiffres |
L'exemple suivant montre comment utiliser quelques littéraux de chaîne -
let stringL = "Hello\tWorld\n\nHello\'Swift 4\'"
print(stringL)
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Hello World
Hello'Swift 4'
Littéraux booléens
Il existe trois littéraux booléens et ils font partie des mots-clés standard de Swift 4 -
Une valeur de true représentant vrai.
Une valeur de false représentant faux.
Une valeur de nil ne représentant aucune valeur.
Un opérateur est un symbole qui indique au compilateur d'effectuer des manipulations mathématiques ou logiques spécifiques. Objective-C est riche en opérateurs intégrés et fournit les types d'opérateurs suivants -
- Opérateurs arithmétiques
- Opérateurs de comparaison
- Opérateurs logiques
- Opérateurs au niveau du bit
- Opérateurs d'affectation
- Opérateurs de gamme
- Opérateurs divers
Ce tutoriel expliquera les opérateurs arithmétique, relationnel, logique, bit à bit, d'affectation et autres un par un.
Opérateurs arithmétiques
Le tableau suivant montre tous les opérateurs arithmétiques pris en charge par le langage Swift 4. Supposons une variableA détient 10 et variable B détient 20, alors -
Opérateur | La description | Exemple |
---|---|---|
+ | Ajoute deux opérandes | A + B donnera 30 |
- | Soustrait le deuxième opérande du premier | A - B donnera -10 |
* | Multiplie les deux opérandes | A * B donnera 200 |
/ | Divise le numérateur par le dénominateur | B / A donnera 2 |
% | Opérateur de module et reste après une division entière / flottante | B% A donnera 0 |
Opérateurs de comparaison
Le tableau suivant présente tous les opérateurs relationnels pris en charge par le langage Swift 4. Supposons une variableA détient 10 et variable B détient 20, alors -
Opérateur | La description | Exemple |
---|---|---|
== | Vérifie si les valeurs de deux opérandes sont égales ou non; si oui, alors la condition devient vraie. | (A == B) n'est pas vrai. |
! = | Vérifie si les valeurs de deux opérandes sont égales ou non; si les valeurs ne sont pas égales, la condition devient vraie. | (A! = B) est vrai. |
> | Vérifie si la valeur de l'opérande gauche est supérieure à la valeur de l'opérande droit; si oui, alors la condition devient vraie. | (A> B) n'est pas vrai. |
< | Vérifie si la valeur de l'opérande gauche est inférieure à la valeur de l'opérande droit; si oui, alors la condition devient vraie. | (A <B) est vrai. |
> = | Vérifie si la valeur de l'opérande gauche est supérieure ou égale à la valeur de l'opérande droit; si oui, alors la condition devient vraie. | (A> = B) n'est pas vrai. |
<= | Vérifie si la valeur de l'opérande gauche est inférieure ou égale à la valeur de l'opérande droit; si oui, alors la condition devient vraie. | (A <= B) est vrai. |
Opérateurs logiques
Le tableau suivant présente tous les opérateurs logiques pris en charge par le langage Swift 4. Supposons une variableA contient 1 et variable B détient 0, alors -
Opérateur | La description | Exemple |
---|---|---|
&& | Opérateur logique ET appelé. Si les deux opérandes sont différents de zéro, la condition devient vraie. | (A && B) est faux. |
|| | Opérateur OU logique appelé. Si l'un des deux opérandes est différent de zéro, la condition devient vraie. | (A || B) est vrai. |
! | Opérateur PAS logique appelé. Utilisez pour inverser l'état logique de son opérande. Si une condition est vraie, alors l'opérateur logique NOT la rendra fausse. | ! (A && B) est vrai. |
Opérateurs au niveau du bit
Les opérateurs au niveau du bit travaillent sur des bits et exécutent des opérations bit par bit. Les tables de vérité pour &, | et ^ sont les suivantes:
p | q | p & q | p | q | p ^ q |
---|---|---|---|---|
0 | 0 | 0 | 0 | 0 |
0 | 1 | 0 | 1 | 1 |
1 | 1 | 1 | 1 | 0 |
1 | 0 | 0 | 1 | 1 |
Assume A = 60; and B = 13;
In binary format, they will be as follows:
A = 0011 1100
B = 0000 1101
-----------------
A & B = 0000 1100
A|B = 0011 1101
A^B = 0011 0001
~A = 1100 0011
Les opérateurs binaires pris en charge par le langage Swift 4 sont répertoriés dans le tableau suivant. Supposons une variableA détient 60 et variable B détient 13, puis 7−
Opérateur | La description | Exemple |
---|---|---|
& | L'opérateur binaire AND copie un peu le résultat, s'il existe dans les deux opérandes. | (A & B) donnera 12, soit 0000 1100 |
| | L'opérateur OR binaire copie un bit, s'il existe dans l'un ou l'autre des opérandes. | (A | B) donnera 61, soit 0011 1101 |
^ | L'opérateur XOR binaire copie le bit s'il est défini dans un opérande mais pas dans les deux. | (A ^ B) donnera 49, soit 0011 0001 |
~ | L'opérateur de complément Binary Ones est unaire et a pour effet de «retourner» les bits. | (~ A) donnera -61, qui est de 1100 0011 sous la forme du complément à 2. |
<< | Opérateur de décalage binaire gauche. La valeur des opérandes de gauche est déplacée vers la gauche du nombre de bits spécifié par l'opérande de droite. | (A << 2 donnera 240, soit 1111 0000 |
>> | Opérateur de décalage binaire vers la droite. La valeur des opérandes de gauche est déplacée vers la droite du nombre de bits spécifié par l'opérande de droite. | Un >> 2 donnera 15, soit 0000 1111 |
Opérateurs d'affectation
SSwift 4 prend en charge les opérateurs d'affectation suivants -
Opérateur | La description | Exemple |
---|---|---|
= | Opérateur d'affectation simple, attribue des valeurs d'opérandes de droite à l'opérande de gauche | C = A + B attribuera la valeur de A + B à C |
+ = | Ajouter l'opérateur d'affectation AND, il ajoute l'opérande droit à l'opérande gauche et affecte le résultat à l'opérande gauche | C + = A équivaut à C = C + A |
- = | Soustraire l'opérateur d'affectation ET, il soustrait l'opérande droit de l'opérande gauche et attribue le résultat à l'opérande gauche | C - = A équivaut à C = C - A |
* = | Multiplier l'opérateur d'affectation ET, il multiplie l'opérande droit par l'opérande gauche et affecte le résultat à l'opérande gauche | C * = A équivaut à C = C * A |
/ = | Opérateur d'affectation de division ET, il divise l'opérande gauche avec l'opérande droit et affecte le résultat à l'opérande gauche | C / = A équivaut à C = C / A |
% = | Opérateur d'assignation de module ET, il prend le module en utilisant deux opérandes et affecte le résultat à l'opérande de gauche | C% = A équivaut à C = C% A |
<< = | Opérateur de décalage ET d'affectation à gauche | C << = 2 est identique à C = C << 2 |
>> = | Opérateur de décalage ET d'affectation à droite | C >> = 2 est identique à C = C >> 2 |
& = | Opérateur d'affectation AND au niveau du bit | C & = 2 est identique à C = C & 2 |
^ = | OU exclusif au niveau du bit et opérateur d'affectation | C ^ = 2 est identique à C = C ^ 2 |
| = | OR inclusif au niveau du bit et opérateur d'affectation | C | = 2 est identique à C = C | 2 |
Opérateurs de gamme
Swift 4 comprend deux opérateurs de plage, qui sont des raccourcis pour exprimer une plage de valeurs. Le tableau suivant explique ces deux opérateurs.
Opérateur | La description | Exemple |
---|---|---|
Gamme fermée | (a ... b) définit une plage qui va de a à b et inclut les valeurs a et b. | 1 ... 5 donne 1, 2, 3, 4 et 5 |
Gamme semi-ouverte | (a .. <b) définit une plage qui va de a à b, mais n'inclut pas b. | 1 .. <5 donne 1, 2, 3 et 4 |
Gamme unilatérale | a…, définit une plage qui va de a à la fin des éléments … A, définit une plage allant du début à un |
1… donne 1, 2,3… fin des éléments … 2 donne le début… à 1,2 |
Opérateurs divers
Swift 4 prend en charge quelques autres opérateurs importants, notamment rangeet ? : qui sont expliquées dans le tableau suivant.
Opérateur | La description | Exemple |
---|---|---|
Moins unaire | Le signe d'une valeur numérique peut être basculé en utilisant un préfixe - | -3 ou -4 |
Unaire Plus | Renvoie la valeur sur laquelle il opère, sans aucune modification. | +6 donne 6 |
Conditionnel ternaire | État ? X: Y | Si la condition est vraie? Alors valeur X: Sinon valeur Y |
Priorité des opérateurs
La priorité des opérateurs détermine le regroupement des termes dans une expression. Cela affecte la manière dont une expression est évaluée. Certains opérateurs ont une priorité plus élevée que d'autres; par exemple, l'opérateur de multiplication a une priorité plus élevée que l'opérateur d'addition.
Par exemple, x = 7 + 3 * 2; ici, x est attribué à 13, et non à 20 car l'opérateur * a une priorité plus élevée que +, il est donc d'abord multiplié par 3 * 2, puis ajouté en 7.
Ici, les opérateurs avec la priorité la plus élevée apparaissent en haut du tableau, ceux avec la priorité la plus basse apparaissent en bas. Dans une expression, les opérateurs de priorité supérieure seront évalués en premier.
Opérateur | La description | Exemple |
---|---|---|
Opérateurs d'expression primaires | () []. expr ++ expr-- | de gauche à droite |
Opérateurs unaires | * & + -! ~ ++ expr --expr * /% + - >> << <> <=> = ==! = |
de droite à gauche |
Opérateurs binaires | & ^ | && || |
de gauche à droite |
Opérateur ternaire | ?: | de droite à gauche |
Opérateurs d'affectation | = + = - = * = / =% = >> = << = & = ^ = | = | de droite à gauche |
Virgule | , | de gauche à droite |
Les structures de prise de décision exigent que le programmeur spécifie une ou plusieurs conditions à évaluer ou à tester par le programme, ainsi qu'une ou plusieurs instructions à exécuter si la condition est déterminée comme étant true, et éventuellement d'autres instructions à exécuter si la condition est déterminée false.
Voici le général d'une structure de prise de décision typique trouvée dans la plupart des langages de programmation -
Swift 4 fournit les types suivants d'énoncés de prise de décision. Cliquez sur les liens suivants pour vérifier leurs détails.
Sr.Non | Déclaration et description |
---|---|
1 | si déclaration Une instruction if consiste en une expression booléenne suivie d'une ou plusieurs instructions. |
2 | instruction if ... else Une instruction if peut être suivie d'une instruction else facultative, qui s'exécute lorsque l'expression booléenne est fausse. |
3 | if ... else if ... else Déclaration Une instruction if peut être suivie d'une instruction else if ... else facultative, ce qui est très utile pour tester diverses conditions en utilisant une instruction if ... else if unique. |
4 | instructions if imbriquées Vous pouvez utiliser une instruction if ou else if dans une autre instruction if ou else if. |
5 | instruction switch Une instruction switch permet de tester l'égalité d'une variable par rapport à une liste de valeurs. |
Le ? : Opérateur
Nous avons couvert conditional operator ? : dans le chapitre précédent qui peut être utilisé pour remplacer if...elsedéclarations. Il a la forme générale suivante -
Exp1 ? Exp2 : Exp3;
Où Exp1, Exp2 et Exp3 sont des expressions. Notez l'utilisation et le placement des deux points.
La valeur d'un? expression est déterminée comme ceci: Exp1 est évalué. Si c'est vrai, alors Exp2 est évalué et devient la valeur de l'ensemble? expression. Si Exp1 est faux, Exp3 est évalué et sa valeur devient la valeur de l'expression.
Il peut arriver que vous deviez exécuter un bloc de code plusieurs fois. En général, les instructions sont exécutées de manière séquentielle: la première instruction d'une fonction est exécutée en premier, suivie de la seconde, et ainsi de suite.
Les langages de programmation fournissent diverses structures de contrôle qui permettent des chemins d'exécution plus compliqués.
Une instruction de boucle nous permet d'exécuter une instruction ou un groupe d'instructions plusieurs fois. Voici le général d'une instruction de boucle dans la plupart des langages de programmation -
Le langage de programmation Swift 4 fournit les types de boucle suivants pour gérer les exigences de bouclage. Cliquez sur les liens suivants pour vérifier leurs détails.
Sr.Non | Type de boucle et description |
---|---|
1 | for-in Cette boucle exécute un ensemble d'instructions pour chaque élément d'une plage, d'une séquence, d'une collection ou d'une progression. |
2 | boucle while Répète une instruction ou un groupe d'instructions tant qu'une condition donnée est vraie. Il teste la condition avant d'exécuter le corps de la boucle. |
3 | répéter ... tout en boucle Comme une instruction while, sauf qu'elle teste la condition à la fin du corps de la boucle. |
Déclarations de contrôle de boucle
Les instructions de contrôle de boucle modifient l'exécution de sa séquence normale. Lorsque l'exécution quitte une étendue, tous les objets automatiques qui ont été créés dans cette étendue sont détruits.
Swift 4 prend en charge les instructions de contrôle suivantes. Cliquez sur les liens suivants pour vérifier leurs détails.
Sr.Non | Déclaration de contrôle et description |
---|---|
1 | continue déclaration Cette instruction indique à une boucle d'arrêter ce qu'elle est en train de faire et de recommencer au début de l'itération suivante dans la boucle. |
2 | déclaration break Termine l'instruction de boucle et transfère l'exécution à l'instruction immédiatement après la boucle. |
3 | déclaration de chute L'instruction fallthrough simule le comportement du commutateur Swift 4 en commutateur de style C. |
Les chaînes de Swift 4 sont une collection ordonnée de caractères, comme "Hello, World!" et ils sont représentés par le type de données Swift 4String, qui à son tour représente un ensemble de valeurs de Character type.
Créer une chaîne
Vous pouvez créer une chaîne en utilisant une chaîne littérale ou en créant une instance d'une classe String comme suit -
// String creation using String literal
var stringA = "Hello, Swift 4!"
print( stringA )
// String creation using String instance
var stringB = String("Hello, Swift 4!")
print( stringB )
//Multiple line string
let stringC = """
Hey this is a
example of multiple Line
string by tutorialsPoint
"""
print(stringC)
Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant
Hello, Swift 4!
Hello, Swift 4!
Hey this is a
example of multiple Line
string by tutorialsPoint
Chaîne vide
Vous pouvez créer une chaîne vide en utilisant une chaîne littérale vide ou en créant une instance de la classe String comme indiqué ci-dessous. Vous pouvez également vérifier si une chaîne est vide ou non en utilisant la propriété BooleanisEmpty.
// Empty string creation using String literal
var stringA = ""
if stringA.isEmpty {
print( "stringA is empty" )
} else {
print( "stringA is not empty" )
}
// Empty string creation using String instance
let stringB = String()
if stringB.isEmpty {
print( "stringB is empty" )
} else {
print( "stringB is not empty" )
}
Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -
stringA is empty
stringB is empty
Constantes de chaîne
Vous pouvez spécifier si votre chaîne peut être modifiée (ou mutée) en l'affectant à une variable, ou elle sera constante en l'affectant à une constante en utilisant let mot-clé comme indiqué ci-dessous -
// stringA can be modified
var stringA = "Hello, Swift 4!"
stringA + = "--Readers--"
print( stringA )
// stringB can not be modified
let stringB = String("Hello, Swift 4!")
stringB + = "--Readers--"
print( stringB )
Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -
Playground execution failed: error: <EXPR>:10:1: error: 'String' is not
convertible to '@lvalue UInt8'
stringB + = "--Readers--"
Interpolation de chaîne
L'interpolation de chaîne est un moyen de construire une nouvelle valeur String à partir d'un mélange de constantes, de variables, de littéraux et d'expressions en incluant leurs valeurs dans un littéral de chaîne.
Chaque élément (variable ou constante) que vous insérez dans le littéral de chaîne est entouré d'une paire de parenthèses, précédé d'une barre oblique inverse. Voici un exemple simple -
var varA = 20
let constA = 100
var varC:Float = 20.0
var stringA = "\(varA) times \(constA) is equal to \(varC * 100)"
print( stringA )
Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -
20 times 100 is equal to 2000.0
Concaténation de chaînes
Vous pouvez utiliser l'opérateur + pour concaténer deux chaînes ou une chaîne et un caractère, ou deux caractères. Voici un exemple simple -
let constA = "Hello,"
let constB = "World!"
var stringA = constA + constB
print( stringA )
Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -
Hello,World!
Longueur de chaine
Les cordes Swift 4 n'ont pas de lengthpropriété, mais vous pouvez utiliser la fonction global count () pour compter le nombre de caractères dans une chaîne. Voici un exemple simple -
var varA = "Hello, Swift 4!"
print( "\(varA), length is \((varA.count))" )
Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -
Hello, Swift 4!, length is 15
Comparaison des chaînes
Vous pouvez utiliser l'opérateur == pour comparer deux variables ou constantes de chaînes. Voici un exemple simple -
var varA = "Hello, Swift 4!"
var varB = "Hello, World!"
if varA == varB {
print( "\(varA) and \(varB) are equal" )
} else {
print( "\(varA) and \(varB) are not equal" )
}
Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -
Hello, Swift 4! and Hello, World! are not equal
Itération de chaîne
Les chaînes sont à nouveau une collection de valeurs dans swift 4, nous pouvons donc itérer sur une chaîne en utilisant des boucles. -
for chars in "ThisString" {
print(chars, terminator: " ")
}
Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -
T h i s S t r i n g
Chaînes Unicode
Vous pouvez accéder à une représentation UTF-8 et UTF-16 d'une chaîne en itérant sur ses propriétés utf8 et utf16 comme illustré dans l'exemple suivant -
var unicodeString = "Dog???"
print("UTF-8 Codes: ")
for code in unicodeString.utf8 {
print("\(code) ")
}
print("\n")
print("UTF-16 Codes: ")
for code in unicodeString.utf16 {
print("\(code) ")
}
Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -
UTF-8 Codes:
68
111
103
63
63
63
UTF-16 Codes:
68
111
103
63
63
63
Fonctions et opérateurs de chaîne
Swift 4 prend en charge un large éventail de méthodes et d'opérateurs liés aux chaînes -
Sr.Non | Fonctions / opérateurs et objectif |
---|---|
1 | isEmpty Valeur booléenne qui détermine si une chaîne est vide ou non. |
2 | hasPrefix(prefix: String) Fonction pour vérifier si une chaîne de paramètres donnée existe ou non en tant que préfixe de la chaîne. |
3 | hasSuffix(suffix: String) Fonction pour vérifier si une chaîne de paramètres donnée existe ou non en tant que suffixe de la chaîne. |
4 | toInt() Fonction pour convertir la valeur de chaîne numérique en nombre entier. |
5 | count() Fonction globale pour compter le nombre de caractères dans une chaîne. |
6 | utf8 Propriété pour renvoyer une représentation UTF-8 d'une chaîne. |
sept | utf16 Propriété pour renvoyer une représentation UTF-16 d'une chaîne. |
8 | unicodeScalars Propriété pour renvoyer une représentation Unicode Scalar d'une chaîne. |
9 | + Opérateur pour concaténer deux chaînes, ou une chaîne et un caractère, ou deux caractères. |
dix | += Opérateur pour ajouter une chaîne ou un caractère à une chaîne existante. |
11 | == Opérateur pour déterminer l'égalité de deux chaînes. |
12 | < Opérateur pour effectuer une comparaison lexicographique pour déterminer si une chaîne est évaluée comme inférieure à une autre. |
13 | startIndex Pour obtenir la valeur au début de l'index de la chaîne. |
14 | endIndex Pour obtenir la valeur à la fin de l'index de la chaîne. |
15 | Indices Pour accéder aux indéces une à une. c'est à dire tous les caractères de la chaîne un par un. |
16 | insert("Value", at: position) Pour insérer une valeur à une position. |
17 | remove(at: position) removeSubrange(range) pour supprimer une valeur à une position ou pour supprimer une plage de valeurs d'une chaîne. |
18 | reversed() renvoie l'inverse d'une chaîne |
UNE character dans Swift est un littéral de chaîne à un seul caractère, adressé par le type de données Character. Jetez un œil à l'exemple suivant. Il utilise deux constantes de caractère -
let char1: Character = "A"
let char2: Character = "B"
print("Value of char1 \(char1)")
print("Value of char2 \(char2)")
Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -
Value of char1 A
Value of char2 B
Si vous essayez de stocker plus d'un caractère dans une variable ou une constante de type Caractère, Swift 4 ne le permettra pas. Essayez de taper l'exemple suivant dans Swift 4 Playground et vous obtiendrez une erreur avant même la compilation.
// Following is wrong in Swift 4
let char: Character = "AB"
print("Value of char \(char)")
Variables de caractères vides
Il n'est pas possible de créer une variable ou une constante Caractère vide qui aura une valeur vide. La syntaxe suivante n'est pas possible -
// Following is wrong in Swift 4
let char1: Character = ""
var char2: Character = ""
print("Value of char1 \(char1)")
print("Value of char2 \(char2)")
Accès aux caractères à partir de chaînes
Comme expliqué lors de la discussion sur les chaînes de Swift 4, String représente une collection de valeurs Character dans un ordre spécifié. Nous pouvons donc accéder aux caractères individuels de la chaîne donnée en itérant sur cette chaîne avec unfor-in boucle -
for ch in "Hello" {
print(ch)
}
Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -
H
e
l
l
o
Concaténation de chaînes avec des caractères
L'exemple suivant montre comment un personnage de Swift 4 peut être concaténé avec la chaîne de Swift 4.
var varA:String = "Hello "
let varB:Character = "G"
varA.append( varB )
print("Value of varC = \(varA)")
Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -
Value of varC = Hello G
Les tableaux Swift 4 sont utilisés pour stocker des listes ordonnées de valeurs du même type. Swift 4 met une vérification stricte qui ne vous permet pas de saisir un mauvais type dans un tableau, même par erreur.
Si vous affectez un tableau créé à une variable, il est toujours modifiable, ce qui signifie que vous pouvez le modifier en ajoutant, supprimant ou modifiant ses éléments; mais si vous assignez un tableau à une constante, ce tableau est immuable et sa taille et son contenu ne peuvent pas être modifiés.
Création de tableaux
Vous pouvez créer un tableau vide d'un certain type en utilisant la syntaxe d'initialisation suivante -
var someArray = [SomeType]()
Voici la syntaxe pour créer un tableau d'une taille donnée a * et l'initialiser avec une valeur -
var someArray = [SomeType](count: NumbeOfElements, repeatedValue: InitialValue)
Vous pouvez utiliser l'instruction suivante pour créer un tableau vide de Int type ayant 3 éléments et la valeur initiale égale à zéro -
var someInts = [Int](count: 3, repeatedValue: 0)
Voici un autre exemple pour créer un tableau de trois éléments et attribuer trois valeurs à ce tableau -
var someInts:[Int] = [10, 20, 30]
Accès aux baies
Vous pouvez récupérer une valeur d'un tableau en utilisant subscript syntaxe, en passant l'index de la valeur que vous souhaitez récupérer entre crochets immédiatement après le nom du tableau comme suit -
var someVar = someArray[index]
Ici le indexcommence à 0, ce qui signifie que le premier élément est accessible en utilisant l'index 0, le deuxième élément est accessible en utilisant l'index 1 et ainsi de suite. L'exemple suivant montre comment créer, initialiser et accéder à des tableaux -
var someInts = [Int](count: 3, repeatedValue: 10)
var someVar = someInts[0]
print( "Value of first element is \(someVar)" )
print( "Value of second element is \(someInts[1])" )
print( "Value of third element is \(someInts[2])" )
Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -
Value of first element is 10
Value of second element is 10
Value of third element is 10
Modification des tableaux
Vous pouvez utiliser append()méthode ou opérateur d'affectation d'addition (+ =) pour ajouter un nouvel élément à la fin d'un tableau. Jetez un œil à l'exemple suivant. Ici, au départ, nous créons un tableau vide puis ajoutons de nouveaux éléments dans le même tableau -
var someInts = [Int]()
someInts.append(20)
someInts.append(30)
someInts += [40]
var someVar = someInts[0]
print( "Value of first element is \(someVar)" )
print( "Value of second element is \(someInts[1])" )
print( "Value of third element is \(someInts[2])" )
Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -
Value of first element is 20
Value of second element is 30
Value of third element is 40
Vous pouvez modifier un élément existant d'un tableau en attribuant une nouvelle valeur à un index donné, comme indiqué dans l'exemple suivant -
var someInts = [Int]()
someInts.append(20)
someInts.append(30)
someInts += [40]
// Modify last element
someInts[2] = 50
var someVar = someInts[0]
print( "Value of first element is \(someVar)" )
print( "Value of second element is \(someInts[1])" )
print( "Value of third element is \(someInts[2])" )
Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -
Value of first element is 20
Value of second element is 30
Value of third element is 50
Itération sur un tableau
Vous pouvez utiliser for-in boucle pour parcourir l'ensemble des valeurs d'un tableau, comme indiqué dans l'exemple suivant -
var someStrs = [String]()
someStrs.append("Apple")
someStrs.append("Amazon")
someStrs += ["Google"]
for item in someStrs {
print(item)
}
Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -
Apple
Amazon
Google
Vous pouvez utiliser enumerate() fonction qui renvoie l'index d'un élément avec sa valeur comme indiqué ci-dessous dans l'exemple suivant -
var someStrs = [String]()
someStrs.append("Apple")
someStrs.append("Amazon")
someStrs += ["Google"]
for (index, item) in someStrs.enumerated() {
print("Value at index = \(index) is \(item)")
}
Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -
Value at index = 0 is Apple
Value at index = 1 is Amazon
Value at index = 2 is Google
Ajout de deux tableaux
Vous pouvez utiliser l'opérateur d'addition (+) pour ajouter deux tableaux du même type qui produiront un nouveau tableau avec une combinaison de valeurs des deux tableaux comme suit -
var intsA = [Int](count:2, repeatedValue: 2)
var intsB = [Int](count:3, repeatedValue: 1)
var intsC = intsA + intsB
for item in intsC {
print(item)
}
Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -
2
2
1
1
1
La propriété count
Vous pouvez utiliser la lecture seule count propriété d'un tableau pour connaître le nombre d'éléments dans un tableau ci-dessous -
var intsA = [Int](count:2, repeatedValue: 2)
var intsB = [Int](count:3, repeatedValue: 1)
var intsC = intsA + intsB
print("Total items in intsA = \(intsA.count)")
print("Total items in intsB = \(intsB.count)")
print("Total items in intsC = \(intsC.count)")
Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -
Total items in intsA = 2
Total items in intsB = 3
Total items in intsC = 5
La propriété vide
Vous pouvez utiliser la lecture seule empty propriété d'un tableau pour savoir si un tableau est vide ou non comme indiqué ci-dessous -
var intsA = [Int](count:2, repeatedValue: 2)
var intsB = [Int](count:3, repeatedValue: 1)
var intsC = [Int]()
print("intsA.isEmpty = \(intsA.isEmpty)")
print("intsB.isEmpty = \(intsB.isEmpty)")
print("intsC.isEmpty = \(intsC.isEmpty)")
Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -
intsA.isEmpty = false
intsB.isEmpty = false
intsC.isEmpty = true
Swift 4 sets sont utilisés pour stocker des valeurs distinctes des mêmes types mais ils n'ont pas de classement défini comme les tableaux.
Vous pouvez utiliser des ensembles au lieu de tableaux si l'ordre des éléments ne pose pas de problème ou si vous souhaitez vous assurer qu'il n'y a pas de valeurs en double. (les ensembles n'autorisent que des valeurs distinctes.)
Un type doit être hachable pour être stocké dans un ensemble. Une valeur de hachage est une valeur Int égale pour des objets égaux. Par exemple, si x == y, alorsx.hashvalue == y.hashvalue.
Toutes les valeurs swift de base sont de type hachables par défaut et peuvent être utilisées comme valeurs définies.
Créer des ensembles
Vous pouvez créer un ensemble vide d'un certain type en utilisant la syntaxe d'initialisation suivante -
var someSet = Set<Character>() //Character can be replaced by data type of set.
Accès et modification des sets
Vous pouvez accéder ou modifier un ensemble en utilisant ses méthodes et propriétés -
La méthode "count" peut être utilisée pour afficher le nombre d'éléments dans l'ensemble.
someSet.count // prints the number of elements
La méthode "insert" peut être utilisée pour insérer des valeurs dans l'ensemble.
someSet.insert("c") // adds the element to Set.
De même, isEmpty peut être utilisé pour vérifier si set est vide.
someSet.isEmpty // returns true or false depending on the set Elements.
La méthode "remove" peut être utilisée pour supprimer une valeur dans l'ensemble.
someSet.remove("c") // removes a element , removeAll() can be used to remove all elements
La méthode "contient" peut être utilisée pour vérifier l'existence d'une valeur dans un ensemble.
someSet.contains("c") // to check if set contains this value.
Itérer sur un ensemble
Vous pouvez parcourir un ensemble en utilisant la boucle for-in -
for items in someSet {
print(someSet)
}
//Swift sets are not in an ordered way, to iterate over a set in ordered way use
for items in someSet.sorted() {
print(someSet)
}
Exécution des opérations de set
Vous pouvez effectuer des opérations de set de base sur les sets Swift.
Voici les méthodes pour effectuer les opérations de réglage -
- Intersection
- Union
- subtracting
let evens: Set = [10,12,14,16,18]
let odds: Set = [5,7,9,11,13]
let primes = [2,3,5,7]
odds.union(evens).sorted()
// [5,7,9,10,11,12,13,14,16,18]
odds.intersection(evens).sorted()
//[]
odds.subtracting(primes).sorted()
//[9, 11, 13]
Swift 4 dictionariessont utilisés pour stocker des listes non ordonnées de valeurs du même type. Swift 4 met une vérification stricte qui ne vous permet pas de saisir un mauvais type dans un dictionnaire, même par erreur.
Les dictionnaires Swift 4 utilisent un identifiant unique appelé keypour stocker une valeur qui plus tard peut être référencée et recherchée via la même clé. Contrairement aux éléments d'un tableau, les éléments d'undictionaryn'ont pas d'ordre spécifié. Vous pouvez utiliser undictionary lorsque vous devez rechercher des valeurs en fonction de leurs identifiants.
Une clé de dictionnaire peut être un entier ou une chaîne sans restriction, mais elle doit être unique dans un dictionnaire.
Si vous affectez un dictionnaire créé à une variable, il est toujours modifiable, ce qui signifie que vous pouvez le modifier en ajoutant, supprimant ou modifiant ses éléments. Mais si vous affectez un dictionnaire à une constante, ce dictionnaire est immuable et sa taille et son contenu ne peuvent pas être modifiés.
Création d'un dictionnaire
Vous pouvez créer un dictionnaire vide d'un certain type en utilisant la syntaxe d'initialisation suivante -
var someDict = [KeyType: ValueType]()
Vous pouvez utiliser la syntaxe simple suivante pour créer un dictionnaire vide dont la clé sera de type Int et les valeurs associées seront des chaînes -
var someDict = [Int: String]()
Voici un exemple pour créer un dictionnaire à partir d'un ensemble de valeurs données -
var someDict:[Int:String] = [1:"One", 2:"Two", 3:"Three"]
Initialisation basée sur la séquence
Swift 4 vous permet de créer un dictionnaire à partir de tableaux (paires clé-valeur).
var cities = [“Delhi”,”Bangalore”,”Hyderabad”]
Vous pouvez utiliser la syntaxe simple suivante pour créer un dictionnaire vide dont la clé sera de type Int et les valeurs associées seront des chaînes -
var Distance = [2000,10, 620]
Voici un exemple pour créer un dictionnaire à partir d'un ensemble de valeurs données -
let cityDistanceDict = Dictionary(uniqueKeysWithValues: zip(cities, Distance))
Les lignes de code ci-dessus créeront un dictionnaire avec les villes comme clé et la distance comme valeur -
Filtration
Swift 4 vous permet de filtrer les valeurs d'un dictionnaire.
var closeCities = cityDistanceDict.filter { $0.value < 1000 }
Si nous exécutons le code ci-dessus, notre dictionnaire closeCities sera.
["Bangalore" : 10 , "Hyderabad" : 620]
Regroupement de dictionnaires
Swift 4 vous permet de créer un regroupement de valeurs de dictionnaire.
var cities = ["Delhi","Bangalore","Hyderabad","Dehradun","Bihar"]
Vous pouvez utiliser la syntaxe simple suivante pour regrouper les valeurs du dictionnaire en fonction du premier alphabet.
var GroupedCities = Dictionary(grouping: cities ) { $0.first! }
Le résultat du code ci-dessus sera
["D" :["Delhi","Dehradun"], "B" : ["Bengaluru","Bihar"], "H" : ["Hyderabad"]]
Accéder aux dictionnaires
Vous pouvez récupérer une valeur d'un dictionnaire en utilisant la syntaxe d'indice, en passant la clé de la valeur que vous souhaitez récupérer entre crochets immédiatement après le nom du dictionnaire comme suit -
var someVar = someDict[key]
Vérifions l'exemple suivant pour créer, initialiser et accéder aux valeurs d'un dictionnaire -
var someDict:[Int:String] = [1:"One", 2:"Two", 3:"Three"]
var someVar = someDict[1]
print( "Value of key = 1 is \(someVar)" )
print( "Value of key = 2 is \(someDict[2])" )
print( "Value of key = 3 is \(someDict[3])" )
Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -
Value of key = 1 is Optional("One")
Value of key = 2 is Optional("Two")
Value of key = 3 is Optional("Three")
Modifier les dictionnaires
Vous pouvez utiliser updateValue(forKey:)pour ajouter une valeur existante à une clé donnée du dictionnaire. Cette méthode renvoie une valeur facultative du type valeur du dictionnaire. Voici un exemple simple -
var someDict:[Int:String] = [1:"One", 2:"Two", 3:"Three"]
var oldVal = someDict.updateValue("New value of one", forKey: 1)
var someVar = someDict[1]
print( "Old value of key = 1 is \(oldVal)" )
print( "Value of key = 1 is \(someVar)" )
print( "Value of key = 2 is \(someDict[2])" )
print( "Value of key = 3 is \(someDict[3])" )
Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -
Old value of key = 1 is Optional("One")
Value of key = 1 is Optional("New value of one")
Value of key = 2 is Optional("Two")
Value of key = 3 is Optional("Three")
Vous pouvez modifier un élément existant d'un dictionnaire en attribuant une nouvelle valeur à une clé donnée, comme indiqué dans l'exemple suivant -
var someDict:[Int:String] = [1:"One", 2:"Two", 3:"Three"]
var oldVal = someDict[1]
someDict[1] = "New value of one"
var someVar = someDict[1]
print( "Old value of key = 1 is \(oldVal)" )
print( "Value of key = 1 is \(someVar)" )
print( "Value of key = 2 is \(someDict[2])" )
print( "Value of key = 3 is \(someDict[3])" )
Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -
Old value of key = 1 is Optional("One")
Value of key = 1 is Optional("New value of one")
Value of key = 2 is Optional("Two")
Value of key = 3 is Optional("Three")
Supprimer les paires clé-valeur
Vous pouvez utiliser removeValueForKey()pour supprimer une paire clé-valeur d'un dictionnaire. Cette méthode supprime la paire clé-valeur si elle existe et renvoie la valeur supprimée, ou renvoie nil si aucune valeur n'existe. Voici un exemple simple -
var someDict:[Int:String] = [1:"One", 2:"Two", 3:"Three"]
var removedValue = someDict.removeValue(forKey: 2)
print( "Value of key = 1 is \(someDict[1])" )
print( "Value of key = 2 is \(someDict[2])" )
print( "Value of key = 3 is \(someDict[3])" )
Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -
Value of key = 1 is Optional("One")
Value of key = 2 is nil
Value of key = 3 is Optional("Three")
Vous pouvez également utiliser la syntaxe d'indice pour supprimer une paire clé-valeur d'un dictionnaire en attribuant une valeur de nilpour cette clé. Voici un exemple simple -
var someDict:[Int:String] = [1:"One", 2:"Two", 3:"Three"]
someDict[2] = nil
print( "Value of key = 1 is \(someDict[1])" )
print( "Value of key = 2 is \(someDict[2])" )
print( "Value of key = 3 is \(someDict[3])" )
Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -
Value of key = 1 is Optional("One")
Value of key = 2 is nil
Value of key = 3 is Optional("Three")
Itérer sur un dictionnaire
Vous pouvez utiliser un for-in boucle pour parcourir l'ensemble des paires clé-valeur dans un dictionnaire, comme indiqué dans l'exemple suivant -
var someDict:[Int:String] = [1:"One", 2:"Two", 3:"Three"]
for (index, keyValue) in someDict.enumerated() {
print("Dictionary key \(index) - Dictionary value \(keyValue)")
}
Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -
Dictionary key 2 - Dictionary value Two
Dictionary key 3 - Dictionary value Three
Dictionary key 1 - Dictionary value One
Vous pouvez utiliser enumerate() fonction qui renvoie l'index de l'élément avec sa paire (clé, valeur) comme indiqué ci-dessous dans l'exemple -
var someDict:[Int:String] = [1:"One", 2:"Two", 3:"Three"]
for (key, value) in someDict.enumerated() {
print("Dictionary key \(key) - Dictionary value \(value)")
}
Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -
Dictionary key 0 - Dictionary value (key: 2, value: "Two")
Dictionary key 1 - Dictionary value (key: 3, value: "Three")
Dictionary key 2 - Dictionary value (key: 1, value: "One")
Convertir en tableaux
Vous pouvez extraire une liste de paires clé-valeur d'un dictionnaire donné pour créer des tableaux séparés pour les clés et les valeurs. Voici un exemple -
var someDict:[Int:String] = [1:"One", 2:"Two", 3:"Three"]
let dictKeys = [Int](someDict.keys)
let dictValues = [String](someDict.values)
print("Print Dictionary Keys")
for (key) in dictKeys {
print("\(key)")
}
print("Print Dictionary Values")
for (value) in dictValues {
print("\(value)")
}
Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -
Print Dictionary Keys
2
3
1
Print Dictionary Values
Two
Three
One
La propriété count
Vous pouvez utiliser la lecture seule count propriété d'un dictionnaire pour connaître le nombre d'éléments dans un dictionnaire comme indiqué ci-dessous -
var someDict1:[Int:String] = [1:"One", 2:"Two", 3:"Three"]
var someDict2:[Int:String] = [4:"Four", 5:"Five"]
print("Total items in someDict1 = \(someDict1.count)")
print("Total items in someDict2 = \(someDict2.count)")
Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -
Total items in someDict1 = 3
Total items in someDict2 = 2
La propriété vide
Vous pouvez utiliser en lecture seule empty propriété d'un dictionnaire pour savoir si un dictionnaire est vide ou non, comme indiqué ci-dessous -
var someDict1:[Int:String] = [1:"One", 2:"Two", 3:"Three"]
var someDict2:[Int:String] = [4:"Four", 5:"Five"]
var someDict3:[Int:String] = [Int:String]()
print("someDict1 = \(someDict1.isEmpty)")
print("someDict2 = \(someDict2.isEmpty)")
print("someDict3 = \(someDict3.isEmpty)")
Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -
someDict1 = false
someDict2 = false
someDict3 = true
Une fonction est un ensemble d'instructions organisées ensemble pour effectuer une tâche spécifique. Une fonction Swift 4 peut être aussi simple qu'une simple fonction C à aussi complexe qu'une fonction de langage Objective C. Cela nous permet de passer des valeurs de paramètres locaux et globaux dans les appels de fonction.
Function Declaration - informe le compilateur du nom, du type de retour et des paramètres d'une fonction.
Function Definition - Il fournit le corps réel de la fonction.
Les fonctions Swift 4 contiennent le type de paramètre et ses types de retour.
Définition de fonction
Dans Swift 4, une fonction est définie par le mot clé "func". Lorsqu'une fonction est nouvellement définie, elle peut prendre une ou plusieurs valeurs comme «paramètres» d'entrée de la fonction et elle traitera les fonctions dans le corps principal et transmettra les valeurs aux fonctions en tant que «types de retour».
Chaque fonction a un nom de fonction, qui décrit la tâche exécutée par la fonction. Pour utiliser une fonction, vous «appelez» cette fonction avec son nom et passez des valeurs d'entrée (appelées arguments) qui correspondent aux types de paramètres de la fonction. Les paramètres de fonction sont également appelés «tuples».
Les arguments d'une fonction doivent toujours être fournis dans le même ordre que la liste des paramètres de la fonction et les valeurs de retour sont suivies de →.
Syntaxe
func funcname(Parameters) -> returntype {
Statement1
Statement2
---
Statement N
return parameters
}
Jetez un œil au code suivant. Le nom de l'étudiant est déclaré en tant que type de données chaîne déclaré à l'intérieur de la fonction «étudiant» et lorsque la fonction est appelée, il renvoie le nom de l'étudiant.
func student(name: String) -> String {
return name
}
print(student(name: "First Program"))
print(student(name: "About Functions"))
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
First Program
About Functions
Appeler une fonction
Supposons que nous ayons défini une fonction appelée 'affichage' à Considérer par exemple pour afficher les nombres une fonction avec le nom de fonction 'affichage' est initialisée en premier avec l'argument 'no1' qui contient un type de données entier. Ensuite, l'argument «no1» est affecté à l'argument «a» qui ci-après pointera vers le même entier de type de données. Maintenant, l'argument «a» est renvoyé à la fonction. Ici, la fonction display () contiendra la valeur entière et renverra les valeurs entières à chaque fois que la fonction est appelée.
func display(no1: Int) -> Int {
let a = no1
return a
}
print(display(no1: 100))
print(display(no1: 200))
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
100
200
Paramètres et valeurs de retour
Swift 4 fournit des paramètres de fonction flexibles et ses valeurs de retour allant des valeurs simples aux valeurs complexes. Semblables à celles de C et d'Objective C, les fonctions de Swift 4 peuvent également prendre plusieurs formes.
Fonctions avec paramètres
Une fonction est accessible en passant ses valeurs de paramètre au corps de la fonction. Nous pouvons passer une à plusieurs valeurs de paramètre sous forme de tuples à l'intérieur de la fonction.
func mult(no1: Int, no2: Int) -> Int {
return no1*no2
}
print(mult(no1: 2, no2: 20))
print(mult(no1: 3, no2: 15))
print(mult(no1: 4, no2: 30))
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
40
45
120
Fonctions sans paramètres
Nous pouvons également avoir des fonctions sans aucun paramètre.
Syntaxe
func funcname() -> datatype {
return datatype
}
Voici un exemple ayant une fonction sans paramètre -
func votersname() -> String {
return "Alice"
}
print(votersname())
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Alice
Fonctions avec valeurs de retour
Les fonctions sont également utilisées pour renvoyer des valeurs de type de données chaîne, entier et flottant comme types de retour. Pour trouver le plus grand et le plus petit nombre dans un tableau donné, la fonction «ls» est déclarée avec des types de données entiers grands et petits.
Un tableau est initialisé pour contenir des valeurs entières. Ensuite, le tableau est traité et chaque valeur du tableau est lue et comparée pour sa valeur précédente. Lorsque la valeur est inférieure à la précédente, elle est stockée dans un 'petit' argument, sinon elle est stockée dans un 'grand' argument et les valeurs sont renvoyées en appelant la fonction.
func ls(array: [Int]) -> (large: Int, small: Int) {
var lar = array[0]
var sma = array[0]
for i in array[1..<array.count] {
if i < sma {
sma = i
} else if i > lar {
lar = i
}
}
return (lar, sma)
}
let num = ls(array: [40,12,-5,78,98])
print("Largest number is: \(num.large) and smallest number is: \(num.small)")
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Largest number is: 98 and smallest number is: -5
Fonctions sans valeurs de retour
Certaines fonctions peuvent avoir des arguments déclarés à l'intérieur de la fonction sans aucune valeur de retour. Le programme suivant déclarea et bcomme arguments de la fonction sum (). à l'intérieur de la fonction elle-même les valeurs des argumentsa et b sont passés en appelant la fonction appel sum () et ses valeurs sont imprimées, éliminant ainsi les valeurs de retour.
func sum(a: Int, b: Int) {
let a = a + b
let b = a - b
print(a, b)
}
sum(a: 20, b: 10)
sum(a: 40, b: 10)
sum(a: 24, b: 6)
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
30 20
50 40
30 24
Fonctions avec types de retour facultatifs
Swift 4 introduit une fonction «optionnelle» pour se débarrasser des problèmes en introduisant une mesure de sécurité. Considérez par exemple que nous déclarons le type de retour des valeurs de fonction sous forme d'entier, mais que se passera-t-il lorsque la fonction renvoie une valeur de chaîne ou une valeur nulle. Dans ce cas, le compilateur renverra une valeur d'erreur. «facultatifs» sont introduits pour se débarrasser de ces problèmes.
Les fonctions optionnelles prendront deux formes «valeur» et «nil». Nous mentionnerons 'Optionals' avec le caractère clé réservé '?' pour vérifier si le tuple renvoie une valeur ou une valeur nulle.
func minMax(array: [Int]) -> (min: Int, max: Int)? {
if array.isEmpty { return nil }
var currentMin = array[0]
var currentMax = array[0]
for value in array[1..<array.count] {
if value < currentMin {
currentMin = value
} else if value > currentMax {
currentMax = value
}
}
return (currentMin, currentMax)
}
if let bounds = minMax(array: [8, -6, 2, 109, 3, 71]) {
print("min is \(bounds.min) and max is \(bounds.max)")
}
Lorsque nous exécutons le programme ci-dessus en utilisant le terrain de jeu, nous obtenons le résultat suivant -
min is -6 and max is 109
«Les options» sont utilisées pour vérifier les valeurs «nil» ou inutiles, ce qui prend beaucoup de temps dans le débogage et rend le code efficace et lisible pour l'utilisateur.
Fonctions Noms des paramètres locaux et externes
Noms des paramètres locaux
Les noms de paramètres locaux sont accessibles uniquement à l'intérieur de la fonction.
func sample(number: Int) {
print(number)
}
Ici le funcsample argument number est déclaré comme variable interne car il est accédé en interne par la fonction sample (). Ici, le 'nombre' est déclaré comme variable locale mais la référence à la variable est faite en dehors de la fonction avec l'instruction suivante -
func sample(number: Int) {
print(number)
}
sample(number: 1)
sample(number: 2)
sample(number: 3)
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
1
2
3
Noms des paramètres externes
Les noms de paramètres externes nous permettent de nommer des paramètres de fonction pour rendre leur objectif plus clair. Par exemple ci-dessous, vous pouvez nommer deux paramètres de fonction, puis appeler cette fonction comme suit -
func pow(firstArg a: Int, secondArg b: Int) -> Int {
var res = a
for _ in 1..<b {
res = res * a
}
print(res)
return res
}
pow(firstArg:5, secondArg:3)
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
125
Paramètres variadiques
Lorsque nous voulons définir une fonction avec plusieurs nombres d'arguments, nous pouvons déclarer les membres en tant que paramètres «variadiques». Les paramètres peuvent être spécifiés comme variadiques par (···) après le nom du paramètre.
func vari<N>(members: N...){
for i in members {
print(i)
}
}
vari(members: 4,3,5)
vari(members: 4.5, 3.1, 5.6)
vari(members: "Swift 4", "Enumerations", "Closures")
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
4
3
5
4.5
3.1
5.6
Swift 4
Enumerations
Closures
Paramètres constants, variables et E / S
Les fonctions par défaut considèrent les paramètres comme «constants», tandis que l'utilisateur peut également déclarer les arguments des fonctions comme des variables. Nous avons déjà discuté du fait que le mot clé 'let' est utilisé pour déclarer des paramètres constants et que les paramètres variables sont définis avec le mot clé 'var'.
Les paramètres d'E / S dans Swift 4 fournissent des fonctionnalités pour conserver les valeurs des paramètres même si ses valeurs sont modifiées après l'appel de la fonction. Au début de la définition du paramètre de fonction, le mot clé 'inout' est déclaré pour conserver les valeurs de membre.
Il dérive le mot-clé 'inout' puisque ses valeurs sont passées 'in' à la fonction et ses valeurs sont accédées et modifiées par son corps de fonction et il est renvoyé 'out' de la fonction pour modifier l'argument d'origine.
Les variables ne sont transmises qu'en tant qu'argument pour le paramètre in-out puisque ses valeurs seules sont modifiées à l'intérieur et à l'extérieur de la fonction. Il n'est donc pas nécessaire de déclarer des chaînes et des littéraux en tant que paramètres d'entrée-sortie. '&' avant un nom de variable fait référence au fait que nous transmettons l'argument au paramètre in-out.
func temp(a1: inout Int, b1: inout Int) {
let t = a1
a1 = b1
b1 = t
}
var no = 2
var co = 10
temp(a1: &no, b1: &co)
print("Swapped values are \(no), \(co)")
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Swapped values are 10, 2
Types de fonction et son utilisation
Chaque fonction suit la fonction spécifique en considérant les paramètres d'entrée et sort le résultat souhaité.
func inputs(no1: Int, no2: Int) -> Int {
return no1/no2
}
Voici un exemple -
func inputs(no1: Int, no2: Int) -> Int {
return no1/no2
}
print(inputs(no1: 20, no2: 10))
print(inputs(no1: 36, no2: 6))
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
2
6
Ici, la fonction est initialisée avec deux arguments no1 et no2 en tant que types de données entiers et son type de retour est également déclaré comme 'int'
Func inputstr(name: String) -> String {
return name
}
Ici, la fonction est déclarée comme string Type de données.
Les fonctions peuvent également avoir void les types de données et de telles fonctions ne renverront rien.
func inputstr() {
print("Swift 4 Functions")
print("Types and its Usage")
}
inputstr()
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Swift 4 Functions
Types and its Usage
La fonction ci-dessus est déclarée comme une fonction void sans arguments ni valeurs de retour.
Utilisation des types de fonction
Les fonctions sont d'abord passées avec des arguments de type entier, flottant ou chaîne, puis elles sont passées sous forme de constantes ou de variables à la fonction comme indiqué ci-dessous.
var addition: (Int, Int) -> Int = sum
Ici, sum est un nom de fonction ayant des variables entières «a» et «b» qui est maintenant déclarée comme une variable à l'ajout du nom de la fonction. Ci-après, les fonctions d'addition et de somme ont toutes deux le même nombre d'arguments déclarés comme type de données entier et renvoient également des valeurs entières comme références.
func sum(a: Int, b: Int) -> Int {
return a + b
}
var addition: (Int, Int) -> Int = sum
print("Result: \(addition(40, 89))")
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Result: 129
Types de fonction en tant que types de paramètres et types de retour
Nous pouvons également passer la fonction elle-même en tant que types de paramètres à une autre fonction.
func sum(a: Int, b: Int) -> Int {
return a + b
}
var addition: (Int, Int) -> Int = sum
print("Result: \(addition(40, 89))")
func another(addition: (Int, Int) -> Int, a: Int, b: Int) {
print("Result: \(addition(a, b))")
}
another(sum, 10, 20)
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Result: 129
Result: 30
Fonctions imbriquées
Une fonction imbriquée offre la possibilité d'appeler la fonction externe en invoquant la fonction interne.
func calcDecrement(forDecrement total: Int) -> () -> Int {
var overallDecrement = 0
func decrementer() -> Int {
overallDecrement -= total
return overallDecrement
}
return decrementer
}
let decrem = calcDecrement(forDecrement: 30)
print(decrem())
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
-30
Les fermetures dans Swift 4 sont similaires à celles des fonctions autonomes organisées en blocs et appelées n'importe où comme les langages C et Objective C. Les constantes et références de variables définies à l'intérieur des fonctions sont capturées et stockées dans des fermetures. Les fonctions sont considérées comme des cas particuliers de fermetures et prennent les trois formes suivantes -
Fonctions globales | Fonctions imbriquées | Expressions de fermeture |
---|---|---|
Avoir un nom. Ne saisissez aucune valeur | Avoir un nom. Capturer les valeurs de la fonction englobante | Les fermetures sans nom capturent les valeurs des blocs adjacents |
Les expressions de fermeture en langage Swift 4 suivent des styles de syntaxe nets, optimisés et légers qui incluent.
- Inférence des types de paramètres et de valeurs de retour à partir du contexte.
- Retours implicites des fermetures d'expression unique.
- Noms d'arguments abrégés et
- Syntaxe de fermeture de fin
Syntaxe
Voici une syntaxe générique pour définir la fermeture qui accepte les paramètres et renvoie un type de données -
{
(parameters) −> return type in
statements
}
Voici un exemple simple -
let studname = { print("Welcome to Swift Closures") }
studname()
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Welcome to Swift Closures
La fermeture suivante accepte deux paramètres et renvoie une valeur booléenne -
{
(Int, Int) −> Bool in
Statement1
Statement 2
---
Statement n
}
Voici un exemple simple -
let divide = {
(val1: Int, val2: Int) -> Int in
return val1 / val2
}
let result = divide(200, 20)
print (result)
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
10
Expressions dans les fermetures
Les fonctions imbriquées offrent un moyen pratique de nommer et de définir des blocs de code. Au lieu de représenter toute la déclaration de fonction et les constructions de nom sont utilisées pour désigner des fonctions plus courtes. La représentation de la fonction dans une brève déclaration claire avec une syntaxe ciblée est obtenue par des expressions de fermeture.
Programme d'ordre croissant
Le tri d'une chaîne est réalisé par la fonction réservée de clé Swift 4s "triée" qui est déjà disponible dans la bibliothèque standard. La fonction triera les chaînes données dans l'ordre croissant et renvoie les éléments dans un nouveau tableau avec la même taille et le même type de données que ceux mentionnés dans l'ancien tableau. L'ancien tableau reste le même.
Deux arguments sont représentés dans la fonction triée -
Valeurs de type connu représentées sous forme de tableaux.
Contenu du tableau (Int, Int) et retourne une valeur booléenne (Bool) si le tableau est trié correctement, il retournera la valeur vraie sinon il retournera faux.
Une fonction normale avec une chaîne d'entrée est écrite et transmise à la fonction triée pour obtenir les chaînes triées dans le nouveau tableau qui est illustré ci-dessous -
func ascend(s1: String, s2: String) -> Bool {
return s1 > s2
}
let stringcmp = ascend(s1: "Swift 4", s2: "great")
print (stringcmp)
Lorsque nous exécutons le programme ci-dessus en utilisant le terrain de jeu, nous obtenons le résultat suivant -
true
Le tableau initial à trier pour la glace est donné comme "Swift 4" et "super". La fonction pour trier le tableau est déclarée comme type de données chaîne et son type de retour est mentionné comme booléen. Les deux chaînes sont comparées et triées par ordre croissant et stockées dans un nouveau tableau. Si le tri est effectué avec succès, la fonction retournera une valeur vraie, sinon elle retournera faux.
La syntaxe de l'expression de fermeture utilise -
- paramètres constants,
- paramètres variables, et
- paramètres inout.
L'expression de fermeture ne prenait pas en charge les valeurs par défaut. Les paramètres variadiques et les tuples peuvent également être utilisés comme types de paramètres et types de retour.
let sum = {
(no1: Int, no2: Int) -> Int in
return no1 + no2
}
let digits = sum(10, 20)
print(digits)
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
30
Les paramètres et les déclarations de type de retour mentionnés dans l'instruction de fonction peuvent également être représentés par la fonction d'expression de fermeture en ligne avec le mot-clé 'in'. Une fois le paramètre et les types de retour déclarés, le mot clé «in» est utilisé pour désigner le corps de la fermeture.
Retours implicites d'expression unique
Ici, le type de fonction du deuxième argument de la fonction triée indique clairement qu'une valeur booléenne doit être renvoyée par la fermeture. Étant donné que le corps de la fermeture contient une seule expression (s1> s2) qui renvoie une valeur booléenne, il n'y a pas d'ambiguïté et le mot-clé return peut être omis.
Pour renvoyer une instruction d'expression unique dans les fermetures d'expression, le mot clé 'return' est omis dans sa partie déclaration.
var count:[Int] = [5, 10, -6, 75, 20]
let descending = count.sorted(by: { n1, n2 in n1 > n2 })
let ascending = count.sorted(by: { n1, n2 in n1 < n2 })
print(descending)
print(ascending)
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
[75, 20, 10, 5, -6]
[-6, 5, 10, 20, 75]
L'instruction elle-même définit clairement que lorsque string1 est supérieur à string 2 return true sinon false donc l'instruction return est omise ici.
Fermetures de type connu
Considérez l'ajout de deux nombres. Nous savons que l'addition renverra le type de données entier. Par conséquent, les fermetures de type connu sont déclarées comme -
let sub = {
(no1: Int, no2: Int) -> Int in
return no1 - no2
}
let digits = sub(10, 20)
print(digits)
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
-10
Déclaration des noms d'arguments abrégés comme fermetures
Swift 4 fournit automatiquement des noms d'arguments abrégés aux fermetures en ligne, qui peuvent être utilisés pour faire référence aux valeurs des arguments de la fermeture par les noms $ 0, $1, $2, et ainsi de suite.
var shorthand: (String, String) -> String
shorthand = { $1 }
print(shorthand("100", "200"))
Ici, $ 0 et $ 1 font référence aux premier et deuxième arguments String de la fermeture.
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
200
Swift 4 permet à l'utilisateur de représenter les fermetures en ligne sous forme de noms d'arguments abrégés en représentant $ 0, $1, $2 --- $ n.
La liste des arguments de fermeture est omise dans la section de définition lorsque nous représentons des noms d'argument abrégés dans des expressions de fermeture. En fonction du type de fonction, les noms des arguments abrégés seront dérivés. Étant donné que l'argument abrégé est défini dans le corps de l'expression, le mot clé «in» est omis.
Les fermetures en tant que fonctions d'opérateur
Swift 4 fournit un moyen facile d'accéder aux membres en fournissant simplement des fonctions d'opérateur comme des fermetures. Dans les exemples précédents, le mot-clé 'Bool' est utilisé pour renvoyer soit 'true' lorsque les chaînes sont égales, sinon il renvoie 'false'.
L'expression est rendue encore plus simple par la fonction d'opérateur en fermeture comme -
let numb = [98, -20, -30, 42, 18, 35]
var sortedNumbers = numb.sorted ({
(left: Int, right: Int) -> Bool in
return left < right
})
let asc = numb.sorted(<)
print(asc)
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
[-30, -20, 18, 35, 42, 98]
Fermetures en tant que remorques
Passer l'argument final de la fonction à une expression de fermeture est déclaré à l'aide de 'Fermetures de fin'. Il est écrit en dehors de la fonction () avec {}. Son utilisation est nécessaire lorsqu'il n'est pas possible d'écrire la fonction en ligne sur une seule ligne.
reversed = sorted(names) { $0 > $1}
où {$ 0> $ 1} sont représentés comme des fermetures de fin déclarées à l'extérieur de (noms).
import Foundation
var letters = ["North", "East", "West", "South"]
let twoletters = letters.map({
(state: String) -> String in
return state.substringToIndex(advance(state.startIndex, 2)).uppercaseString
})
let stletters = letters.map() {
$0.substringToIndex(advance($0.startIndex, 2)).uppercaseString
}
print(stletters)
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
[NO, EA, WE, SO]
Capture de valeurs et de types de référence
Dans Swift 4, la capture des constantes et des valeurs de variables se fait à l'aide de fermetures. Il fait en outre référence et modifie les valeurs de ces constantes et variables à l'intérieur du corps de fermeture même si les variables n'existent plus.
La capture des valeurs constantes et variables est obtenue en utilisant une fonction imbriquée en écrivant la fonction avec dans le corps d'une autre fonction.
Une fonction imbriquée capture -
- Arguments de fonction externe.
- Capturez les constantes et les variables définies dans la fonction externe.
Dans Swift 4, lorsqu'une constante ou une variable est déclarée à l'intérieur d'une fonction, les références à ces variables sont également créées automatiquement par la fermeture. Il offre également la possibilité de faire référence à plus de deux variables comme la même fermeture comme suit -
let decrem = calcDecrement(forDecrement: 18)
decrem()
Ici oneDecrement et les variables de décrémentation pointeront toutes les deux sur le même bloc de mémoire comme référence de fermeture.
func calcDecrement(forDecrement total: Int) -> () -> Int {
var overallDecrement = 100
func decrementer() -> Int {
overallDecrement -= total
print(overallDecrement)
return overallDecrement
}
return decrementer
}
let decrem = calcDecrement(forDecrement: 18)
decrem()
decrem()
decrem()
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
82
64
46
Lorsque chaque fois que la fonction externe calcDecrement est appelée, elle appelle la fonction decrementer () et décrémente la valeur de 18 et renvoie le résultat à l'aide de la fonction externe calcDecrement. Ici, calcDecrement agit comme une fermeture.
Même si la fonction décrémenter () n'a pas d'arguments, la fermeture par défaut fait référence aux variables «globalDecrement» et «total» en capturant ses valeurs existantes. La copie des valeurs des variables spécifiées est stockée avec la nouvelle fonction décrémenteur (). Swift 4 gère les fonctions de gestion de la mémoire en allouant et en libérant des espaces mémoire lorsque les variables ne sont pas utilisées.
Une énumération est un type de données défini par l'utilisateur qui se compose d'un ensemble de valeurs associées. Mot-cléenum est utilisé pour définir le type de données énumérées.
Fonctionnalité d'énumération
L'énumération dans Swift 4 ressemble également à la structure de C et de l'Objectif C.
Il est déclaré dans une classe et ses valeurs sont accessibles via l'instance de cette classe.
La valeur initiale du membre est définie à l'aide des initiateurs enum.
Sa fonctionnalité est également étendue en assurant la fonctionnalité de protocole standard.
Syntaxe
Les énumérations sont introduites avec le mot-clé enum et placent leur définition entière dans une paire d'accolades -
enum enumname {
// enumeration values are described here
}
Par exemple, vous pouvez définir une énumération pour les jours de la semaine comme suit -
enum DaysofaWeek {
case Sunday
case Monday
---
case Saturday
}
Exemple
enum names {
case Swift
case Closures
}
var lang = names.Closures
lang = .Closures
switch lang {
case .Swift:
print("Welcome to Swift")
case .Closures:
print("Welcome to Closures")
default:
print("Introduction")
}
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Welcome to Closures
L'énumération Swift 4 n'attribue pas la valeur par défaut à ses membres comme C et Objective C. Au lieu de cela, les membres sont explicitement définis par leurs noms d'énumération. Le nom de l'énumération doit commencer par une majuscule (Ex: enum DaysofaWeek).
var weekDay = DaysofaWeek.Sunday
Ici, le nom d'énumération 'DaysofaWeek' est affecté à un jour de semaine variable. Il informe le compilateur que le type de données appartient à Sunday sera assigné aux membres suivants enum de cette classe particulière. Une fois le type de données du membre enum défini, les membres sont accessibles en passant des valeurs et d'autres calculs.
Énumération avec instruction Switch
L'instruction Swift 4 'Switch' suit également la sélection multi-directionnelle. Une seule variable est accessible à un moment donné en fonction de la condition spécifiée. La casse par défaut dans l'instruction switch est utilisée pour intercepter les cas non spécifiés.
enum Climate {
case India
case America
case Africa
case Australia
}
var season = Climate.America
season = .America
switch season {
case .India:
print("Climate is Hot")
case .America:
print("Climate is Cold")
case .Africa:
print("Climate is Moderate")
case .Australia:
print("Climate is Rainy")
}
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Climate is Cold
Le programme définit d'abord le climat comme le nom de l'énumération. Ensuite, ses membres comme «Inde», «Amérique», «Afrique» et «Australie» sont déclarés appartenant à la classe «Climat». Désormais, le membre Amérique est affecté à une variable de saison. De plus, Switch case verra les valeurs correspondant à .America et se branchera à cette instruction particulière. La sortie sera affichée comme "Le climat est froid". De même, tous les membres sont accessibles via des instructions switch. Lorsque la condition n'est pas satisfaite, il imprime par défaut «Le climat n'est pas prévisible».
L'énumération peut être davantage classée en valeurs associées et valeurs brutes.
Différence entre les valeurs associées et les valeurs brutes
Valeurs associées | Valeurs brutes |
Différents types de données | Mêmes types de données |
Ex: enum {10,0.8, "Hello"} | Ex: enum {10,35,50} |
Les valeurs sont créées en fonction d'une constante ou d'une variable | Valeurs pré-remplies |
Varie une fois déclaré à chaque fois | La valeur pour le membre est la même |
Énumération avec les valeurs associées
enum Student {
case Name(String)
case Mark(Int,Int,Int)
}
var studDetails = Student.Name("Swift 4")
var studMarks = Student.Mark(98,97,95)
switch studMarks {
case .Name(let studName):
print("Student name is: \(studName).")
case .Mark(let Mark1, let Mark2, let Mark3):
print("Student Marks are: \(Mark1),\(Mark2),\(Mark3).")
}
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Student Marks are: 98,97,95.
Pensez par exemple à accéder au nom des étudiants et aux marques sécurisées dans trois matières: le nom de l'énumération est déclaré comme étudiant et les membres présents dans la classe enum sont nom qui appartient à la chaîne de type de données, les marques sont représentées comme mark1, mark2 et mark3 de type de données Integer. Pour accéder au nom de l'élève ou aux notes qu'il a notées
var studDetails = Student.Name("Swift")
var studMarks = Student.Mark(98,97,95)
Maintenant, le boîtier de commutation imprimera le nom de l'étudiant si ce bloc de cas est exécuté, sinon il imprimera les marques sécurisées par l'étudiant. Si les deux conditions échouent, le bloc par défaut sera exécuté.
Énumération avec valeurs brutes
Les valeurs brutes peuvent être des chaînes, des caractères ou tout type de nombre entier ou à virgule flottante. Chaque valeur brute doit être unique dans sa déclaration d'énumération. Lorsque des entiers sont utilisés pour les valeurs brutes, ils s'incrémentent automatiquement si aucune valeur n'est spécifiée pour certains des membres de l'énumération.
enum Month: Int {
case January = 1, February, March, April, May, June, July, August,
September, October, November, December
}
let yearMonth = Month.May.rawValue
print("Value of the Month is: \(yearMonth).")
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Value of the Month is: 5.
Swift 4 fournit un bloc de construction flexible pour utiliser les constructions comme structures. En utilisant ces structures une fois peut définir des méthodes et des propriétés de construction.
Contrairement à C et à l'objectif C
La structure n'a pas besoin de fichiers d'implémentation et d'interface.
La structure nous permet de créer un seul fichier et d'étendre automatiquement son interface à d'autres blocs.
Dans Structure, les valeurs de variable sont copiées et transmises dans les codes suivants en renvoyant une copie des anciennes valeurs afin que les valeurs ne puissent pas être modifiées.
Syntaxe
Structures are defined with a 'Struct' Keyword.
struct nameStruct {
Definition 1
Definition 2
---
Definition N
}
Définition d'une structure
Prenons par exemple, supposons que nous devions accéder au dossier des élèves contenant les notes de trois matières et connaître le total de trois matières. Ici, markStruct est utilisé pour initialiser une structure avec trois marques comme type de données 'Int'.
struct MarkStruct {
var mark1: Int
var mark2: Int
var mark3: Int
}
Accéder à la structure et à ses propriétés
Les membres de la structure sont accessibles par son nom de structure. Les instances de la structure sont initialisées par le mot clé 'let'.
struct studentMarks {
var mark1 = 100
var mark2 = 200
var mark3 = 300
}
let marks = studentMarks()
print("Mark1 is \(marks.mark1)")
print("Mark2 is \(marks.mark2)")
print("Mark3 is \(marks.mark3)")
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Mark1 is 100
Mark2 is 200
Mark3 is 300
Les notes des étudiants sont accessibles par le nom de structure «studentMarks». Les membres de la structure sont initialisés en tant que mark1, mark2, mark3 avec des valeurs de type entier. Ensuite, la structure studentMarks () est transmise aux 'marques' avec le mot clé 'let'. Ci-après, les «marques» contiendront les valeurs des membres de la structure. Désormais, les valeurs sont imprimées en accédant aux valeurs des membres de la structure par '.' avec ses noms initialisés.
struct MarksStruct {
var mark: Int
init(mark: Int) {
self.mark = mark
}
}
var aStruct = MarksStruct(mark: 98)
var bStruct = aStruct // aStruct and bStruct are two structs with the same value!
bStruct.mark = 97
print(aStruct.mark) // 98
print(bStruct.mark) // 97
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
98
97
Meilleures pratiques d'utilisation des structures
Le langage Swift 4 fournit la fonctionnalité pour définir des structures en tant que types de données personnalisés pour la construction des blocs fonctionnels. Les instances de structure sont transmises par sa valeur aux blocs définis pour des manipulations ultérieures.
Besoin d'avoir des structures
Pour encapsuler des valeurs de données simples.
Copier les données encapsulées et leurs propriétés associées par «valeurs» plutôt que par «références».
Structure à «Copier» et «Référence».
Les structures de Swift 4 transmettent leurs membres avec leurs valeurs plutôt que par ses références.
struct markStruct {
var mark1: Int
var mark2: Int
var mark3: Int
init(mark1: Int, mark2: Int, mark3: Int) {
self.mark1 = mark1
self.mark2 = mark2
self.mark3 = mark3
}
}
var marks = markStruct(mark1: 98, mark2: 96, mark3:100)
print(marks.mark1)
print(marks.mark2)
print(marks.mark3)
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
98
96
100
Un autre exemple
struct markStruct {
var mark1: Int
var mark2: Int
var mark3: Int
init(mark1: Int, mark2: Int, mark3: Int) {
self.mark1 = mark1
self.mark2 = mark2
self.mark3 = mark3
}
}
var fail = markStruct(mark1: 34, mark2: 42, mark3: 13)
print(fail.mark1)
print(fail.mark2)
print(fail.mark3)
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
34
42
13
La structure 'markStruct' est définie en premier avec ses membres mark1, mark2 et mark3. Désormais, les variables des classes membres sont initialisées pour contenir des valeurs entières. Ensuite, la copie des membres de la structure est créée avec le mot-clé «self». Une fois la copie des membres de la structure créée, le bloc de structure avec ses paramètres, les marques sont passées à la variable «marks» qui contiendra désormais les notes des étudiants. Ensuite, les marques sont imprimées sous la forme 98, 96, 100. L'étape suivante pour les mêmes membres de structure, une autre instance appelée «échec» est utilisée pour pointer les mêmes membres de structure avec des marques différentes. Ensuite, les résultats sont maintenant imprimés sous la forme 34, 42, 13. Cela explique clairement que les structures auront une copie des variables membres puis passeront les membres à leurs blocs fonctionnels à venir.
Les classes de Swift 4 sont des éléments constitutifs de constructions flexibles. Comme pour les constantes, les variables et les fonctions, l'utilisateur peut définir des propriétés et des méthodes de classe. Swift 4 nous fournit la fonctionnalité qui, lors de la déclaration de classes, les utilisateurs n'ont pas besoin de créer des interfaces ou des fichiers d'implémentation. Swift 4 nous permet de créer des classes sous la forme d'un fichier unique et les interfaces externes seront créées par défaut une fois les classes initialisées.
Avantages d'avoir des cours
L'héritage acquiert les propriétés d'une classe à une autre classe
Le cast de type permet à l'utilisateur de vérifier le type de classe au moment de l'exécution
Les déinitialiseurs prennent soin de libérer les ressources mémoire
Le comptage de références permet à l'instance de classe d'avoir plus d'une référence
Caractéristiques communes des classes et des structures
- Les propriétés sont définies pour stocker des valeurs
- Les indices sont définis pour donner accès aux valeurs
- Les méthodes sont initialisées pour améliorer la fonctionnalité
- L'état initial est défini par les initialiseurs
- Les fonctionnalités sont étendues au-delà des valeurs par défaut
- Confirmation des normes de fonctionnalité du protocole
Syntaxe
Class classname {
Definition 1
Definition 2
---
Definition N
}
Définition de classe
class student {
var studname: String
var mark: Int
var mark2: Int
}
La syntaxe de création d'instances
let studrecord = student()
Exemple
class MarksStruct {
var mark: Int
init(mark: Int) {
self.mark = mark
}
}
class studentMarks {
var mark = 300
}
let marks = studentMarks()
print("Mark is \(marks.mark)")
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Mark is 300
Accès aux propriétés de classe en tant que types de référence
Les propriétés de classe sont accessibles par le '.' syntaxe. Le nom de la propriété est séparé par un "." après le nom de l'instance.
class MarksStruct {
var mark: Int
init(mark: Int) {
self.mark = mark
}
}
class studentMarks {
var mark1 = 300
var mark2 = 400
var mark3 = 900
}
let marks = studentMarks()
print("Mark1 is \(marks.mark1)")
print("Mark2 is \(marks.mark2)")
print("Mark3 is \(marks.mark3)")
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Mark1 is 300
Mark2 is 400
Mark3 is 900
Opérateurs d'identité de classe
Les classes dans Swift 4 font référence à plusieurs constantes et variables pointant vers une seule instance. Pour connaître les constantes et les variables pointant vers une instance de classe particulière, des opérateurs d'identité sont utilisés. Les instances de classe sont toujours passées par référence. Dans les classes, les instances NSString, NSArray et NSDictionary sont toujours attribuées et transmises en tant que référence à une instance existante, plutôt qu'en tant que copie.
Identique aux opérateurs | Pas identique aux opérateurs |
---|---|
L'opérateur utilisé est (===) | L'opérateur utilisé est (! ==) |
Renvoie true lorsque deux constantes ou variables pointant vers une même instance | Renvoie true lorsque deux constantes ou variables pointant vers une instance différente |
class SampleClass: Equatable {
let myProperty: String
init(s: String) {
myProperty = s
}
}
func ==(lhs: SampleClass, rhs: SampleClass) -> Bool {
return lhs.myProperty == rhs.myProperty
}
let spClass1 = SampleClass(s: "Hello")
let spClass2 = SampleClass(s: "Hello")
spClass1 === spClass2 // false
print("\(spClass1)")
spClass1 !== spClass2 // true
print("\(spClass2)")
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
main.SampleClass
main.SampleClass
Le langage Swift 4 fournit des propriétés de classe, d'énumération ou de structure pour associer des valeurs. Les propriétés peuvent être classées en propriétés stockées et propriétés calculées.
Différence entre les propriétés stockées et les propriétés calculées
Propriété stockée | Propriété calculée |
---|---|
Stocker les valeurs constantes et variables comme instance | Calculez une valeur plutôt que de stocker la valeur |
Fourni par les classes et les structures | Fourni par des classes, des énumérations et des structures |
Les propriétés stockées et calculées sont associées au type d'instance. Lorsque les propriétés sont associées à ses valeurs de type, elles sont définies comme «Propriétés de type». Les propriétés stockées et calculées sont généralement associées à des instances d'un type particulier. Cependant, les propriétés peuvent également être associées au type lui-même. Ces propriétés sont appelées propriétés de type. Des observateurs de propriété sont également utilisés
- Pour observer la valeur des propriétés stockées
- Pour observer la propriété de la sous-classe héritée dérivée de la superclasse
Propriétés stockées
Swift 4 introduit le concept de propriété stockée pour stocker les instances de constantes et de variables. Les propriétés stockées des constantes sont définies par le mot clé 'let' et les propriétés stockées des variables sont définies par le mot clé 'var'.
- Pendant la définition, la propriété stockée fournit la «valeur par défaut»
- Lors de l'initialisation, l'utilisateur peut initialiser et modifier les valeurs initiales
struct Number {
var digits: Int
let pi = 3.1415
}
var n = Number(digits: 12345)
n.digits = 67
print("\(n.digits)")
print("\(n.pi)")
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
67
3.1415
Considérez la ligne suivante dans le code ci-dessus -
let pi = 3.1415
Ici, la variable pi est initialisée en tant que valeur de propriété stockée avec l'instance pi = 3.1415. Ainsi, chaque fois que l'instance est référencée, elle contiendra la valeur 3.1415 seule.
Une autre méthode pour avoir une propriété stockée est d'avoir des structures constantes. Ainsi, toute l'instance des structures sera considérée comme «Propriétés stockées des constantes».
struct Number {
var digits: Int
let numbers = 3.1415
}
var n = Number(digits: 12345)
n.digits = 67
print("\(n.digits)")
print("\(n.numbers)")
n.numbers = 8.7
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
error: cannot assign to 'numbers' in 'n'
n.numbers = 8.7
Au lieu de réinitialiser le «nombre» à 8,7, il renverra un message d'erreur indiquant que le «nombre» est déclaré comme constant.
Propriété stockée paresseuse
Swift 4 fournit une propriété flexible appelée «Lazy Stored Property» où il ne calculera pas les valeurs initiales lorsque la variable est initialisée pour la première fois. Le modificateur 'lazy' est utilisé avant la déclaration de variable pour l'avoir comme propriété stockée différée.
Les propriétés paresseuses sont utilisées -
- Pour retarder la création d'objet.
- Lorsque la propriété dépend d'autres parties d'une classe, qui ne sont pas encore connues
class sample {
lazy var no = number() // `var` declaration is required.
}
class number {
var name = "Swift 4"
}
var firstsample = sample()
print(firstsample.no.name)
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Swift 4
Variables d'instance
En Objective C, les propriétés stockées ont également des variables d'instance à des fins de sauvegarde pour stocker les valeurs déclarées dans la propriété stockée.
Swift 4 intègre ces deux concepts dans une seule déclaration de «propriété stockée». Au lieu d'avoir une variable d'instance correspondante et une valeur de sauvegarde, la «propriété stockée» contient toutes les informations intégrées définies dans un seul emplacement sur la propriété des variables par nom de variable, type de données et fonctionnalités de gestion de la mémoire.
Propriétés calculées
Plutôt que de stocker les valeurs calculées, les propriétés fournissent un getter et un setter facultatif pour récupérer et définir indirectement d'autres propriétés et valeurs.
class sample {
var no1 = 0.0, no2 = 0.0
var length = 300.0, breadth = 150.0
var middle: (Double, Double) {
get {
return (length / 2, breadth / 2)
}
set(axis){
no1 = axis.0 - (length / 2)
no2 = axis.1 - (breadth / 2)
}
}
}
var result = sample()
print(result.middle)
result.middle = (0.0, 10.0)
print(result.no1)
print(result.no2)
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
(150.0, 75.0)
-150.0
-65.0
Lorsqu'une propriété calculée laisse la nouvelle valeur indéfinie, la valeur par défaut est définie pour cette variable particulière.
Propriétés calculées en tant que propriétés en lecture seule
Une propriété en lecture seule dans une propriété calculée est définie comme une propriété avec getter mais sans setter. Il est toujours utilisé pour renvoyer une valeur. Les variables sont ensuite accessibles via un '.' Syntaxe mais ne peut pas être définie sur une autre valeur.
class film {
var head = ""
var duration = 0.0
var metaInfo: [String:String] {
return [
"head": self.head,
"duration":"\(self.duration)"
]
}
}
var movie = film()
movie.head = "Swift 4 Properties"
movie.duration = 3.09
print(movie.metaInfo["head"]!)
print(movie.metaInfo["duration"]!)
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Swift 4 Properties
3.09
Propriétés calculées en tant qu'observateurs de propriétés
Dans Swift 4 pour observer et répondre aux valeurs de propriété, des observateurs de propriété sont utilisés. Chaque fois que les valeurs de propriété sont définies, des observateurs de propriété sont appelés. Sauf les propriétés stockées paresseuses, nous pouvons ajouter des observateurs de propriété à la propriété «héritée» par la méthode «remplacement».
Les observateurs de propriétés peuvent être définis soit par
Avant de stocker la valeur - willset
Après avoir enregistré la nouvelle valeur - didset
Lorsqu'une propriété est définie dans un initialiseur, les observateurs willset et didset ne peuvent pas être appelés.
class Samplepgm {
var counter: Int = 0 {
willSet(newTotal){
print("Total Counter is: \(newTotal)")
}
didSet {
if counter > oldValue {
print("Newly Added Counter \(counter - oldValue)")
}
}
}
}
let NewCounter = Samplepgm()
NewCounter.counter = 100
NewCounter.counter = 800
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Total Counter is: 100
Newly Added Counter 100
Total Counter is: 800
Newly Added Counter 700
Variables locales et globales
Les variables locales et globales sont déclarées pour le calcul et l'observation des propriétés.
Variables locales | Variables globales |
---|---|
Variables définies dans une fonction, une méthode ou un contexte de fermeture. | Variables définies en dehors du contexte de fonction, de méthode, de fermeture ou de type. |
Utilisé pour stocker et récupérer des valeurs. | Utilisé pour stocker et récupérer des valeurs. |
Les propriétés stockées sont utilisées pour obtenir et définir les valeurs. | Les propriétés stockées sont utilisées pour obtenir et définir les valeurs. |
Les propriétés calculées sont également utilisées. | Les propriétés calculées sont également utilisées. |
Type de propriétés
Les propriétés sont définies dans la section Définition de type avec des accolades {} et la portée des variables est également définie précédemment. Pour définir les propriétés de type pour les types valeur, le mot clé «static» est utilisé et pour les types de classe, le mot clé «class» est utilisé.
Syntaxe
struct Structname {
static var storedTypeProperty = " "
static var computedTypeProperty: Int {
// return an Int value here
}
}
enum Enumname {
static var storedTypeProperty = " "
static var computedTypeProperty: Int {
// return an Int value here
}
}
class Classname {
class var computedTypeProperty: Int {
// return an Int value here
}
}
Requête et définition des propriétés
Tout comme les propriétés d'occurrence Les propriétés de type sont interrogées et définies avec '.' Syntaxe uniquement sur le type au lieu de pointer vers l'instance.
struct StudMarks {
static let markCount = 97
static var totalCount = 0
var InternalMarks: Int = 0 {
didSet {
if InternalMarks > StudMarks.markCount {
InternalMarks = StudMarks.markCount
}
if InternalMarks > StudMarks.totalCount {
StudMarks.totalCount = InternalMarks
}
}
}
}
var stud1Mark1 = StudMarks()
var stud1Mark2 = StudMarks()
stud1Mark1.InternalMarks = 98
print(stud1Mark1.InternalMarks)
stud1Mark2.InternalMarks = 87
print(stud1Mark2.InternalMarks)
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
97
87
En langage Swift 4, les fonctions associées à des types particuliers sont appelées méthodes. En Objective C, les classes sont utilisées pour définir des méthodes, tandis que le langage Swift 4 offre à l'utilisateur la flexibilité d'avoir des méthodes pour les classes, les structures et les énumérations.
Méthodes d'instance
En langage Swift 4, les instances Classes, Structures et Enumeration sont accessibles via les méthodes d'instance.
Les méthodes d'instance fournissent des fonctionnalités
- Pour accéder et modifier les propriétés des instances
- fonctionnalité liée au besoin de l'instance
La méthode d'instance peut être écrite à l'intérieur des {} accolades. Il a un accès implicite aux méthodes et propriétés de l'instance de type. Lorsqu'une instance spécifique du type est appelée, elle aura accès à cette instance particulière.
Syntaxe
func funcname(Parameters) -> returntype {
Statement1
Statement2
---
Statement N
return parameters
}
Exemple
class calculations {
let a: Int
let b: Int
let res: Int
init(a: Int, b: Int) {
self.a = a
self.b = b
res = a + b
}
func tot(c: Int) -> Int {
return res - c
}
func result() {
print("Result is: \(tot(c: 20))")
print("Result is: \(tot(c: 50))")
}
}
let pri = calculations(a: 600, b: 300)
pri.result()
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Result is: 880
Result is: 850
Les calculs de classe définissent deux méthodes d'instance -
- init () est défini pour ajouter deux nombres a et b et les stocker dans le résultat 'res'
- tot () est utilisé pour soustraire le 'res' de passer la valeur 'c'
Enfin, pour imprimer les méthodes de calculs avec des valeurs pour a et b est appelée. Les méthodes d'instance sont accessibles avec '.' syntaxe de point
Noms des paramètres locaux et externes
Les fonctions Swift 4 décrivent les déclarations locales et globales pour leurs variables. De même, les conventions de dénomination des méthodes Swift 4 ressemblent également à celles de l'Objectif C. Mais les caractéristiques des déclarations de noms de paramètres locaux et globaux sont différentes pour les fonctions et les méthodes. Le premier paramètre de Swift 4 est référencé par les noms de préposition comme «avec», «pour» et «par» pour des conventions de dénomination faciles d'accès.
Swift 4 offre la flexibilité des méthodes en déclarant le premier nom de paramètre en tant que noms de paramètres locaux et les noms de paramètres restants comme étant des noms de paramètres globaux. Ici, «no1» est déclaré par les méthodes Swift 4 comme noms de paramètres locaux. «no2» est utilisé pour les déclarations globales et accessible via le programme.
class division {
var count: Int = 0
func incrementBy(no1: Int, no2: Int) {
count = no1 / no2
print(count)
}
}
let counter = division()
counter.incrementBy(no1: 1800, no2: 3)
counter.incrementBy(no1: 1600, no2: 5)
counter.incrementBy(no1: 11000, no2: 3)
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
600
320
3666
Nom du paramètre externe avec symbole # et _
Même si les méthodes Swift 4 fournissent les premiers noms de paramètres pour les déclarations locales, l'utilisateur a la possibilité de modifier les noms de paramètres des déclarations locales vers les déclarations globales. Cela peut être fait en préfixant le symbole «#» avec le premier nom de paramètre. Ce faisant, le premier paramètre est accessible globalement à travers les modules.
Lorsque l'utilisateur a besoin d'accéder aux noms de paramètres suivants avec un nom externe, le nom de la méthode est remplacé à l'aide du symbole «_».
class multiplication {
var count: Int = 0
func incrementBy(no1: Int, no2: Int) {
count = no1 * no2
print(count)
}
}
let counter = multiplication()
counter.incrementBy(no1: 800, no2: 3)
counter.incrementBy(no1: 100, no2: 5)
counter.incrementBy(no1: 15000, no2: 3)
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
2400
500
45000
Propriété de soi dans les méthodes
Les méthodes ont une propriété implicite appelée «self» pour toutes ses instances de type définies. La propriété 'Self' est utilisée pour référencer les instances actuelles pour ses méthodes définies.
class calculations {
let a: Int
let b: Int
let res: Int
init(a: Int, b: Int) {
self.a = a
self.b = b
res = a + b
print("Inside Self Block: \(res)")
}
func tot(c: Int) -> Int {
return res - c
}
func result() {
print("Result is: \(tot(c: 20))")
print("Result is: \(tot(c: 50))")
}
}
let pri = calculations(a: 600, b: 300)
let sum = calculations(a: 1200, b: 300)
pri.result()
sum.result()
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Inside Self Block: 900
Inside Self Block: 1500
Result is: 880
Result is: 850
Result is: 1480
Result is: 1450
Modification des types de valeur à partir des méthodes d'instance
Dans Swift 4, les structures et les énumérations appartiennent à des types de valeur qui ne peuvent pas être modifiés par ses méthodes d'instance. Cependant, le langage Swift 4 offre la flexibilité de modifier les types de valeur en «mutant» le comportement. Mutate apportera toutes les modifications aux méthodes d'instance et reviendra à la forme d'origine après l'exécution de la méthode. De plus, par la propriété 'self', une nouvelle instance est créée pour sa fonction implicite et remplacera la méthode existante après son exécution
struct area {
var length = 1
var breadth = 1
func area() -> Int {
return length * breadth
}
mutating func scaleBy(res: Int) {
length *= res
breadth *= res
print(length)
print(breadth)
}
}
var val = area(length: 3, breadth: 5)
val.scaleBy(res: 3)
val.scaleBy(res: 30)
val.scaleBy(res: 300)
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
9
15
270
450
81000
135000
Propriété propre pour la méthode de mutation
Les méthodes de mutation combinées à la propriété 'self' attribuent une nouvelle instance à la méthode définie.
struct area {
var length = 1
var breadth = 1
func area() -> Int {
return length * breadth
}
mutating func scaleBy(res: Int) {
self.length *= res
self.breadth *= res
print(length)
print(breadth)
}
}
var val = area(length: 3, breadth: 5)
val.scaleBy(res: 13)
Lorsque nous exécutons le programme ci-dessus en utilisant Playground, nous obtenons le résultat suivant. -
39
65
Méthodes de type
Lorsqu'une instance particulière d'une méthode est appelée, elle est appelée en tant que méthode Instance; et lorsque la méthode appelle un type particulier de méthode, elle est appelée «Méthodes de type». Les méthodes de type pour les 'classes' sont définies par le mot clé 'func' et les méthodes de type structures et énumérations sont définies avec le mot clé 'static' avant le mot clé 'func'.
Les méthodes de type sont appelées et accessibles par '.' syntaxe où au lieu d'appeler une instance particulière, la méthode entière est appelée.
class Math {
class func abs(number: Int) -> Int {
if number < 0 {
return (-number)
} else {
return number
}
}
}
struct absno {
static func abs(number: Int) -> Int {
if number < 0 {
return (-number)
} else {
return number
}
}
}
let no = Math.abs(number: -35)
let num = absno.abs(number: -5)
print(no)
print(num)
Lorsque nous exécutons le programme ci-dessus en utilisant Playground, nous obtenons le résultat suivant. -
35
5
L'accès aux éléments membres d'une collection, d'une séquence et d'une liste dans Classes, Structures et Enumerations se fait à l'aide d'indices. Ces indices sont utilisés pour stocker et récupérer les valeurs à l'aide d'index. Les éléments de tableau sont accessibles à l'aide de someArray [index] et ses éléments membres suivants dans une instance de Dictionary sont accessibles en tant que someDicitonary [key].
Pour un seul type, les indices peuvent aller d'une déclaration à plusieurs déclarations. Nous pouvons utiliser l'indice approprié pour surcharger le type de valeur d'index passé à l'indice. Les indices vont également d'une dimension unique à plusieurs dimensions selon les exigences des utilisateurs pour leurs déclarations de type de données d'entrée.
Syntaxe de la déclaration d'indice et son utilisation
Récapitulons les propriétés calculées. Les indices suivent également la même syntaxe que celle des propriétés calculées. Pour les instances de type de requête, les indices sont écrits entre crochets suivis du nom de l'instance. La syntaxe de l'indice suit la même structure syntaxique que celle de la syntaxe «méthode d'instance» et «propriété calculée». Le mot-clé 'indice' est utilisé pour définir les indices et l'utilisateur peut spécifier un ou plusieurs paramètres avec leurs types de retour. Les indices peuvent avoir des propriétés en lecture-écriture ou en lecture seule et les instances sont stockées et récupérées à l'aide des propriétés «getter» et «setter» comme celles des propriétés calculées.
Syntaxe
subscript(index: Int) −> Int {
get {
// used for subscript value declarations
}
set(newValue) {
// definitions are written here
}
}
Exemple 1
struct subexample {
let decrementer: Int
subscript(index: Int) -> Int {
return decrementer / index
}
}
let division = subexample(decrementer: 100)
print("The number is divisible by \(division[9]) times")
print("The number is divisible by \(division[2]) times")
print("The number is divisible by \(division[3]) times")
print("The number is divisible by \(division[5]) times")
print("The number is divisible by \(division[7]) times")
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
The number is divisible by 11 times
The number is divisible by 50 times
The number is divisible by 33 times
The number is divisible by 20 times
The number is divisible by 14 times
Exemple2
class daysofaweek {
private var days = ["Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "saturday"]
subscript(index: Int) -> String {
get {
return days[index]
}
set(newValue) {
self.days[index] = newValue
}
}
}
var p = daysofaweek()
print(p[0])
print(p[1])
print(p[2])
print(p[3])
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Sunday
Monday
Tuesday
Wednesday
Options en indice
Les indices prennent un à plusieurs paramètres d'entrée et ces paramètres d'entrée appartiennent également à n'importe quel type de données. Ils peuvent également utiliser des paramètres variables et variadiques. Les indices ne peuvent pas fournir de valeurs de paramètre par défaut ni utiliser de paramètres d'entrée-sortie.
La définition de plusieurs indices est appelée «surcharge d'indice» où une classe ou une structure peut fournir plusieurs définitions d'indice selon les besoins. Ces indices multiples sont déduits en fonction des types de valeurs déclarées entre les accolades en indice.
struct Matrix {
let rows: Int, columns: Int
var print: [Double]
init(rows: Int, columns: Int) {
self.rows = rows
self.columns = columns
print = Array(count: rows * columns, repeatedValue: 0.0)
}
subscript(row: Int, column: Int) -> Double {
get {
return print[(row * columns) + column]
}
set {
print[(row * columns) + column] = newValue
}
}
}
var mat = Matrix(rows: 3, columns: 3)
mat[0,0] = 1.0
mat[0,1] = 2.0
mat[1,0] = 3.0
mat[1,1] = 5.0
print("\(mat[0,0])")
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
1.0
L'indice Swift 4 prend en charge un seul paramètre pour plusieurs déclarations de paramètres pour les types de données appropriés. Le programme déclare la structure 'Matrix' comme une matrice matricielle 2 * 2 dimensionnelle pour stocker les types de données 'Double'. Le paramètre Matrix est entré avec des types de données Integer pour déclarer des lignes et des colonnes.
Une nouvelle instance pour la matrice est créée en passant le nombre de lignes et de colonnes à l'initialisation comme indiqué ci-dessous.
var mat = Matrix(rows: 3, columns: 3)
Les valeurs de matrice peuvent être définies en passant les valeurs de ligne et de colonne dans l'indice, séparées par une virgule, comme indiqué ci-dessous.
mat[0,0] = 1.0
mat[0,1] = 2.0
mat[1,0] = 3.0
mat[1,1] = 5.0
La capacité de prendre plus de forme est définie comme l'héritage. En général, une classe peut hériter des méthodes, propriétés et fonctionnalités d'une autre classe. Les classes peuvent être classées en sous-classe et super classe.
Sub Class - lorsqu'une classe hérite des propriétés, méthodes et fonctions d'une autre classe, elle est appelée comme sous-classe
Super Class - La classe contenant des propriétés, des méthodes et des fonctions pour hériter d'autres classes d'elle-même est appelée comme une super classe
Les classes Swift 4 contiennent une superclasse qui appelle et accède aux méthodes, propriétés, fonctions et méthodes de substitution. En outre, les observateurs de propriétés sont également utilisés pour ajouter une propriété et modifier les méthodes de propriété stockées ou calculées.
Classe de base
Une classe qui n'hérite pas des méthodes, propriétés ou fonctions d'une autre classe est appelée «classe de base».
class StudDetails {
var stname: String!
var mark1: Int!
var mark2: Int!
var mark3: Int!
init(stname: String, mark1: Int, mark2: Int, mark3: Int) {
self.stname = stname
self.mark1 = mark1
self.mark2 = mark2
self.mark3 = mark3
}
}
let stname = "Swift 4"
let mark1 = 98
let mark2 = 89
let mark3 = 76
print(stname)
print(mark1)
print(mark2)
print(mark3)
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Swift 4
98
89
76
La classe avec le nom de classe StudDetails est définie ici comme une classe de base qui est utilisée pour contenir le nom des étudiants, et trois sujets marquent comme mark1, mark2 et mark3. Le mot-clé 'let' est utilisé pour initialiser la valeur de la classe de base et la valeur de la classe de base est affichée dans le terrain de jeu à l'aide de la fonction 'print'.
Sous-classe
L'action de baser une nouvelle classe sur une classe existante est définie comme «Sous-classe». La sous-classe hérite des propriétés, méthodes et fonctions de sa classe de base. Pour définir une sous-classe, «:» est utilisé avant le nom de la classe de base
class StudDetails {
var mark1: Int;
var mark2: Int;
init(stm1:Int, results stm2:Int) {
mark1 = stm1;
mark2 = stm2;
}
func print() {
print("Mark1:\(mark1), Mark2:\(mark2)")
}
}
class display : StudDetails {
init() {
super.init(stm1: 93, results: 89)
}
}
let marksobtained = display()
marksobtained.print()
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Mark1:93, Mark2:89
La classe «StudDetails» est définie comme une super classe où les notes des élèves sont déclarées et la sous-classe «display» est utilisée pour hériter des notes de sa super classe. La sous-classe définit les notes des étudiants et appelle la méthode print () pour afficher la note des étudiants.
Primordial
L'accès à l'instance de super-classe, aux méthodes de type, à l'instance, aux propriétés de type et à la sous-classe d'indices fournit le concept de remplacement. Le mot clé 'override' est utilisé pour remplacer les méthodes déclarées dans la superclasse.
Accès aux méthodes, propriétés et indices de super classe
Le mot clé 'super' est utilisé comme préfixe pour accéder aux méthodes, propriétés et indices déclarés dans la super classe
Primordial | Accès aux méthodes, propriétés et indices |
Méthodes | super.somemethod () |
Propriétés | super.someProperty () |
Les indices | super [someIndex] |
Remplacement des méthodes
Les méthodes d'instance et de type héritées peuvent être remplacées par le mot-clé 'override' par nos méthodes définies dans notre sous-classe. Ici, print () est remplacé dans la sous-classe pour accéder à la propriété type mentionnée dans la super classe print (). Une nouvelle instance de la super classe cricket () est également créée en tant que «cricinstance».
class cricket {
func print() {
print("Welcome to Swift 4 Super Class")
}
}
class tennis: cricket {
override func print() {
print("Welcome to Swift 4 Sub Class")
}
}
let cricinstance = cricket()
cricinstance.print()
let tennisinstance = tennis()
tennisinstance.print()
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Welcome to Swift Super Class
Welcome to Swift Sub Class
Remplacement de propriété
Vous pouvez remplacer une instance héritée ou une propriété de classe pour fournir vos propres getter et setter personnalisés pour cette propriété, ou pour ajouter des observateurs de propriété pour permettre à la propriété de remplacement d'observer quand la valeur de propriété sous-jacente change.
Remplacer les acquéreurs et les setters de propriété
Swift 4 permet à l'utilisateur de fournir un getter et un setter personnalisés pour remplacer la propriété héritée, qu'il s'agisse d'une propriété stockée ou calculée. La sous-classe ne connaît pas le nom et le type de propriété hérités. Par conséquent, il est essentiel que l'utilisateur spécifie dans la sous-classe, le nom et le type de la propriété de substitution spécifiée dans la super classe.
Cela peut être fait de deux manières -
Lorsque setter est défini pour la propriété de remplacement, l'utilisateur doit également définir getter.
Lorsque nous ne voulons pas modifier le getter de propriété hérité, nous pouvons simplement passer la valeur héritée par la syntaxe «super.someProperty» à la super classe.
class Circle {
var radius = 12.5
var area: String {
return "of rectangle for \(radius) "
}
}
class Rectangle: Circle {
var print = 7
override var area: String {
return super.area + " is now overridden as \(print)"
}
}
let rect = Rectangle()
rect.radius = 25.0
rect.print = 3
print("Radius \(rect.area)")
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Radius of rectangle for 25.0 is now overridden as 3
Remplacer les observateurs de propriété
Lorsqu'une nouvelle propriété doit être ajoutée pour une propriété héritée, le concept de «remplacement de propriété» est introduit dans Swift 4. Cela avertit l'utilisateur lorsque la valeur de propriété héritée est modifiée. Mais le remplacement n'est pas applicable pour les propriétés stockées constantes héritées et les propriétés calculées héritées en lecture seule.
class Circle {
var radius = 12.5
var area: String {
return "of rectangle for \(radius) "
}
}
class Rectangle: Circle {
var print = 7
override var area: String {
return super.area + " is now overridden as \(print)"
}
}
let rect = Rectangle()
rect.radius = 25.0
rect.print = 3
print("Radius \(rect.area)")
class Square: Rectangle {
override var radius: Double {
didSet {
print = Int(radius/5.0)+1
}
}
}
let sq = Square()
sq.radius = 100.0
print("Radius \(sq.area)")
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Radius of rectangle for 25.0 is now overridden as 3
Radius of rectangle for 100.0 is now overridden as 21
Propriété finale pour empêcher le remplacement
Lorsque l'utilisateur n'a pas besoin de vouloir que d'autres accèdent aux méthodes, propriétés ou indices de la super classe, Swift 4 introduit la propriété «finale» pour empêcher le remplacement. Une fois que la propriété 'finale' est déclarée, les indices ne permettront pas de remplacer les méthodes, propriétés et indices de la super classe. Il n'y a aucune disposition pour avoir la propriété «finale» dans la «super classe». Lorsque la propriété «finale» est déclarée, l'utilisateur est limité à créer d'autres sous-classes.
final class Circle {
final var radius = 12.5
var area: String {
return "of rectangle for \(radius) "
}
}
class Rectangle: Circle {
var print = 7
override var area: String {
return super.area + " is now overridden as \(print)"
}
}
let rect = Rectangle()
rect.radius = 25.0
rect.print = 3
print("Radius \(rect.area)")
class Square: Rectangle {
override var radius: Double {
didSet {
print = Int(radius/5.0)+1
}
}
}
let sq = Square()
sq.radius = 100.0
print("Radius \(sq.area)")
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
<stdin>:14:18: error: var overrides a 'final' var
override var area: String {
^
<stdin>:7:9: note: overridden declaration is here
var area: String {
^
<stdin>:12:11: error: inheritance from a final class 'Circle'
class Rectangle: Circle {
^
<stdin>:25:14: error: var overrides a 'final' var
override var radius: Double {
^
<stdin>:6:14: note: overridden declaration is here
final var radius = 12.5
Puisque la super classe est déclarée comme «finale» et que ses types de données sont également déclarés comme «finaux», le programme ne permettra pas de créer davantage de sous-classes et il lancera des erreurs.
Les classes, structures et énumérations une fois déclarées dans Swift 4 sont initialisées pour préparer l'instance d'une classe. La valeur initiale est initialisée pour la propriété stockée et également pour les nouvelles instances, les valeurs sont initialisées pour continuer. Le mot-clé pour créer la fonction d'initialisation est exécuté par la méthode 'init ()'. L'initialiseur Swift 4 diffère d'Objective-C en ce qu'il ne renvoie aucune valeur. Sa fonction est de vérifier l'initialisation des instances nouvellement créées avant son traitement. Swift 4 fournit également un processus de «désinitialisation» pour effectuer des opérations de gestion de la mémoire une fois que les instances sont désallouées.
Rôle d'initialisation pour les propriétés stockées
Les propriétés stockées doivent initialiser les instances de ses classes et structures avant de traiter les instances. Les propriétés stockées utilisent l'initialiseur pour affecter et initialiser des valeurs, éliminant ainsi la nécessité d'appeler des observateurs de propriétés. L'initialiseur est utilisé dans la propriété stockée
Pour créer une valeur initiale.
Pour attribuer une valeur de propriété par défaut dans la définition de propriété.
Pour initialiser une instance pour un type de données particulier, «init ()» est utilisé. Aucun argument n'est passé dans la fonction init ().
Syntaxe
init() {
//New Instance initialization goes here
}
Exemple
struct rectangle {
var length: Double
var breadth: Double
init() {
length = 6
breadth = 12
}
}
var area = rectangle()
print("area of rectangle is \(area.length*area.breadth)")
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
area of rectangle is 72.0
Ici, la structure «rectangle» est initialisée avec la longueur et la largeur des membres en tant que types de données «Double». La méthode Init () est utilisée pour initialiser les valeurs pour la longueur et le double des membres nouvellement créés. L'aire du rectangle est calculée et renvoyée en appelant la fonction rectangle.
Définition des valeurs de propriété par défaut
Le langage Swift 4 fournit la fonction Init () pour initialiser les valeurs de propriété stockées. En outre, l'utilisateur a la possibilité d'initialiser les valeurs de propriété par défaut lors de la déclaration des membres de la classe ou de la structure. Lorsque la propriété prend la même valeur seule dans tout le programme, nous pouvons la déclarer uniquement dans la section déclaration plutôt que de l'initialiser dans init (). La définition des valeurs de propriété par défaut active l'utilisateur lorsque l'héritage est défini pour les classes ou les structures.
struct rectangle {
var length = 6
var breadth = 12
}
var area = rectangle()
print("area of rectangle is \(area.length*area.breadth)")
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
area of rectangle is 72
Ici, au lieu de déclarer la longueur et la largeur dans init (), les valeurs sont initialisées dans la déclaration elle-même.
Initialisation des paramètres
En langage Swift 4, l'utilisateur a la possibilité d'initialiser les paramètres dans le cadre de la définition de l'initialiseur en utilisant init ().
struct Rectangle {
var length: Double
var breadth: Double
var area: Double
init(fromLength length: Double, fromBreadth breadth: Double) {
self.length = length
self.breadth = breadth
area = length * breadth
}
init(fromLeng leng: Double, fromBread bread: Double) {
self.length = leng
self.breadth = bread
area = leng * bread
}
}
let ar = Rectangle(fromLength: 6, fromBreadth: 12)
print("area is: \(ar.area)")
let are = Rectangle(fromLeng: 36, fromBread: 12)
print("area is: \(are.area)")
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
area is: 72.0
area is: 432.0
Paramètres locaux et externes
Les paramètres d'initialisation ont des noms de paramètres locaux et globaux similaires à ceux des paramètres de fonction et de méthode. La déclaration de paramètre local est utilisée pour accéder dans le corps d'initialisation et la déclaration de paramètre externe est utilisée pour appeler l'initialiseur. Les initialiseurs Swift 4 diffèrent des initialiseurs de fonction et de méthode en ce qu'ils n'identifient pas quel initialiseur est utilisé pour appeler quelles fonctions.
Pour surmonter cela, Swift 4 introduit un nom externe automatique pour chaque paramètre dans init (). Ce nom externe automatique est aussi équivalent que le nom local écrit avant chaque paramètre d'initialisation.
struct Days {
let sunday, monday, tuesday: Int
init(sunday: Int, monday: Int, tuesday: Int) {
self.sunday = sunday
self.monday = monday
self.tuesday = tuesday
}
init(daysofaweek: Int) {
sunday = daysofaweek
monday = daysofaweek
tuesday = daysofaweek
}
}
let week = Days(sunday: 1, monday: 2, tuesday: 3)
print("Days of a Week is: \(week.sunday)")
print("Days of a Week is: \(week.monday)")
print("Days of a Week is: \(week.tuesday)")
let weekdays = Days(daysofaweek: 4)
print("Days of a Week is: \(weekdays.sunday)")
print("Days of a Week is: \(weekdays.monday)")
print("Days of a Week is: \(weekdays.tuesday)")
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Days of a Week is: 1
Days of a Week is: 2
Days of a Week is: 3
Days of a Week is: 4
Days of a Week is: 4
Days of a Week is: 4
Paramètres sans noms externes
Lorsqu'un nom externe n'est pas nécessaire pour un tiret bas d'initialisation, «_» est utilisé pour remplacer le comportement par défaut.
struct Rectangle {
var length: Double
init(frombreadth breadth: Double) {
length = breadth * 10
}
init(frombre bre: Double) {
length = bre * 30
}
init(_ area: Double) {
length = area
}
}
let rectarea = Rectangle(180.0)
print("area is: \(rectarea.length)")
let rearea = Rectangle(370.0)
print("area is: \(rearea.length)")
let recarea = Rectangle(110.0)
print("area is: \(recarea.length)")
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
area is: 180.0
area is: 370.0
area is: 110.0
Types de propriété facultatifs
Lorsque la propriété stockée à une instance ne renvoie aucune valeur, cette propriété est déclarée avec un type «facultatif» indiquant qu'aucune valeur n'est renvoyée pour ce type particulier. Lorsque la propriété stockée est déclarée comme «facultative», elle initialise automatiquement la valeur à «nil» lors de l'initialisation elle-même.
struct Rectangle {
var length: Double?
init(frombreadth breadth: Double) {
length = breadth * 10
}
init(frombre bre: Double) {
length = bre * 30
}
init(_ area: Double) {
length = area
}
}
let rectarea = Rectangle(180.0)
print("area is: \(rectarea.length)")
let rearea = Rectangle(370.0)
print("area is: \(rearea.length)")
let recarea = Rectangle(110.0)
print("area is: \(recarea.length)")
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
area is: Optional(180.0)
area is: Optional(370.0)
area is: Optional(110.0)
Modification des propriétés des constantes lors de l'initialisation
L'initialisation permet également à l'utilisateur de modifier également la valeur de la propriété constante. Lors de l'initialisation, la propriété de classe permet à ses instances de classe d'être modifiées par la super classe et non par la sous-classe. Considérez par exemple dans le programme précédent que «longueur» est déclarée comme «variable» dans la classe principale. La variable de programme ci-dessous «longueur» est modifiée en tant que variable «constante».
struct Rectangle {
let length: Double?
init(frombreadth breadth: Double) {
length = breadth * 10
}
init(frombre bre: Double) {
length = bre * 30
}
init(_ area: Double) {
length = area
}
}
let rectarea = Rectangle(180.0)
print("area is: \(rectarea.length)")
let rearea = Rectangle(370.0)
print("area is: \(rearea.length)")
let recarea = Rectangle(110.0)
print("area is: \(recarea.length)")
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
area is: Optional(180.0)
area is: Optional(370.0)
area is: Optional(110.0)
Initialiseurs par défaut
Les initialiseurs par défaut fournissent une nouvelle instance à toutes ses propriétés déclarées de classe de base ou de structure avec des valeurs par défaut.
class defaultexample {
var studname: String?
var stmark = 98
var pass = true
}
var result = defaultexample()
print("result is: \(result.studname)")
print("result is: \(result.stmark)")
print("result is: \(result.pass)")
Lorsque nous exécutons le programme ci-dessus en utilisant le terrain de jeu, nous obtenons le résultat suivant. -
result is: nil
result is: 98
result is: true
Le programme ci-dessus est défini avec le nom de classe «defaultexample». Trois fonctions membres sont initialisées par défaut en tant que 'studname?' pour stocker les valeurs «nil», «stmark» comme 98 et «pass» comme valeur booléenne «true». De même, les valeurs de membre de la classe peuvent être initialisées par défaut avant de traiter les types de membre de classe.
Initialiseurs Memberwise pour les types de structure
Lorsque les initialiseurs personnalisés ne sont pas fournis par l'utilisateur, les types de structure dans Swift 4 recevront automatiquement l '«initialiseur par membre». Sa fonction principale est d'initialiser les nouvelles instances de structure avec l'initialisation par défaut des membres, puis les nouvelles propriétés d'instance sont transmises à l'initialisation des membres par leur nom.
struct Rectangle {
var length = 100.0, breadth = 200.0
}
let area = Rectangle(length: 24.0, breadth: 32.0)
print("Area of rectangle is: \(area.length)")
print("Area of rectangle is: \(area.breadth)")
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Area of rectangle is: 24.0
Area of rectangle is: 32.0
Les structures sont initialisées par défaut pour leurs fonctions d'appartenance lors de l'initialisation pour «longueur» comme «100,0» et «largeur» comme «200,0». Mais les valeurs sont remplacées lors du traitement des variables longueur et largeur comme 24,0 et 32,0.
Délégation d'initialiseur pour les types de valeur
La délégation d'initialisation est définie comme l'appel d'initialiseurs à partir d'autres initialiseurs. Sa fonction principale est d'agir comme une réutilisabilité pour éviter la duplication de code entre plusieurs initialiseurs.
struct Stmark {
var mark1 = 0.0, mark2 = 0.0
}
struct stdb {
var m1 = 0.0, m2 = 0.0
}
struct block {
var average = stdb()
var result = Stmark()
init() {}
init(average: stdb, result: Stmark) {
self.average = average
self.result = result
}
init(avg: stdb, result: Stmark) {
let tot = avg.m1 - (result.mark1 / 2)
let tot1 = avg.m2 - (result.mark2 / 2)
self.init(average: stdb(m1: tot, m2: tot1), result: result)
}
}
let set1 = block()
print("student result is: \(set1.average.m1, set1.average.m2)
\(set1.result.mark1, set1.result.mark2)")
let set2 = block(average: stdb(m1: 2.0, m2: 2.0),
result: Stmark(mark1: 5.0, mark2: 5.0))
print("student result is: \(set2.average.m1, set2.average.m2)
\(set2.result.mark1, set2.result.mark2)")
let set3 = block(avg: stdb(m1: 4.0, m2: 4.0),
result: Stmark(mark1: 3.0, mark2: 3.0))
print("student result is: \(set3.average.m1, set3.average.m2)
\(set3.result.mark1, set3.result.mark2)")
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
(0.0,0.0) (0.0,0.0)
(2.0,2.0) 5.0,5.0)
(2.5,2.5) (3.0,3.0)
Règles de délégation d'initialiseur
Types de valeur | Types de classe |
---|---|
L'héritage n'est pas pris en charge pour les types valeur tels que les structures et les énumérations. La référence à d'autres initialiseurs se fait via self.init | L'héritage est pris en charge. Vérifie que toutes les valeurs de propriété stockées sont initialisées |
Héritage et initialisation de classe
Les types de classe ont deux types d'initialiseurs pour vérifier si les propriétés stockées définies reçoivent une valeur initiale, à savoir les initialiseurs désignés et les initialiseurs pratiques.
Initialiseurs désignés et initialiseurs de commodité
Initialiseur désigné | Initialiseur de commodité |
---|---|
Considéré comme l'initialisation principale d'une classe | Considéré comme supportant l'initialisation pour une classe |
Toutes les propriétés de classe sont initialisées et un initialiseur de superclasse approprié est appelé pour une initialisation supplémentaire | Un initialiseur désigné est appelé avec un initialiseur pratique pour créer une instance de classe pour un cas d'utilisation spécifique ou un type de valeur d'entrée |
Au moins un initialiseur désigné est défini pour chaque classe | Pas besoin d'avoir des initialiseurs de commodité obligatoires définis lorsque la classe ne nécessite pas d'initialiseurs. |
Init (paramètres) {instructions} | commodité init (paramètres) {instructions} |
Programme pour les initialiseurs désignés
class mainClass {
var no1 : Int // local storage
init(no1 : Int) {
self.no1 = no1 // initialization
}
}
class subClass : mainClass {
var no2 : Int // new subclass storage
init(no1 : Int, no2 : Int) {
self.no2 = no2 // initialization
super.init(no1:no1) // redirect to superclass
}
}
let res = mainClass(no1: 10)
let print = subClass(no1: 10, no2: 20)
print("res is: \(res.no1)")
print("res is: \(print.no1)")
print("res is: \(print.no2)")
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
res is: 10
res is: 10
res is: 20
Programme pour les initialiseurs de commodité
class mainClass {
var no1 : Int // local storage
init(no1 : Int) {
self.no1 = no1 // initialization
}
}
class subClass : mainClass {
var no2 : Int
init(no1 : Int, no2 : Int) {
self.no2 = no2
super.init(no1:no1)
}
// Requires only one parameter for convenient method
override convenience init(no1: Int) {
self.init(no1:no1, no2:0)
}
}
let res = mainClass(no1: 20)
let print = subClass(no1: 30, no2: 50)
print("res is: \(res.no1)")
print("res is: \(print.no1)")
print("res is: \(print.no2)")
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
res is: 20
res is: 30
res is: 50
Héritage et remplacement de l'initialiseur
Swift 4 ne permet pas à ses sous-classes d'hériter par défaut de ses initialiseurs de superclasse pour leurs types de membres. L'héritage n'est applicable aux initialiseurs de super classe que dans une certaine mesure, ce qui sera discuté dans Héritage d'initialisation automatique.
Lorsque l'utilisateur a besoin d'avoir des initialiseurs définis dans la super classe, la sous-classe avec les initialiseurs doit être définie par l'utilisateur comme une implémentation personnalisée. Lorsque le remplacement doit être effectué par la sous-classe, le mot-clé «override» de la super classe doit être déclaré.
class sides {
var corners = 4
var description: String {
return "\(corners) sides"
}
}
let rectangle = sides()
print("Rectangle: \(rectangle.description)")
class pentagon: sides {
override init() {
super.init()
corners = 5
}
}
let bicycle = pentagon()
print("Pentagon: \(bicycle.description)")
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Rectangle: 4 sides
Pentagon: 5 sides
Initialiseurs désignés et pratiques en action
class Planet {
var name: String
init(name: String) {
self.name = name
}
convenience init() {
self.init(name: "[No Planets]")
}
}
let plName = Planet(name: "Mercury")
print("Planet name is: \(plName.name)")
let noplName = Planet()
print("No Planets like that: \(noplName.name)")
class planets: Planet {
var count: Int
init(name: String, count: Int) {
self.count = count
super.init(name: name)
}
override convenience init(name: String) {
self.init(name: name, count: 1)
}
}
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Planet name is: Mercury
No Planets like that: [No Planets]
Initialiseur disponible
L'utilisateur doit être averti en cas d'échec de l'initialisation lors de la définition d'une classe, d'une structure ou de valeurs d'énumération. L'initialisation des variables devient parfois un échec en raison de -
- Valeurs de paramètre non valides.
- Absence de source externe requise.
- Condition empêchant l'initialisation de réussir.
Pour intercepter les exceptions lancées par la méthode d'initialisation, Swift 4 produit une initialisation flexible appelée «initialiseur failable» pour informer l'utilisateur que quelque chose est laissé inaperçu lors de l'initialisation de la structure, de la classe ou des membres de l'énumération. Le mot clé pour attraper l'initialiseur disponible est «init?». De plus, les initialiseurs disponibles et non disponibles ne peuvent pas être définis avec les mêmes types et noms de paramètres.
struct studrecord {
let stname: String
init?(stname: String) {
if stname.isEmpty {return nil }
self.stname = stname
}
}
let stmark = studrecord(stname: "Swing")
if let name = stmark {
print("Student name is specified")
}
let blankname = studrecord(stname: "")
if blankname == nil {
print("Student name is left blank")
}
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Student name is specified
Student name is left blank
Initialiseurs disponibles pour les énumérations
Le langage Swift 4 offre la flexibilité d'avoir des initialiseurs disponibles pour les énumérations afin d'avertir l'utilisateur lorsque les membres de l'énumération sont laissés de l'initialisation des valeurs.
enum functions {
case a, b, c, d
init?(funct: String) {
switch funct {
case "one":
self = .a
case "two":
self = .b
case "three":
self = .c
case "four":
self = .d
default:
return nil
}
}
}
let result = functions(funct: "two")
if result != nil {
print("With In Block Two")
}
let badresult = functions(funct: "five")
if badresult == nil {
print("Block Does Not Exist")
}
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
With In Block Two
Block Does Not Exist
Initialiseurs disponibles pour les classes
Un initialiseur disponible lorsqu'il est déclaré avec des énumérations et des structures alerte un échec d'initialisation en toute circonstance dans son implémentation. Cependant, l'initialiseur disponible dans les classes n'alertera l'échec qu'une fois que les propriétés stockées auront été définies sur une valeur initiale.
class studrecord {
let studname: String!
init?(studname: String) {
self.studname = studname
if studname.isEmpty { return nil }
}
}
if let stname = studrecord(studname: "Failable Initializers") {
print("Module is \(stname.studname)")
}
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Module is Optional("Failable Initializers")
Remplacement d'un initialiseur disponible
Comme pour initialize, l'utilisateur a également la possibilité de remplacer un initialiseur disponible de superclasse dans la sous-classe. L'initialisation disponible de la super classe peut également être remplacée par un initialiseur de sous-classe non disponible.
L'initialiseur de sous-classe ne peut pas déléguer jusqu'à l'initialiseur de superclasse lors du remplacement d'un initialiseur de superclasse disponible avec une initialisation de sous-classe non disponible.
Un initialiseur non disponible ne peut jamais déléguer à un initialiseur disponible.
Le programme ci-dessous décrit les initialiseurs disponibles et non disponibles.
class Planet {
var name: String
init(name: String) {
self.name = name
}
convenience init() {
self.init(name: "[No Planets]")
}
}
let plName = Planet(name: "Mercury")
print("Planet name is: \(plName.name)")
let noplName = Planet()
print("No Planets like that: \(noplName.name)")
class planets: Planet {
var count: Int
init(name: String, count: Int) {
self.count = count
super.init(name: name)
}
override convenience init(name: String) {
self.init(name: name, count: 1)
}
}
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Planet name is: Mercury
No Planets like that: [No Planets]
L'init! Initialiseur disponible
Swift 4 fournit «init?» pour définir un initialiseur facultatif d'instance disponible. Pour définir une instance facultative implicitement déroulée du type spécifique 'init!' est spécifié.
struct studrecord {
let stname: String
init!(stname: String) {
if stname.isEmpty {return nil }
self.stname = stname
}
}
let stmark = studrecord(stname: "Swing")
if let name = stmark {
print("Student name is specified")
}
let blankname = studrecord(stname: "")
if blankname == nil {
print("Student name is left blank")
}
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Student name is specified
Student name is left blank
Initialiseurs requis
Pour déclarer chaque sous-classe du mot clé initialize 'required' doit être défini avant la fonction init ().
class classA {
required init() {
var a = 10
print(a)
}
}
class classB: classA {
required init() {
var b = 30
print(b)
}
}
let res = classA()
let print = classB()
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
10
30
10
Avant qu'une instance de classe ne doive être désallouée, «deinitializer» doit être appelé pour désallouer l'espace mémoire. Le mot-clé 'deinit' est utilisé pour désallouer les espaces mémoire occupés par les ressources système. La déinitialisation n'est disponible que sur les types de classe.
Désinitialisation pour désallouer de l'espace mémoire
Swift 4 désalloue automatiquement vos instances lorsqu'elles ne sont plus nécessaires, pour libérer des ressources. Swift 4 gère la gestion de la mémoire des instances via le comptage automatique des références (ARC), comme décrit dans Comptage automatique des références. En règle générale, vous n'avez pas besoin d'effectuer un nettoyage manuel lorsque vos instances sont désallouées. Cependant, lorsque vous travaillez avec vos propres ressources, vous devrez peut-être effectuer vous-même un nettoyage supplémentaire. Par exemple, si vous créez une classe personnalisée pour ouvrir un fichier et y écrire des données, vous devrez peut-être fermer le fichier avant que l'instance de classe ne soit libérée.
var counter = 0; // for reference counting
class baseclass {
init() {
counter++;
}
deinit {
counter--;
}
}
var print: baseclass? = baseclass()
print(counter)
print = nil
print(counter)
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
1
0
Lorsque l'instruction print = nil est omise, les valeurs du compteur conservent les mêmes car il n'est pas désinitialisé.
var counter = 0; // for reference counting
class baseclass {
init() {
counter++;
}
deinit {
counter--;
}
}
var print: baseclass? = baseclass()
print(counter)
print(counter)
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
1
1
Les fonctions de gestion de la mémoire et son utilisation sont gérées en langage Swift 4 via le comptage automatique des références (ARC). ARC est utilisé pour initialiser et désinitialiser les ressources système, libérant ainsi les espaces mémoire utilisés par les instances de classe lorsque les instances ne sont plus nécessaires. ARC garde une trace des informations sur les relations entre nos instances de code pour gérer efficacement les ressources mémoire.
Fonctions de l'ARC
ARC alloue un morceau de mémoire pour stocker les informations à chaque fois qu'une nouvelle instance de classe est créée par init ().
Les informations sur le type d'instance et ses valeurs sont stockées en mémoire.
Lorsque l'instance de classe n'est plus nécessaire, elle libère automatiquement l'espace mémoire par deinit () pour un stockage et une récupération supplémentaires de l'instance de classe.
ARC garde une trace des propriétés, des constantes et des variables des instances de classe actuellement référencées afin que deinit () ne soit appliqué qu'à ces instances inutilisées.
ARC maintient une «référence forte» à ces propriétés, constantes et variables d'instance de classe pour restreindre la désallocation lorsque l'instance de classe est actuellement utilisée.
Programme ARC
class StudDetails {
var stname: String!
var mark: Int!
init(stname: String, mark: Int) {
self.stname = stname
self.mark = mark
}
deinit {
print("Deinitialized \(self.stname)")
print("Deinitialized \(self.mark)")
}
}
let stname = "Swift 4"
let mark = 98
print(stname)
print(mark)
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Swift 4
98
Instances de classe ARC Strong Reference Cycles
class studmarks {
let name: String
var stud: student?
init (name: String) {
print("Initializing: \(name)")
self.name = name
}
deinit {
print("Deallocating: \(self.name)")
}
}
class student {
let name: String
var strname: studmarks?
init (name: String) {
print("Initializing: \(name)")
self.name = name
}
deinit {
print("Deallocating: \(self.name)")
}
}
var shiba: studmarks?
var mari: student?
shiba = studmarks(name: "Swift 4")
mari = student(name: "ARC")
shiba!.stud = mari
mari!.strname = shiba
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Initializing: Swift 4
Initializing: ARC
Références faibles et inconnues de l'ARC
Les propriétés de type de classe ont deux façons de résoudre les cycles de référence forts -
- Références faibles
- Références non propriétaires
Ces références sont utilisées pour permettre à une instance de référencer d'autres instances dans un cycle de référence. Ensuite, les instances peuvent faire référence à chaque instance au lieu de se soucier du cycle de référence fort. Lorsque l'utilisateur sait qu'une instance peut renvoyer des valeurs «nil», nous pouvons le signaler en utilisant une référence faible. Lorsque l'instance va retourner quelque chose plutôt que nil, déclarez-la avec une référence sans propriétaire.
Programme de référence faible
class module {
let name: String
init(name: String) { self.name = name }
var sub: submodule?
deinit { print("\(name) Is The Main Module") }
}
class submodule {
let number: Int
init(number: Int) { self.number = number }
weak var topic: module?
deinit { print("Sub Module with its topic number is \(number)") }
}
var toc: module?
var list: submodule?
toc = module(name: "ARC")
list = submodule(number: 4)
toc!.sub = list
list!.topic = toc
toc = nil
list = nil
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
ARC Is The Main Module
Sub Module with its topic number is 4
Programme de référence sans propriétaire
class student {
let name: String
var section: marks?
init(name: String) {
self.name = name
}
deinit { print("\(name)") }
}
class marks {
let marks: Int
unowned let stname: student
init(marks: Int, stname: student) {
self.marks = marks
self.stname = stname
}
deinit { print("Marks Obtained by the student is \(marks)") }
}
var module: student?
module = student(name: "ARC")
module!.section = marks(marks: 98, stname: module!)
module = nil
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
ARC
Marks Obtained by the student is 98
Cycles de référence solides pour les fermetures
Lorsque nous affectons une fermeture à la propriété d'instance de classe et au corps de la fermeture pour capturer une instance particulière, un cycle de référence fort peut se produire. Une référence forte à la fermeture est définie par «self.someProperty» ou «self.someMethod ()». Des cycles de référence forts sont utilisés comme types de référence pour les fermetures.
class HTMLElement {
let samplename: String
let text: String?
lazy var asHTML: () -> String = {
if let text = self.text {
return "<\(self.samplename)>\(text)</\(self.samplename)>"
} else {
return "<\(self.samplename) />"
}
}
init(samplename: String, text: String? = nil) {
self.samplename = samplename
self.text = text
}
deinit {
print("\(samplename) is being deinitialized")
}
}
var paragraph: HTMLElement? = HTMLElement(samplename: "p", text: "Welcome to Closure SRC")
print(paragraph!.asHTML())
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
<p>Welcome to Closure SRC</p>
Références faibles et inconnues
Lorsque la fermeture et l'instance se réfèrent l'une à l'autre, l'utilisateur peut définir la capture dans une fermeture comme une référence sans propriétaire. Ensuite, cela ne permettrait pas à l'utilisateur de désallouer l'instance en même temps. Lorsque l'instance renvoie parfois une valeur «nil», définissez la fermeture avec l'instance faible.
class HTMLElement {
let module: String
let text: String?
lazy var asHTML: () -> String = {
[unowned self] in
if let text = self.text {
return "<\(self.module)>\(text)</\(self.module)>"
} else {
return "<\(self.module) />"
}
}
init(module: String, text: String? = nil) {
self.module = module
self.text = text
}
deinit {
print("\(module) the deinit()")
}
}
var paragraph: HTMLElement? = HTMLElement(module: "Inside", text: "ARC Weak References")
print(paragraph!.asHTML())
paragraph = nil
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
<Inside>ARC Weak References</Inside>
Inside the deinit()
Le processus d'interrogation, d'appel des propriétés, des indices et des méthodes sur une option qui peut être «nil» est défini comme un chaînage facultatif. Le chaînage facultatif renvoie deux valeurs -
si l'option contient une 'valeur', l'appel de sa propriété, de ses méthodes et de ses indices associés renvoie des valeurs
si l'option contient une valeur 'nil', toutes ses propriétés, méthodes et indices associés renvoient nil
Étant donné que plusieurs requêtes aux méthodes, propriétés et indices sont regroupées, l'échec d'une chaîne affectera toute la chaîne et se traduira par une valeur «nil».
Chaînage facultatif comme alternative au déballage forcé
Le chaînage facultatif est spécifié après la valeur facultative avec '?' pour appeler une propriété, une méthode ou un indice lorsque la valeur facultative renvoie des valeurs.
Chaînage facultatif '?' | Accès aux méthodes, propriétés et indices Chaînage optionnel '!' pour forcer le déballage |
? est placé après la valeur facultative pour appeler la propriété, la méthode ou l'indice | ! est placé après la valeur facultative pour appeler la propriété, la méthode ou l'indice pour forcer le déroulement de la valeur |
Échoue gracieusement lorsque l'option est «nil» | Le déballage forcé déclenche une erreur d'exécution lorsque l'option est «nil» |
Programme de chaînage optionnel avec '!'
class ElectionPoll {
var candidate: Pollbooth?
}
lass Pollbooth {
var name = "MP"
}
let cand = ElectionPoll()
let candname = cand.candidate!.name
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
fatal error: unexpectedly found nil while unwrapping an Optional value
0 Swift 4 0x0000000103410b68
llvm::sys::PrintStackTrace(__sFILE*) + 40
1 Swift 4 0x0000000103411054 SignalHandler(int) + 452
2 libsystem_platform.dylib 0x00007fff9176af1a _sigtramp + 26
3 libsystem_platform.dylib 0x000000000000000b _sigtramp + 1854492939
4 libsystem_platform.dylib 0x00000001074a0214 _sigtramp + 1976783636
5 Swift 4 0x0000000102a85c39
llvm::JIT::runFunction(llvm::Function*, std::__1::vector > const&) + 329
6 Swift 4 0x0000000102d320b3
llvm::ExecutionEngine::runFunctionAsMain(llvm::Function*,
std::__1::vector<std::__1::basic_string, std::__1::allocator >,
std::__1::allocator<std::__1::basic_string, std::__1::allocator > > > const&,
char const* const*) + 1523
7 Swift 4 0x000000010296e6ba Swift 4::RunImmediately(Swift
4::CompilerInstance&, std::__1::vector<std::__1::basic_string,
std::__1::allocator >, std::__1::allocator<std::__1::basic_string,
std::__1::allocator > > > const&, Swift 4::IRGenOptions&, Swift 4::SILOptions
const&) + 1066
8 Swift 4 0x000000010275764b frontend_main(llvm::ArrayRef,
char const*, void*) + 5275
9 Swift 4 0x0000000102754a6d main + 1677
10 libdyld.dylib 0x00007fff8bb9e5c9 start + 1
11 libdyld.dylib 0x000000000000000c start + 1950751300
Stack dump:
0. Program arguments:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/
usr/bin/Swift 4 -frontend -interpret - -target x86_64-apple-darwin14.0.0 -
target-cpu core2 -sdk
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/
SDKs/MacOSX10.10.sdk -module-name main
/bin/sh: line 47: 15672 Done cat <<'SWIFT 4'
import Foundation
</std::__1::basic_string</std::__1::basic_string</std::__1::basic_string</std::
__1::basic_string
Le programme ci-dessus déclare «scrutin d'élection» comme nom de classe et contient «candidat» comme fonction d'appartenance. La sous-classe est déclarée comme «cabine de vote» et «nom» comme sa fonction d'appartenance qui est initialisée comme «MP». L'appel à la super classe est initialisé en créant une instance «cand» avec facultatif «!». Puisque les valeurs ne sont pas déclarées dans sa classe de base, la valeur «nil» est stockée, renvoyant ainsi une erreur fatale par la procédure de déballage forcé.
Programme de chaînage optionnel avec '?'
class ElectionPoll {
var candidate: Pollbooth?
}
class Pollbooth {
var name = "MP"
}
let cand = ElectionPoll()
if let candname = cand.candidate?.name {
print("Candidate name is \(candname)")
} else {
print("Candidate name cannot be retreived")
}
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Candidate name cannot be retreived
Le programme ci-dessus déclare 'scrutin' comme nom de classe et contient 'candidat' comme fonction d'appartenance. La sous-classe est déclarée comme «cabine de vote» et «nom» comme sa fonction d'appartenance qui est initialisée comme «MP». L'appel à la super classe est initialisé en créant une instance «cand» avec facultatif «?». Puisque les valeurs ne sont pas déclarées dans sa classe de base, la valeur «nil» est stockée et imprimée dans la console par le bloc de gestionnaire else.
Définition de classes de modèle pour le chaînage facultatif et l'accès aux propriétés
Le langage Swift 4 fournit également le concept de chaînage facultatif, pour déclarer plus d'une sous-classe en tant que classes de modèle. Ce concept sera très utile pour définir des modèles complexes et accéder aux propriétés, méthodes et sous-propriétés des sous-propriétés.
class rectangle {
var print: circle?
}
class circle {
var area = [radius]()
var cprint: Int {
return area.count
}
subscript(i: Int) -> radius {
get {
return area[i]
}
set {
area[i] = newValue
}
}
func circleprint() {
print("The number of rooms is \(cprint)")
}
var rectarea: circumference?
}
class radius {
let radiusname: String
init(radiusname: String) { self.radiusname = radiusname }
}
class circumference {
var circumName: String?
var circumNumber: String?
var street: String?
func buildingIdentifier() -> String? {
if circumName != nil {
return circumName
} else if circumNumber != nil {
return circumNumber
} else {
return nil
}
}
}
let rectname = rectangle()
if let rectarea = rectname.print?.cprint {
print("Area of rectangle is \(rectarea)")
} else {
print("Rectangle Area is not specified")
}
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Rectangle Area is not specified
Appel de méthodes via un chaînage facultatif
class rectangle {
var print: circle?
}
class circle {
var area = [radius]()
var cprint: Int {
return area.count
}
subscript(i: Int) -> radius {
get {
return area[i]
}
set {
area[i] = newValue
}
}
func circleprint() {
print("Area of Circle is: \(cprint)")
}
var rectarea: circumference?
}
class radius {
let radiusname: String
init(radiusname: String) { self.radiusname = radiusname }
}
class circumference {
var circumName: String?
var circumNumber: String?
var circumarea: String?
func buildingIdentifier() -> String? {
if circumName != nil {
return circumName
} else if circumNumber != nil {
return circumNumber
} else {
return nil
}
}
}
let circname = rectangle()
if circname.print?.circleprint() != nil {
print("Area of circle is specified)")
} else {
print("Area of circle is not specified")
}
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Area of circle is not specified
La fonction circleprint () déclarée dans la sous-classe circle () est appelée en créant une instance nommée 'circname'. La fonction retournera une valeur si elle contient une valeur, sinon elle retournera un message d'impression défini par l'utilisateur en vérifiant l'instruction 'if circname.print? .Circleprint ()! = Nil'.
Accès aux abonnements via le chaînage facultatif
Le chaînage facultatif est utilisé pour définir et récupérer une valeur d'indice pour valider si l'appel à cet indice renvoie une valeur. '?' est placé avant les accolades de l'indice pour accéder à la valeur facultative de l'indice particulier.
Programme 1
class rectangle {
var print: circle?
}
class circle {
var area = [radius]()
var cprint: Int {
return area.count
}
subscript(i: Int) -> radius {
get {
return area[i]
}
set {
area[i] = newValue
}
}
func circleprint() {
print("The number of rooms is \(cprint)")
}
var rectarea: circumference?
}
class radius {
let radiusname: String
init(radiusname: String) { self.radiusname = radiusname }
}
class circumference {
var circumName: String?
var circumNumber: String?
var circumarea: String?
func buildingIdentifier() -> String? {
if circumName != nil {
return circumName
} else if circumNumber != nil {
return circumNumber
} else {
return nil
}
}
}
let circname = rectangle()
if let radiusName = circname.print?[0].radiusname {
print("The first room name is \(radiusName).")
} else {
print("Radius is not specified.")
}
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Radius is not specified.
Dans le programme ci-dessus, les valeurs d'instance de la fonction d'appartenance 'radiusName' ne sont pas spécifiées. Par conséquent, l'appel du programme à la fonction ne retournera que d'autre part tandis que pour renvoyer les valeurs, nous devons définir les valeurs de la fonction d'appartenance particulière.
Programme 2
class rectangle {
var print: circle?
}
class circle {
var area = [radius]()
var cprint: Int {
return area.count
}
subscript(i: Int) -> radius {
get {
return area[i]
}
set {
area[i] = newValue
}
}
func circleprint() {
print("The number of rooms is \(cprint)")
}
var rectarea: circumference?
}
class radius {
let radiusname: String
init(radiusname: String) { self.radiusname = radiusname }
}
class circumference {
var circumName: String?
var circumNumber: String?
var circumarea: String?
func buildingIdentifier() -> String? {
if circumName != nil {
return circumName
} else if circumNumber != nil {
return circumNumber
} else {
return nil
}
}
}
let circname = rectangle()
circname.print?[0] = radius(radiusname: "Diameter")
let printing = circle()
printing.area.append(radius(radiusname: "Units"))
printing.area.append(radius(radiusname: "Meter"))
circname.print = printing
if let radiusName = circname.print?[0].radiusname {
print("Radius is measured in \(radiusName).")
} else {
print("Radius is not specified.")
}
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Radius is measured in Units.
Dans le programme ci-dessus, les valeurs d'instance pour la fonction d'appartenance 'radiusName' sont spécifiées. Par conséquent, l'appel du programme à la fonction renverra désormais des valeurs.
Accès aux indices de type facultatif
class rectangle {
var print: circle?
}
class circle {
var area = [radius]()
var cprint: Int {
return area.count
}
subscript(i: Int) -> radius {
get {
return area[i]
}
set {
area[i] = newValue
}
}
func circleprint() {
print("The number of rooms is \(cprint)")
}
var rectarea: circumference?
}
class radius {
let radiusname: String
init(radiusname: String) { self.radiusname = radiusname }
}
class circumference {
var circumName: String?
var circumNumber: String?
var circumarea: String?
func buildingIdentifier() -> String? {
if circumName != nil {
return circumName
} else if circumNumber != nil {
return circumNumber
} else {
return nil
}
}
}
let circname = rectangle()
circname.print?[0] = radius(radiusname: "Diameter")
let printing = circle()
printing.area.append(radius(radiusname: "Units"))
printing.area.append(radius(radiusname: "Meter"))
circname.print = printing
var area = ["Radius": [35, 45, 78, 101], "Circle": [90, 45, 56]]
area["Radius"]?[1] = 78
area["Circle"]?[1]--
print(area["Radius"]?[0])
print(area["Radius"]?[1])
print(area["Radius"]?[2])
print(area["Radius"]?[3])
print(area["Circle"]?[0])
print(area["Circle"]?[1])
print(area["Circle"]?[2])
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Optional(35)
Optional(78)
Optional(78)
Optional(101)
Optional(90)
Optional(44)
Optional(56)
Les valeurs facultatives des indices sont accessibles en se référant à leurs valeurs d'indice. Il est accessible en indice [0], indice [1] etc. Les valeurs d'indice par défaut pour 'rayon' sont d'abord attribuées comme [35, 45, 78, 101] et pour 'Cercle' [90, 45, 56]] . Ensuite, les valeurs de l'indice sont modifiées en tant que Rayon [0] à 78 et Cercle [1] à 45.
Lier plusieurs niveaux de chaînage
Plusieurs sous-classes peuvent également être liées à ses méthodes, propriétés et indices de super classe par chaînage facultatif.
Le chaînage multiple des options peut être lié -
Si la récupération du type n'est pas facultative, le chaînage facultatif renverra une valeur facultative. Par exemple, si String via le chaînage facultatif, il retournera String? Valeur
class rectangle {
var print: circle?
}
class circle {
var area = [radius]()
var cprint: Int {
return area.count
}
subscript(i: Int) -> radius {
get {
return area[i]
}
set {
area[i] = newValue
}
}
func circleprint() {
print("The number of rooms is \(cprint)")
}
var rectarea: circumference?
}
class radius {
let radiusname: String
init(radiusname: String) { self.radiusname = radiusname }
}
class circumference {
var circumName: String?
var circumNumber: String?
var circumarea: String?
func buildingIdentifier() -> String? {
if circumName != nil {
return circumName
} else if circumNumber != nil {
return circumNumber
} else {
return nil
}
}
}
let circname = rectangle()
if let radiusName = circname.print?[0].radiusname {
print("The first room name is \(radiusName).")
} else {
print("Radius is not specified.")
}
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Radius is not specified.
Dans le programme ci-dessus, les valeurs d'instance de la fonction d'appartenance 'radiusName' ne sont pas spécifiées. Par conséquent, l'appel du programme à la fonction ne retournera qu'une partie du reste, tandis que pour renvoyer les valeurs, nous devons définir les valeurs de la fonction d'appartenance particulière.
Si le type de récupération est déjà facultatif, le chaînage facultatif renverra également une valeur facultative. Par exemple, si String? Est-ce accessible via un chaînage facultatif, il retournera String? Valeur..
class rectangle {
var print: circle?
}
class circle {
var area = [radius]()
var cprint: Int {
return area.count
}
subscript(i: Int) -> radius {
get {
return area[i]
}
set {
area[i] = newValue
}
}
func circleprint() {
print("The number of rooms is \(cprint)")
}
var rectarea: circumference?
}
class radius {
let radiusname: String
init(radiusname: String) { self.radiusname = radiusname }
}
class circumference {
var circumName: String?
var circumNumber: String?
var circumarea: String?
func buildingIdentifier() -> String? {
if circumName != nil {
return circumName
} else if circumNumber != nil {
return circumNumber
} else {
return nil
}
}
}
let circname = rectangle()
circname.print?[0] = radius(radiusname: "Diameter")
let printing = circle()
printing.area.append(radius(radiusname: "Units"))
printing.area.append(radius(radiusname: "Meter"))
circname.print = printing
if let radiusName = circname.print?[0].radiusname {
print("Radius is measured in \(radiusName).")
} else {
print("Radius is not specified.")
}
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Radius is measured in Units.
Dans le programme ci-dessus, les valeurs d'instance pour la fonction d'appartenance 'radiusName' sont spécifiées. Par conséquent, l'appel de programme à la fonction renverra désormais des valeurs.
Chaînage sur des méthodes avec des valeurs de retour facultatives
Le chaînage facultatif est également utilisé pour accéder aux méthodes définies par les sous-classes.
class rectangle {
var print: circle?
}
class circle {
var area = [radius]()
var cprint: Int {
return area.count
}
subscript(i: Int) -> radius {
get {
return area[i]
}
set {
area[i] = newValue
}
}
func circleprint() {
print("Area of Circle is: \(cprint)")
}
var rectarea: circumference?
}
class radius {
let radiusname: String
init(radiusname: String) { self.radiusname = radiusname }
}
class circumference {
var circumName: String?
var circumNumber: String?
var circumarea: String?
func buildingIdentifier() -> String? {
if circumName != nil {
return circumName
} else if circumNumber != nil {
return circumNumber
} else {
return nil
}
}
}
let circname = rectangle()
if circname.print?.circleprint() != nil {
print("Area of circle is specified)")
} else {
print("Area of circle is not specified")
}
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Area of circle is not specified
Pour valider le type d'une instance, 'Type Casting' entre en jeu en langage Swift 4. Il est utilisé pour vérifier si le type d'instance appartient à une super classe ou sous-classe particulière ou s'il est défini dans sa propre hiérarchie.
Le casting de type Swift 4 fournit deux opérateurs «est» pour vérifier le type d'une valeur et «as» et pour convertir la valeur de type en un type différent. La conversion de type vérifie également si le type d'instance suit une norme de conformité de protocole particulière.
Définition d'une hiérarchie de classes
La conversion de type est utilisée pour vérifier le type d'instances afin de savoir s'il appartient à un type de classe particulier. En outre, il vérifie la hiérarchie des classes et de ses sous-classes pour vérifier et transtyper ces instances pour en faire une même hiérarchie.
class Subjects {
var physics: String
init(physics: String) {
self.physics = physics
}
}
class Chemistry: Subjects {
var equations: String
init(physics: String, equations: String) {
self.equations = equations
super.init(physics: physics)
}
}
class Maths: Subjects {
var formulae: String
init(physics: String, formulae: String) {
self.formulae = formulae
super.init(physics: physics)
}
}
let sa = [ Chemistry(physics: "solid physics", equations: "Hertz"),
Maths(physics: "Fluid Dynamics", formulae: "Giga Hertz")]
let samplechem = Chemistry(physics: "solid physics", equations: "Hertz")
print("Instance physics is: \(samplechem.physics)")
print("Instance equation is: \(samplechem.equations)")
let samplemaths = Maths(physics: "Fluid Dynamics", formulae: "Giga Hertz")
print("Instance physics is: \(samplemaths.physics)")
print("Instance formulae is: \(samplemaths.formulae)")
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Instance physics is: solid physics
Instance equation is: Hertz
Instance physics is: Fluid Dynamics
Instance formulae is: Giga Hertz
Vérification de type
La vérification de type est effectuée avec l'opérateur «est». L'opérateur de vérification de type 'is' vérifie si l'instance appartient à un type de sous-classe particulier et renvoie 'true' si elle appartient à cette instance, sinon elle retournera 'false'.
class Subjects {
var physics: String
init(physics: String) {
self.physics = physics
}
}
class Chemistry: Subjects {
var equations: String
init(physics: String, equations: String) {
self.equations = equations
super.init(physics: physics)
}
}
class Maths: Subjects {
var formulae: String
init(physics: String, formulae: String) {
self.formulae = formulae
super.init(physics: physics)
}
}
let sa = [
Chemistry(physics: "solid physics", equations: "Hertz"),
Maths(physics: "Fluid Dynamics", formulae: "Giga Hertz"),
Chemistry(physics: "Thermo physics", equations: "Decibels"),
Maths(physics: "Astro Physics", formulae: "MegaHertz"),
Maths(physics: "Differential Equations", formulae: "Cosine Series")]
let samplechem = Chemistry(physics: "solid physics", equations: "Hertz")
print("Instance physics is: \(samplechem.physics)")
print("Instance equation is: \(samplechem.equations)")
let samplemaths = Maths(physics: "Fluid Dynamics", formulae: "Giga Hertz")
print("Instance physics is: \(samplemaths.physics)")
print("Instance formulae is: \(samplemaths.formulae)")
var chemCount = 0
var mathsCount = 0
for item in sa {
if item is Chemistry {
++chemCount
} else if item is Maths {
++mathsCount
}
}
print("Subjects in chemistry contains \(chemCount) topics and maths contains \(mathsCount) topics")
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Instance physics is: solid physics
Instance equation is: Hertz
Instance physics is: Fluid Dynamics
Instance formulae is: Giga Hertz
Subjects in chemistry contains 2 topics and maths contains 3 topics
Abattu
Le downcasting du type de sous-classe peut être effectué avec deux opérateurs (as? Et as!). 'As?' renvoie une valeur facultative lorsque la valeur renvoie nil. Il est utilisé pour vérifier la réussite du downcast.
'comme!' retourne forcer le déballage comme indiqué dans le chaînage facultatif lorsque le downcasting renvoie une valeur nulle. Il est utilisé pour déclencher une erreur d'exécution en cas d'échec du downcast
class Subjects {
var physics: String
init(physics: String) {
self.physics = physics
}
}
class Chemistry: Subjects {
var equations: String
init(physics: String, equations: String) {
self.equations = equations
super.init(physics: physics)
}
}
class Maths: Subjects {
var formulae: String
init(physics: String, formulae: String) {
self.formulae = formulae
super.init(physics: physics)
}
}
let sa = [
Chemistry(physics: "solid physics", equations: "Hertz"),
Maths(physics: "Fluid Dynamics", formulae: "Giga Hertz"),
Chemistry(physics: "Thermo physics", equations: "Decibels"),
Maths(physics: "Astro Physics", formulae: "MegaHertz"),
Maths(physics: "Differential Equations", formulae: "Cosine Series")]
let samplechem = Chemistry(physics: "solid physics", equations: "Hertz")
print("Instance physics is: \(samplechem.physics)")
print("Instance equation is: \(samplechem.equations)")
let samplemaths = Maths(physics: "Fluid Dynamics", formulae: "Giga Hertz")
print("Instance physics is: \(samplemaths.physics)")
print("Instance formulae is: \(samplemaths.formulae)")
var chemCount = 0
var mathsCount = 0
for item in sa {
if let print = item as? Chemistry {
print("Chemistry topics are: '\(print.physics)', \(print.equations)")
} else if let example = item as? Maths {
print("Maths topics are: '\(example.physics)', \(example.formulae)")
}
}
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Instance physics is: solid physics
Instance equation is: Hertz
Instance physics is: Fluid Dynamics
Instance formulae is: Giga Hertz
Chemistry topics are: 'solid physics', Hertz
Maths topics are: 'Fluid Dynamics', Giga Hertz
Chemistry topics are: 'Thermo physics', Decibels
Maths topics are: 'Astro Physics', MegaHertz
Maths topics are: 'Differential Equations', Cosine Series
Typecasting: n'importe quel objet
Le mot-clé 'Any' est utilisé pour représenter une instance qui appartient à n'importe quel type, y compris les types de fonction.
class Subjects {
var physics: String
init(physics: String) {
self.physics = physics
}
}
class Chemistry: Subjects {
var equations: String
init(physics: String, equations: String) {
self.equations = equations
super.init(physics: physics)
}
}
class Maths: Subjects {
var formulae: String
init(physics: String, formulae: String) {
self.formulae = formulae
super.init(physics: physics)
}
}
let sa = [
Chemistry(physics: "solid physics", equations: "Hertz"),
Maths(physics: "Fluid Dynamics", formulae: "Giga Hertz"),
Chemistry(physics: "Thermo physics", equations: "Decibels"),
Maths(physics: "Astro Physics", formulae: "MegaHertz"),
Maths(physics: "Differential Equations", formulae: "Cosine Series")]
let samplechem = Chemistry(physics: "solid physics", equations: "Hertz")
print("Instance physics is: \(samplechem.physics)")
print("Instance equation is: \(samplechem.equations)")
let samplemaths = Maths(physics: "Fluid Dynamics", formulae: "Giga Hertz")
print("Instance physics is: \(samplemaths.physics)")
print("Instance formulae is: \(samplemaths.formulae)")
var chemCount = 0
var mathsCount = 0
for item in sa {
if let print = item as? Chemistry {
print("Chemistry topics are: '\(print.physics)', \(print.equations)")
} else if let example = item as? Maths {
print("Maths topics are: '\(example.physics)', \(example.formulae)")
}
}
var exampleany = [Any]()
exampleany.append(12)
exampleany.append(3.14159)
exampleany.append("Example for Any")
exampleany.append(Chemistry(physics: "solid physics", equations: "Hertz"))
for print in exampleany {
switch print {
case let someInt as Int:
print("Integer value is \(someInt)")
case let someDouble as Double where someDouble > 0:
print("Pi value is \(someDouble)")
case let someString as String:
print("\(someString)")
case let phy as Chemistry:
print("Topics '\(phy.physics)', \(phy.equations)")
default:
print("None")
}
}
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Instance physics is: solid physics
Instance equation is: Hertz
Instance physics is: Fluid Dynamics
Instance formulae is: Giga Hertz
Chemistry topics are: 'solid physics', Hertz
Maths topics are: 'Fluid Dynamics', Giga Hertz
Chemistry topics are: 'Thermo physics', Decibels
Maths topics are: 'Astro Physics', MegaHertz
Maths topics are: 'Differential Equations', Cosine Series
Integer value is 12
Pi value is 3.14159
Example for Any
Topics 'solid physics', Hertz
AnyObject
Pour représenter l'instance de n'importe quel type de classe, le mot clé 'AnyObject' est utilisé.
class Subjects {
var physics: String
init(physics: String) {
self.physics = physics
}
}
class Chemistry: Subjects {
var equations: String
init(physics: String, equations: String) {
self.equations = equations
super.init(physics: physics)
}
}
class Maths: Subjects {
var formulae: String
init(physics: String, formulae: String) {
self.formulae = formulae
super.init(physics: physics)
}
}
let saprint: [AnyObject] = [Chemistry(physics: "solid physics", equations: "Hertz"),
Maths(physics: "Fluid Dynamics", formulae: "Giga Hertz"),
Chemistry(physics: "Thermo physics", equations: "Decibels"),
Maths(physics: "Astro Physics", formulae: "MegaHertz"),
Maths(physics: "Differential Equations", formulae: "Cosine Series")]
let samplechem = Chemistry(physics: "solid physics", equations: "Hertz")
print("Instance physics is: \(samplechem.physics)")
print("Instance equation is: \(samplechem.equations)")
let samplemaths = Maths(physics: "Fluid Dynamics", formulae: "Giga Hertz")
print("Instance physics is: \(samplemaths.physics)")
print("Instance formulae is: \(samplemaths.formulae)")
var chemCount = 0
var mathsCount = 0
for item in saprint {
if let print = item as? Chemistry {
print("Chemistry topics are: '\(print.physics)', \(print.equations)")
} else if let example = item as? Maths {
print("Maths topics are: '\(example.physics)', \(example.formulae)")
}
}
var exampleany = [Any]()
exampleany.append(12)
exampleany.append(3.14159)
exampleany.append("Example for Any")
exampleany.append(Chemistry(physics: "solid physics", equations: "Hertz"))
for print in exampleany {
switch print {
case let someInt as Int:
print("Integer value is \(someInt)")
case let someDouble as Double where someDouble > 0:
print("Pi value is \(someDouble)")
case let someString as String:
print("\(someString)")
case let phy as Chemistry:
print("Topics '\(phy.physics)', \(phy.equations)")
default:
print("None")
}
}
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Instance physics is: solid physics
Instance equation is: Hertz
Instance physics is: Fluid Dynamics
Instance formulae is: Giga Hertz
Chemistry topics are: 'solid physics', Hertz
Maths topics are: 'Fluid Dynamics', Giga Hertz
Chemistry topics are: 'Thermo physics', Decibels
Maths topics are: 'Astro Physics', MegaHertz
Maths topics are: 'Differential Equations', Cosine Series
Integer value is 12
Pi value is 3.14159
Example for Any
Topics 'solid physics', Hertz
La fonctionnalité d'une classe, d'une structure ou d'un type d'énumération existant peut être ajoutée à l'aide d'extensions. La fonctionnalité de type peut être ajoutée avec des extensions, mais la substitution de la fonctionnalité n'est pas possible avec les extensions.
Swift Extension Functionalities -
- Ajout de propriétés calculées et de propriétés de type calculées
- Définition des méthodes d'instance et de type.
- Fournir de nouveaux initialiseurs.
- Définition des indices
- Définition et utilisation de nouveaux types imbriqués
- Rendre un type existant conforme à un protocole
Les extensions sont déclarées avec le mot clé "extension"
Syntaxe
extension SomeType {
// new functionality can be added here
}
Le type existant peut également être ajouté avec des extensions pour en faire un protocole standard et sa syntaxe est similaire à celle des classes ou des structures.
extension SomeType: SomeProtocol, AnotherProtocol {
// protocol requirements is described here
}
Propriétés calculées
Les propriétés "instance" et "type" calculées peuvent également être étendues à l'aide d'extensions.
extension Int {
var add: Int {return self + 100 }
var sub: Int { return self - 10 }
var mul: Int { return self * 10 }
var div: Int { return self / 5 }
}
let addition = 3.add
print("Addition is \(addition)")
let subtraction = 120.sub
print("Subtraction is \(subtraction)")
let multiplication = 39.mul
print("Multiplication is \(multiplication)")
let division = 55.div
print("Division is \(division)")
let mix = 30.add + 34.sub
print("Mixed Type is \(mix)")
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Addition is 103
Subtraction is 110
Multiplication is 390
Division is 11
Mixed Type is 154
Initialiseurs
Swift 4 offre la flexibilité d'ajouter de nouveaux initialiseurs à un type existant par des extensions. L'utilisateur peut ajouter ses propres types personnalisés pour étendre les types déjà définis et des options d'initialisation supplémentaires sont également possibles. Les extensions ne prennent en charge que init (). deinit () n'est pas pris en charge par les extensions.
struct sum {
var num1 = 100, num2 = 200
}
struct diff {
var no1 = 200, no2 = 100
}
struct mult {
var a = sum()
var b = diff()
}
let calc = mult()
print ("Inside mult block \(calc.a.num1, calc.a.num2)")
print("Inside mult block \(calc.b.no1, calc.b.no2)")
let memcalc = mult(a: sum(num1: 300, num2: 500),b: diff(no1: 300, no2: 100))
print("Inside mult block \(memcalc.a.num1, memcalc.a.num2)")
print("Inside mult block \(memcalc.b.no1, memcalc.b.no2)")
extension mult {
init(x: sum, y: diff) {
let X = x.num1 + x.num2
let Y = y.no1 + y.no2
}
}
let a = sum(num1: 100, num2: 200)
print("Inside Sum Block:\( a.num1, a.num2)")
let b = diff(no1: 200, no2: 100)
print("Inside Diff Block: \(b.no1, b.no2)")
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Inside mult block (100, 200)
Inside mult block (200, 100)
Inside mult block (300, 500)
Inside mult block (300, 100)
Inside Sum Block:(100, 200)
Inside Diff Block: (200, 100)
Méthodes
De nouvelles méthodes d'instance et méthodes de type peuvent être ajoutées à la sous-classe à l'aide d'extensions.
extension Int {
func topics(summation: () -> ()) {
for _ in 0..<self {
summation()
}
}
}
4.topics(summation: {
print("Inside Extensions Block")
})
3.topics(summation: {
print("Inside Type Casting Block")
})
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Inside Extensions Block
Inside Extensions Block
Inside Extensions Block
Inside Extensions Block
Inside Type Casting Block
Inside Type Casting Block
Inside Type Casting Block
La fonction topics () prend un argument de type '(summation: () → ())' pour indiquer que la fonction ne prend aucun argument et qu'elle ne renvoie aucune valeur. Pour appeler cette fonction plusieurs fois, for block est initialisé et l'appel à la méthode avec topic () est initialisé.
Méthodes d'instance en mutation
Les méthodes d'instance peuvent également être mutées lorsqu'elles sont déclarées en tant qu'extensions.
Les méthodes de structure et d'énumération qui modifient self ou ses propriétés doivent marquer la méthode d'instance comme mutante, tout comme les méthodes mutantes d'une implémentation d'origine.
extension Double {
mutating func square() {
let pi = 3.1415
self = pi * self * self
}
}
var Trial1 = 3.3
Trial1.square()
print("Area of circle is: \(Trial1)")
var Trial2 = 5.8
Trial2.square()
print("Area of circle is: \(Trial2)")
var Trial3 = 120.3
Trial3.square()
print("Area of circle is: \(Trial3)")
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Area of circle is: 34.210935
Area of circle is: 105.68006
Area of circle is: 45464.070735
Les indices
L'ajout de nouveaux indices à des instances déjà déclarées peut également être possible avec des extensions.
extension Int {
subscript(var multtable: Int) -> Int {
var no1 = 1
while multtable > 0 {
no1 *= 10
--multtable
}
return (self / no1) % 10
}
}
print(12[0])
print(7869[1])
print(786543[2])
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
2
6
5
Types imbriqués
Les types imbriqués pour les instances de classe, de structure et d'énumération peuvent également être étendus à l'aide d'extensions.
extension Int {
enum calc {
case add
case sub
case mult
case div
case anything
}
var print: calc {
switch self {
case 0:
return .add
case 1:
return .sub
case 2:
return .mult
case 3:
return .div
default:
return .anything
}
}
}
func result(numb: [Int]) {
for i in numb {
switch i.print {
case .add:
print(" 10 ")
case .sub:
print(" 20 ")
case .mult:
print(" 30 ")
case .div:
print(" 40 ")
default:
print(" 50 ")
}
}
}
result(numb: [0, 1, 2, 3, 4, 7])
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
10
20
30
40
50
50
Les protocoles fournissent un modèle pour les méthodes, les propriétés et d'autres fonctionnalités d'exigences. Il est simplement décrit comme un squelette de méthodes ou de propriétés au lieu d'une implémentation. L'implémentation des méthodes et des propriétés peut en outre être effectuée en définissant des classes, des fonctions et des énumérations. La conformité d'un protocole est définie comme les méthodes ou propriétés satisfaisant aux exigences du protocole.
Syntaxe
Les protocoles suivent également la syntaxe similaire à celle des classes, des structures et des énumérations -
protocol SomeProtocol {
// protocol definition
}
Les protocoles sont déclarés après les noms de classe, de structure ou de type d'énumération. Des déclarations de protocole unique et multiple sont également possibles. Si plusieurs protocoles sont définis, ils doivent être séparés par des virgules.
struct SomeStructure: Protocol1, Protocol2 {
// structure definition
}
Lorsqu'un protocole doit être défini pour la super classe, le nom du protocole doit suivre le nom de la super classe avec une virgule.
class SomeClass: SomeSuperclass, Protocol1, Protocol2 {
// class definition
}
Exigences relatives aux propriétés et aux méthodes
Le protocole est utilisé pour spécifier une propriété de type de classe ou une propriété d'instance particulière. Il spécifie simplement le type ou la propriété d'instance seule plutôt que de spécifier s'il s'agit d'une propriété stockée ou calculée. En outre, il est utilisé pour spécifier si la propriété est «gettable» ou «configurable».
Les exigences de propriété sont déclarées par le mot clé «var» en tant que variables de propriété. {get set} est utilisé pour déclarer des propriétés gettable et définissable après leur déclaration de type. Gettable est mentionné par la propriété {get} après sa déclaration de type.
protocol classa {
var marks: Int { get set }
var result: Bool { get }
func attendance() -> String
func markssecured() -> String
}
protocol classb: classa {
var present: Bool { get set }
var subject: String { get set }
var stname: String { get set }
}
class classc: classb {
var marks = 96
let result = true
var present = false
var subject = "Swift 4 Protocols"
var stname = "Protocols"
func attendance() -> String {
return "The \(stname) has secured 99% attendance"
}
func markssecured() -> String {
return "\(stname) has scored \(marks)"
}
}
let studdet = classc()
studdet.stname = "Swift 4"
studdet.marks = 98
studdet.markssecured()
print(studdet.marks)
print(studdet.result)
print(studdet.present)
print(studdet.subject)
print(studdet.stname)
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
98
true
false
Swift 4 Protocols
Swift 4
Exigences de la méthode de mutation
protocol daysofaweek {
mutating func print()
}
enum days: daysofaweek {
case sun, mon, tue, wed, thurs, fri, sat
mutating func print() {
switch self {
case sun:
self = sun
print("Sunday")
case mon:
self = mon
print("Monday")
case tue:
self = tue
print("Tuesday")
case wed:
self = wed
print("Wednesday")
case mon:
self = thurs
print("Thursday")
case tue:
self = fri
print("Friday")
case sat:
self = sat
print("Saturday")
default:
print("NO Such Day")
}
}
}
var res = days.wed
res.print()
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Wednesday
Configuration requise pour l'initialiseur
Swing permet à l'utilisateur d'initialiser les protocoles pour suivre une conformité de type similaire à celle des initialiseurs normaux.
Syntaxe
protocol SomeProtocol {
init(someParameter: Int)
}
Par exemple
protocol tcpprotocol {
init(aprot: Int)
}
Implémentations de classe des exigences d'initialisation de protocole
Un initialiseur désigné ou pratique permet à l'utilisateur d'initialiser un protocole pour se conformer à sa norme par le mot-clé réservé «requis».
class SomeClass: SomeProtocol {
required init(someParameter: Int) {
// initializer implementation statements
}
}
protocol tcpprotocol {
init(aprot: Int)
}
class tcpClass: tcpprotocol {
required init(aprot: Int) {
}
}
La conformité du protocole est assurée sur toutes les sous-classes pour une implémentation explicite ou héritée par le modificateur «requis».
Lorsqu'une sous-classe remplace son exigence d'initialisation de super classe, elle est spécifiée par le mot-clé modificateur 'override'.
protocol tcpprotocol {
init(no1: Int)
}
class mainClass {
var no1: Int // local storage
init(no1: Int) {
self.no1 = no1 // initialization
}
}
class subClass: mainClass, tcpprotocol {
var no2: Int
init(no1: Int, no2 : Int) {
self.no2 = no2
super.init(no1:no1)
}
// Requires only one parameter for convenient method
required override convenience init(no1: Int) {
self.init(no1:no1, no2:0)
}
}
let res = mainClass(no1: 20)
let print = subClass(no1: 30, no2: 50)
print("res is: \(res.no1)")
print("res is: \(print.no1)")
print("res is: \(print.no2)")
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
res is: 20
res is: 30
res is: 50
Protocoles en tant que types
Au lieu d'implémenter des fonctionnalités dans un protocole, elles sont utilisées comme types de fonctions, de classes, de méthodes, etc.
Les protocoles sont accessibles sous forme de types dans -
Fonction, méthode ou initialiser comme paramètre ou type de retour
Constante, variable ou propriété
Tableaux, dictionnaires ou autres conteneurs en tant qu'éléments
protocol Generator {
typealias members
func next() -> members?
}
var items = [10,20,30].generate()
while let x = items.next() {
print(x)
}
for lists in map([1,2,3], {i in i*5}) {
print(lists)
}
print([100,200,300])
print(map([1,2,3], {i in i*10}))
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
10
20
30
5
10
15
[100, 200, 300]
[10, 20, 30]
Ajout de la conformité de protocole avec une extension
Le type existant peut être adopté et conforme à un nouveau protocole en utilisant des extensions. De nouvelles propriétés, méthodes et indices peuvent être ajoutés aux types existants à l'aide d'extensions.
protocol AgeClasificationProtocol {
var age: Int { get }
func agetype() -> String
}
class Person {
let firstname: String
let lastname: String
var age: Int
init(firstname: String, lastname: String) {
self.firstname = firstname
self.lastname = lastname
self.age = 10
}
}
extension Person : AgeClasificationProtocol {
func fullname() -> String {
var c: String
c = firstname + " " + lastname
return c
}
func agetype() -> String {
switch age {
case 0...2:
return "Baby"
case 2...12:
return "Child"
case 13...19:
return "Teenager"
case let x where x > 65:
return "Elderly"
default:
return "Normal"
}
}
}
Héritage de protocole
Swift 4 permet aux protocoles d'hériter des propriétés de ses propriétés définies. Il est similaire à celui de l'héritage de classe, mais avec le choix de lister plusieurs protocoles hérités séparés par des virgules.
protocol classa {
var no1: Int { get set }
func calc(sum: Int)
}
protocol result {
func print(target: classa)
}
class student2: result {
func print(target: classa) {
target.calc(sum: 1)
}
}
class classb: result {
func print(target: classa) {
target.calc(sum: 5)
}
}
class student: classa {
var no1: Int = 10
func calc(sum: Int) {
no1 -= sum
print("Student attempted \(sum) times to pass")
if no1 <= 0 {
print("Student is absent for exam")
}
}
}
class Player {
var stmark: result!
init(stmark: result) {
self.stmark = stmark
}
func print(target: classa) {
stmark.print(target: target)
}
}
var marks = Player(stmark: student2())
var marksec = student()
marks.print(target: marksec)
marks.print(target: marksec)
marks.print(target: marksec)
marks.stmark = classb()
marks.print(target: marksec)
marks.print(target: marksec)
marks.print(target: marksec)
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Student attempted 1 times to pass
Student attempted 1 times to pass
Student attempted 1 times to pass
Student attempted 5 times to pass
Student attempted 5 times to pass
Student is absent for exam
Student attempted 5 times to pass
Student is absent for exam
Protocoles de classe uniquement
Lorsque des protocoles sont définis et que l'utilisateur souhaite définir un protocole avec des classes, il doit être ajouté en définissant d'abord la classe suivie de la liste d'héritage du protocole.
protocol tcpprotocol {
init(no1: Int)
}
class mainClass {
var no1: Int // local storage
init(no1: Int) {
self.no1 = no1 // initialization
}
}
class subClass: mainClass, tcpprotocol {
var no2: Int
init(no1: Int, no2 : Int) {
self.no2 = no2
super.init(no1:no1)
}
// Requires only one parameter for convenient method
required override convenience init(no1: Int) {
self.init(no1:no1, no2:0)
}
}
let res = mainClass(no1: 20)
let print = subClass(no1: 30, no2: 50)
print("res is: \(res.no1)")
print("res is: \(print.no1)")
print("res is: \(print.no2)")
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
res is: 20
res is: 30
res is: 50
Composition du protocole
Swift 4 permet d'appeler plusieurs protocoles à la fois à l'aide de la composition du protocole.
Syntaxe
protocol<SomeProtocol, AnotherProtocol>
Exemple
protocol stname {
var name: String { get }
}
protocol stage {
var age: Int { get }
}
struct Person: stname, stage {
var name: String
var age: Int
}
func print(celebrator: stname & stage) {
print("\(celebrator.name) is \(celebrator.age) years old")
}
let studname = Person(name: "Priya", age: 21)
print(studname)
let stud = Person(name: "Rehan", age: 29)
print(stud)
let student = Person(name: "Roshan", age: 19)
print(student)
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Person(name: "Priya", age: 21)
Person(name: "Rehan", age: 29)
Person(name: "Roshan", age: 19)
Vérification de la conformité du protocole
La conformité du protocole est testée par des opérateurs «est» et «comme» similaires à ceux du type casting.
L'opérateur is renvoie true si une instance est conforme à la norme du protocole et renvoie false en cas d'échec.
le as? la version de l'opérateur downcast renvoie une valeur facultative du type de protocole, et cette valeur est nulle si l'instance n'est pas conforme à ce protocole.
La version as de l'opérateur downcast force le downcast au type de protocole et déclenche une erreur d'exécution si le downcast échoue.
import Foundation
@objc protocol rectangle {
var area: Double { get }
}
@objc class Circle: rectangle {
let pi = 3.1415927
var radius: Double
var area: Double { return pi * radius * radius }
init(radius: Double) { self.radius = radius }
}
@objc class result: rectangle {
var area: Double
init(area: Double) { self.area = area }
}
class sides {
var rectsides: Int
init(rectsides: Int) { self.rectsides = rectsides }
}
let objects: [AnyObject] = [Circle(radius: 2.0),result(area:198),sides(rectsides: 4)]
for object in objects {
if let objectWithArea = object as? rectangle {
print("Area is \(objectWithArea.area)")
} else {
print("Rectangle area is not defined")
}
}
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Area is 12.5663708
Area is 198.0
Rectangle area is not defined
Le langage Swift 4 fournit des fonctionnalités «génériques» pour écrire des fonctions et des types flexibles et réutilisables. Les génériques sont utilisés pour éviter la duplication et pour fournir une abstraction. Les bibliothèques standard Swift 4 sont construites avec du code générique. Les types 'Arrays' et 'Dictionary' de Swift 4s appartiennent à des collections génériques. À l'aide de tableaux et de dictionnaires, les tableaux sont définis pour contenir des valeurs «Int» et des valeurs «String» ou tout autre type.
func exchange(a: inout Int, b: inout Int) {
let temp = a
a = b
b = temp
}
var numb1 = 100
var numb2 = 200
print("Before Swapping values are: \(numb1) and \(numb2)")
exchange(a: &numb1, b: &numb2)
print("After Swapping values are: \(numb1) and \(numb2)")
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Before Swapping values are: 100 and 200
After Swapping values are: 200 and 100
Fonctions génériques: paramètres de type
Les fonctions génériques peuvent être utilisées pour accéder à n'importe quel type de données comme «Int» ou «String».
func exchange<T>(a: inout T, b: inout T) {
let temp = a
a = b
b = temp
}
var numb1 = 100
var numb2 = 200
print("Before Swapping Int values are: \(numb1) and \(numb2)")
exchange(a: &numb1, b: &numb2)
print("After Swapping Int values are: \(numb1) and \(numb2)")
var str1 = "Generics"
var str2 = "Functions"
print("Before Swapping String values are: \(str1) and \(str2)")
exchange(a: &str1, b: &str2)
print("After Swapping String values are: \(str1) and \(str2)")
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Before Swapping Int values are: 100 and 200
After Swapping Int values are: 200 and 100
Before Swapping String values are: Generics and Functions
After Swapping String values are: Functions and Generics
La fonction exchange () est utilisée pour permuter les valeurs qui sont décrites dans le programme ci-dessus et <T> est utilisé comme paramètre de type. Pour la première fois, la fonction exchange () est appelée pour renvoyer les valeurs 'Int' et le second appel à la fonction exchange () renverra les valeurs 'String'. Plusieurs types de paramètres peuvent être inclus dans les crochets angulaires séparés par des virgules.
Les paramètres de type sont nommés comme définis par l'utilisateur pour connaître le but du paramètre de type qu'il contient. Swift 4 fournit <T> comme nom de paramètre de type générique. Cependant, les paramètres de type tels que les tableaux et les dictionnaires peuvent également être nommés en tant que clé, valeur pour identifier qu'ils appartiennent au type 'Dictionary'.
struct TOS<T> {
var items = [T]()
mutating func push(item: T) {
items.append(item)
}
mutating func pop() -> T {
return items.removeLast()
}
}
var tos = TOS<String>()
tos.push(item: "Swift 4")
print(tos.items)
tos.push(item: "Generics")
print(tos.items)
tos.push(item: "Type Parameters")
print(tos.items)
tos.push(item: "Naming Type Parameters")
print(tos.items)
let deletetos = tos.pop()
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
[Swift 4]
[Swift 4, Generics]
[Swift 4, Generics, Type Parameters]
[Swift 4, Generics, Type Parameters, Naming Type Parameters]
Extension d'un type générique
L'extension de la propriété de pile pour connaître le haut de l'élément est incluse avec le mot-clé «extension».
struct TOS<T> {
var items = [T]()
mutating func push(item: T) {
items.append(item)
}
mutating func pop() -> T {
return items.removeLast()
}
}
var tos = TOS<String>()
tos.push(item: "Swift 4")
print(tos.items)
tos.push(item: "Generics")
print(tos.items)
tos.push(item: "Type Parameters")
print(tos.items)
tos.push(item: "Naming Type Parameters")
print(tos.items)
extension TOS {
var first: T? {
return items.isEmpty ? nil : items[items.count - 1]
}
}
if let first = tos.first {
print("The top item on the stack is \(first).")
}
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
["Swift 4"]
["Swift 4", "Generics"]
["Swift 4", "Generics", "Type Parameters"]
["Swift 4", "Generics", "Type Parameters", "Naming Type Parameters"]
The top item on the stack is Naming Type Parameters.
Contraintes de type
Le langage Swift 4 permet aux «contraintes de type» de spécifier si le paramètre de type hérite d'une classe spécifique ou de garantir la norme de conformité du protocole.
func exchange<T>(a: inout T, b: inout T) {
let temp = a
a = b
b = temp
}
var numb1 = 100
var numb2 = 200
print("Before Swapping Int values are: \(numb1) and \(numb2)")
exchange(a: &numb1, b: &numb2)
print("After Swapping Int values are: \(numb1) and \(numb2)")
var str1 = "Generics"
var str2 = "Functions"
print("Before Swapping String values are: \(str1) and \(str2)")
exchange(a: &str1, b: &str2)
print("After Swapping String values are: \(str1) and \(str2)")
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Before Swapping Int values are: 100 and 200
After Swapping Int values are: 200 and 100
Before Swapping String values are: Generics and Functions
After Swapping String values are: Functions and Generics
Types associés
Swift 4 permet aux types associés d'être déclarés dans la définition de protocole par le mot-clé 'associatedtype'.
protocol Container {
associatedtype ItemType
mutating func append(item: ItemType)
var count: Int { get }
subscript(i: Int) -> ItemType { get }
}
struct TOS<T>: Container {
// original Stack<T> implementation
var items = [T]()
mutating func push(item: T) {
items.append(item)
}
mutating func pop() -> T {
return items.removeLast()
}
// conformance to the Container protocol
mutating func append(item: T) {
self.push(item: item)
}
var count: Int {
return items.count
}
subscript(i: Int) -> T {
return items[i]
}
}
var tos = TOS<String>()
tos.push(item: "Swift 4")
print(tos.items)
tos.push(item: "Generics")
print(tos.items)
tos.push(item: "Type Parameters")
print(tos.items)
tos.push(item: "Naming Type Parameters")
print(tos.items)
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
[Swift 4]
[Swift 4, Generics]
[Swift 4, Generics, Type Parameters]
[Swift 4, Generics, Type Parameters, Naming Type Parameters]
Clauses Où
Les contraintes de type permettent à l'utilisateur de définir des exigences sur les paramètres de type associés à une fonction ou à un type générique. Pour définir les exigences des types associés, les clauses «where» sont déclarées comme faisant partie de la liste de paramètres de type. Le mot clé 'where' est placé immédiatement après la liste des paramètres de type suivis des contraintes des types associés, des relations d'égalité entre les types et des types associés.
protocol Container {
associatedtype ItemType
mutating func append(item: ItemType)
var count: Int { get }
subscript(i: Int) -> ItemType { get }
}
struct Stack<T>: Container {
// original Stack<T> implementation
var items = [T]()
mutating func push(item: T) {
items.append(item)
}
mutating func pop() -> T {
return items.removeLast()
}
// conformance to the Container protocol
mutating func append(item: T) {
self.push(item: item)
}
var count: Int {
return items.count
}
subscript(i: Int) -> T {
return items[i]
}
}
func allItemsMatch<
C1: Container, C2: Container
where C1.ItemType == C2.ItemType, C1.ItemType: Equatable>
(someContainer: C1, anotherContainer: C2) -> Bool {
// check that both containers contain the same number of items
if someContainer.count != anotherContainer.count {
return false
}
// check each pair of items to see if they are equivalent
for i in 0..<someContainer.count {
if someContainer[i] != anotherContainer[i] {
return false
}
}
// all items match, so return true
return true
}
var tos = Stack<String>()
tos.push(item: "Swift 4")
print(tos.items)
tos.push(item: "Generics")
print(tos.items)
tos.push(item: "Where Clause")
print(tos.items)
var eos = ["Swift 4", "Generics", "Where Clause"]
print(eos)
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
[Swift 4]
[Swift 4, Generics]
[Swift 4, Generics, Where Clause]
[Swift 4, Generics, Where Clause]
Pour restreindre l'accès aux blocs de code, aux modules et à l'abstraction se fait via le contrôle d'accès. Les classes, structures et énumérations sont accessibles en fonction de leurs propriétés, méthodes, initialiseurs et indices par des mécanismes de contrôle d'accès. L'accès aux constantes, variables et fonctions d'un protocole est restreint et autorisé comme global et local via le contrôle d'accès. Le contrôle d'accès appliqué aux propriétés, types et fonctions peut être appelé «entités».
Le modèle de contrôle d'accès est basé sur des modules et des fichiers source.
Le module est défini comme une seule unité de distribution de code et peut être importé à l'aide du mot-clé «import». Un fichier source est défini comme un fichier de code source unique avec dans un module pour accéder à plusieurs types et fonctions.
Trois niveaux d'accès différents sont fournis par Swift 4 language. Il s'agit d'un accès public, interne et privé.
S. Non | Niveaux d'accès et définition |
---|---|
1 | Public Permet aux entités d'être traitées dans n'importe quel fichier source de leur module de définition, un fichier source d'un autre module qui importe le module de définition. |
2 | Internal Permet aux entités d'être utilisées dans n'importe quel fichier source à partir de leur module de définition, mais pas dans un fichier source en dehors de ce module. |
3 | Private Limite l'utilisation d'une entité à son propre fichier source de définition. L'accès privé joue le rôle de masquer les détails d'implémentation d'une fonctionnalité de code spécifique. |
Syntaxe
public class SomePublicClass {}
internal class SomeInternalClass {}
private class SomePrivateClass {}
public var somePublicVariable = 0
internal let someInternalConstant = 0
private func somePrivateFunction() {}
Contrôle d'accès pour les types de fonction
Certaines fonctions peuvent avoir des arguments déclarés à l'intérieur de la fonction sans aucune valeur de retour. Le programme suivant déclare a et b comme arguments de la fonction sum (). À l'intérieur de la fonction elle-même, les valeurs des arguments a et b sont passées en invoquant l'appel de fonction sum () et ses valeurs sont affichées, éliminant ainsi les valeurs de retour. Pour rendre le type de retour de la fonction privé, déclarez le niveau d'accès global de la fonction avec le modificateur private.
private func sum(a: Int, b: Int) {
let a = a + b
let b = a - b
print(a, b)
}
sum(a: 20, b: 10)
sum(a: 40, b: 10)
sum(a: 24, b: 6)
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
30 20
50 40
30 24
Contrôle d'accès pour les types d'énumération
public enum Student {
case Name(String)
case Mark(Int,Int,Int)
}
var studDetails = Student.Name("Swift 4")
var studMarks = Student.Mark(98,97,95)
switch studMarks {
case .Name(let studName):
print("Student name is: \(studName).")
case .Mark(let Mark1, let Mark2, let Mark3):
print("Student Marks are: \(Mark1),\(Mark2),\(Mark3).")
}
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Student Marks are: 98,97,95
L'énumération en langage Swift 4 reçoit automatiquement le même niveau d'accès pour les cas individuels d'une énumération. Pensez par exemple à accéder au nom des étudiants et aux marques sécurisées dans trois matières: le nom de l'énumération est déclaré comme étudiant et les membres présents dans la classe enum sont nom qui appartient à la chaîne de type de données, les marques sont représentées comme mark1, mark2 et mark3 de type de données Integer. Pour accéder au nom de l'élève ou aux notes qu'il a notées. Maintenant, le boîtier de commutation imprimera le nom de l'étudiant si ce bloc de cas est exécuté, sinon il imprimera les marques sécurisées par l'étudiant. Si les deux conditions échouent, le bloc par défaut sera exécuté.
Contrôle d'accès pour les sous-classes
Swift 4 permet à l'utilisateur de sous-classer n'importe quelle classe accessible dans le contexte d'accès actuel. Une sous-classe ne peut pas avoir un niveau d'accès plus élevé que sa superclasse. L'utilisateur n'a pas le droit d'écrire une sous-classe publique d'une superclasse interne.
public class cricket {
internal func printIt() {
print("Welcome to Swift 4 Super Class")
}
}
internal class tennis: cricket {
override internal func printIt() {
print("Welcome to Swift 4 Sub Class")
}
}
let cricinstance = cricket()
cricinstance.printIt()
let tennisinstance = tennis()
tennisinstance.printIt()
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Welcome to Swift Super Class
Welcome to Swift Sub Class
Contrôle d'accès pour les constantes, les variables, les propriétés et les indices
La constante, la variable ou la propriété Swift 4 ne peut être définie comme publique que son type. Il n'est pas valide d'écrire une propriété publique avec un type privé. De même, un indice ne peut pas être plus public que son index ou son type de retour.
Lorsqu'une constante, une variable, une propriété ou un indice utilise un type privé, la constante, la variable, la propriété ou l'indice doit également être marqué comme privé -
private var privateInstance = SomePrivateClass()
Getters et Setters
Les récupérateurs et les setters pour les constantes, les variables, les propriétés et les indices reçoivent automatiquement le même niveau d'accès que la constante, la variable, la propriété ou l'indice auquel ils appartiennent.
class Samplepgm {
var counter: Int = 0{
willSet(newTotal) {
print("Total Counter is: \(newTotal)")
}
didSet {
if counter > oldValue {
print("Newly Added Counter \(counter - oldValue)")
}
}
}
}
let NewCounter = Samplepgm()
NewCounter.counter = 100
NewCounter.counter = 800
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
Total Counter is: 100
Newly Added Counter 100
Total Counter is: 800
Newly Added Counter 700
Contrôle d'accès pour les initialiseurs et les initialiseurs par défaut
Les initialiseurs personnalisés peuvent se voir attribuer un niveau d'accès inférieur ou égal au type qu'ils initialisent. Un initialiseur requis doit avoir le même niveau d'accès que la classe à laquelle il appartient. Les types de paramètres d'un initialiseur ne peuvent pas être plus privés que son propre niveau d'accès.
Pour déclarer chaque sous-classe du mot clé initialize 'required' doit être défini avant la fonction init ().
class classA {
required init() {
let a = 10
print(a)
}
}
class classB: classA {
required init() {
let b = 30
print(b)
}
}
let res = classA()
let print = classB()
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
10
30
10
Un initialiseur par défaut a le même niveau d'accès que le type qu'il initialise, sauf si ce type est défini comme public. Lorsque l'initialisation par défaut est définie comme publique, elle est considérée comme interne. Lorsque l'utilisateur a besoin d'un type public pour être initialisable avec un initialiseur sans argument dans un autre module, fournissez explicitement un initialiseur public sans argument dans le cadre de la définition du type.
Contrôle d'accès pour les protocoles
Lorsque nous définissons un nouveau protocole pour hériter des fonctionnalités d'un protocole existant, les deux doivent être déclarés avec les mêmes niveaux d'accès pour hériter les propriétés de l'autre. Le contrôle d'accès Swift 4 ne permettra pas aux utilisateurs de définir un protocole «public» qui hérite d'un protocole «interne».
public protocol tcpprotocol {
init(no1: Int)
}
public class mainClass {
var no1: Int // local storage
init(no1: Int) {
self.no1 = no1 // initialization
}
}
class subClass: mainClass, tcpprotocol {
var no2: Int
init(no1: Int, no2 : Int) {
self.no2 = no2
super.init(no1:no1)
}
// Requires only one parameter for convenient method
required override convenience init(no1: Int) {
self.init(no1:no1, no2:0)
}
}
let res = mainClass(no1: 20)
let print = subClass(no1: 30, no2: 50)
print("res is: \(res.no1)")
print("res is: \(print.no1)")
print("res is: \(print.no2)")
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
res is: 20
res is: 30
res is: 50
Contrôle d'accès pour les extensions
Swift 4 ne permet pas aux utilisateurs de fournir un modificateur de niveau d'accès explicite pour une extension lorsque l'utilisateur utilise cette extension pour ajouter la conformité de protocole. Le niveau d'accès par défaut pour chaque implémentation d'exigence de protocole dans l'extension est fourni avec son propre niveau d'accès de protocole.
Contrôle d'accès pour les génériques
Les génériques permettent à l'utilisateur de spécifier des niveaux d'accès minimum pour accéder aux contraintes de type sur ses paramètres de type.
public struct TOS<T> {
var items = [T]()
mutating func push(item: T) {
items.append(item)
}
mutating func pop() -> T {
return items.removeLast()
}
}
var tos = TOS<String>()
tos.push(item: "Swift 4")
print(tos.items)
tos.push(item: "Generics")
print(tos.items)
tos.push(item: "Type Parameters")
print(tos.items)
tos.push(item: "Naming Type Parameters")
print(tos.items)
let deletetos = tos.pop()
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
[Swift 4]
[Swift 4, Generics]
[Swift 4, Generics, Type Parameters]
[Swift 4, Generics, Type Parameters, Naming Type Parameters]
Contrôle d'accès pour les alias de type
L'utilisateur peut définir des alias de type pour traiter des types de contrôle d'accès distincts. Le même niveau d'accès ou différents niveaux d'accès peuvent être définis par l'utilisateur. Lorsque l'alias de type est «privé», ses membres associés peuvent être déclarés comme «privé, interne de type public». Lorsque l'alias de type est public, les membres ne peuvent pas être alias en tant que nom «interne» ou «privé»
Tous les alias de type que vous définissez sont traités comme des types distincts aux fins du contrôle d'accès. Un alias de type peut avoir un niveau d'accès inférieur ou égal au niveau d'accès du type qu'il alias. Par exemple, un alias de type privé peut alias un type privé, interne ou public, mais un alias de type public ne peut pas aliaser un type interne ou privé.
public protocol Container {
associatedtype ItemType
mutating func append(item: ItemType)
var count: Int { get }
subscript(i: Int) -> ItemType { get }
}
struct Stack<T>: Container {
// original Stack<T> implementation
var items = [T]()
mutating func push(item: T) {
items.append(item)
}
mutating func pop() -> T {
return items.removeLast()
}
// conformance to the Container protocol
mutating func append(item: T) {
self.push(item: item)
}
var count: Int {
return items.count
}
subscript(i: Int) -> T {
return items[i]
}
}
func allItemsMatch<
C1: Container, C2: Container
where C1.ItemType == C2.ItemType, C1.ItemType: Equatable>
(someContainer: C1, anotherContainer: C2) -> Bool {
// check that both containers contain the same number of items
if someContainer.count != anotherContainer.count {
return false
}
// check each pair of items to see if they are equivalent
for i in 0..<someContainer.count {
if someContainer[i] != anotherContainer[i] {
return false
}
}
// all items match, so return true
return true
}
var tos = Stack<String>()
tos.push(item: "Swift 4")
print(tos.items)
tos.push(item: "Generics")
print(tos.items)
tos.push(item: "Where Clause")
print(tos.items)
var eos = ["Swift 4", "Generics", "Where Clause"]
print(eos)
Lorsque nous exécutons le programme ci-dessus en utilisant aire de jeux, nous obtenons le résultat suivant -
[Swift 4]
[Swift 4, Generics]
[Swift 4, Generics, Where Clause]
[Swift 4, Generics, Where Clause]
Encodage et décodage rapides
Swift 4 présente un nouveau Codable Protocole, qui vous permet de sérialiser et de désérialiser des types de données personnalisés sans écrire de code spécial - et sans avoir à vous soucier de perdre vos types de valeur.
struct Language: Codable {
var name: String
var version: Int
}
let swift = Language(name: "Swift", version: 4)
let java = Language(name: "java", version: 8)
let R = Language(name: "R", version: 3
Notez que Langauage est conforme au protocole codable. Nous allons maintenant le convertir en une représentation de données Json en utilisant une simple ligne.
let encoder = JSONEncoder()
if let encoded = try? encoder.encode(java) {
//Perform some operations on this value.
}
Swift encodera automatiquement toutes les valeurs de votre type de données.
Vous pouvez décoder les données en utilisant la fonction Decoder comme
let decoder = JSONDecoder()
if let decoded = try? decoder.decode(Language.self, from: encoded) {
//Perform some operations on this value.
}
JSONEncoder et son équivalent de liste de propriétés PropertyListEncoder ont de nombreuses options pour personnaliser leur fonctionnement.