Swift est désormais open source ! "Google considérerait Swift comme un langage « de première classe » pour Android" pouvait-on lire en avril sur le réseau. Et enfin un portage Android du langage a été "merge" dans la base de code officielle de Swift.
Bon tout ceci est un bon prétexte pour apprendre ce nouveau langage et les possibilités qu'il peut nous apporter en terme de développement. Une comparaison avec Java sera notamment proposée afin de montrer les similitudes et differences entre ces deux langages .
3. Développement lancé en 2010 par Chris Lattner
HISTORIQUE DE SWIFT
v1.0: Dévoilé durant la WWDC en 2014
v2.0: Ouverture du compilateur en 2015
v3.0: Publication en septembre 2016
7. MÉTAMORPHOSE D'UNE CLASSE JAVA
public class Personne {
private final String nom;
private int age;
public Personne(String nom, int age) {
this.nom = nom;
this.age = age;
}
public void anniversaire() {
this.age += 1;
}
}
8. SÉPARATEURS
public class Personne {
private final String nom
private int age
public Personne(String nom, int age) {
this.nom = nom
this.age = age
}
public void anniversaire() {
this.age += 1
}
}
9. ATTRIBUTS
public class Personne {
private let nom:String // Constant
private var age:Int // Variable
public Personne(String nom, int age) {
this.nom = nom
this.age = age
}
public void anniversaire() {
this.age += 1
}
}
10. PARAMÈTRES
public class Personne {
private let nom:String
private var age:Int
public Personne(nom:String, age:Int) {
this.nom = nom
this.age = age
}
public void anniversaire() {
this.age += 1
}
}
11. INITIALISATION
public class Personne {
private let nom:String
private var age:Int
public init(nom:String, age:Int) {
this.nom = nom
this.age = age
}
public void anniversaire() {
this.age += 1
}
}
12. FONCTION
public class Personne {
private let nom:String
private var age:Int
public init(nom:String, age:Int) {
this.nom = nom
this.age = age
}
public func anniversaire() -> Void {
this.age += 1
}
}
13. FONCTION OU PROCÉDURE
public class Personne {
private let nom:String
private var age:Int
public init(nom:String, age:Int) {
this.nom = nom
this.age = age
}
public func anniversaire() {
this.age += 1
}
}
14. UNE CLASSE SWIFT
public class Personne {
private let nom:String
private var age:Int
public init(nom:String, age:Int) {
self.nom = nom
self.age = age
}
public func anniversaire() {
self.age += 1
}
}
19. DONNÉE OPTIONNELLE
JAVA SWIFT
Optional<String> n =
Optional.of("A");
Optional<Integer> t =
n.map(v -> v.length());
if (t.isPresent()) {
// t.get();
}
let n:String? = "A" // ou nil
let t:Int? =
n?.characters.count
if let taille = t {
// taille utilisable
}
Fonctions disponibles map, atMap, lter etc.
Donnée optionnelle "portée" par le typage uniquement. Non structurel !
21. STRUCTURES DE CONTRÔLE
Sélection conditionnelle
Garde pour les optionnels
Répétition
if expression {
// bloc en cas de succés
} else {
// bloc optionnel en cas d'échec
}
guard let valeur = expression else {
// valeur n'est pas définie
}
// valeur est définie
let segment = 0..<100
for index in segment {
// bloc répété
}
25. FONCTION :: PARAMÈTRES
func multiplier(a:Int, b:Int) -> Int { return a * b }
En interne les noms des paramètres capturent les valeurs lors de l'appel
multiplier(a:2, b:3)
En externe les noms des paramètres servent de "marques" pour les arguments
Permutation des arguments interdite
34. FONCTION :: GÉNÉRICITÉ
Paramétrisation à la C++, Java, C#
func appliquer<A,B>(_ f:(A) -> B, _ a:A) -> B { return f(a) }
Possibilité de spéci er des contraintes
func estEgal<A:Equatable>(_ a:A, _ b:A) -> Bool { return a == b }
41. PROTOCOLE :: MISE EN OEUVRE
extension Monde {
func recherche(nom:String) -> Personne? {
return vivants().filter{ p in p.nom == nom }.first
}
}
Assimilable au "default" des interfaces dans Java 8
Idem pour les classes, structures et enumérations
45. CLASSE :: INITIALISATION & OPTIONNEL
Initialisation pouvant retourner nil
public class Personne {
private let nom:String
private var age:Int
public init?(nom:String, age:Int) {
guard age > -1 else { return nil } // if age < 0 { return nil }
self.nom = nom
self.age = age
}
}
let personne:Personne? = Personne(nom:"John Doe", age:-1)
47. CLASSE :: REFERENCE TYPE
public class Personne {
private let nom:String
private var age:Int
⊞ public init(nom:String, age:Int) { ... }
}
let personne1 = Personne(nom:"John Doe", age:42)
let personne2 = personne1
personne1 et personne2 référencent la même donnée en mémoire
50. STRUCTURE :: REFERENCE VALUE
var personne1 = Personne(nom:"John Doe", age:42)
let personne2 = personne1
personne1.age += 1
// personne1.age == 43
// personne2.age == 42
personne1 et personne2 ne référencent pas la même donnée en mémoire
52. ENUMÉRATION :: SPÉCIFICATION DE FORMES
public enum StadePersonne {
case Enfant, Adolescent, Adulte
}
let s : StadePersonne = ...
switch s {
case StadePersonne.Enfant: // ...
case StadePersonne.Adolescent: // ...
case StadePersonne.Adulte: // ...
}
Le switch/case doit être exhaustif / Véri é à la compilation
53. ENUMÉRATION :: SWITCH AVANCÉ
public enum PeutEtre<T> {
case QuelqueChose(value:T), Rien
public func get(_ valeurParDefaut:T) -> T {
switch self {
case .QuelqueChose(let v): return v
case _: return valeurParDefaut
}
}
}
Pattern Matching
55. self : Self
public class Personne {
private let nom:String
private var age:Int
⊞ public init(nom:String) { ... }
public func anniversaire() -> Self {
self.age += 1
return self
}
}
Le type Self dénote le type de l'objet courant à savoir ... self
57. SELF :: COPIABLE
class Personne : Copiable {
private let nom:String
private var age:Int
func copie() -> Self {
return type(of:self).init(nom:self.nom, age:self.age)
}
required init(nom:String, age:Int) {
self.nom = nom
self.age = 0
}
}
required force la dé nition dans les sous-classes
58. SELF :: INITIALISATION
class Personne {
private let nom:String
private var age:Int
required init(nom:String, age:Int) {
self.nom = nom
self.age = 0
}
class func new(nom:String) -> Self {
return self.init(nom:nom, age:0) // self ≡ Personne
}
}
Cela me rappelle furieusement le new de Perl !