web-dev-qa-db-fra.com

Variables de fonction statiques dans Swift

J'essaie de comprendre comment déclarer une variable statique étendue uniquement localement à une fonction dans Swift.

En C, cela pourrait ressembler à ceci:

int foo() {
    static int timesCalled = 0;
    ++timesCalled;
    return timesCalled;
}

En Objective-C, c'est fondamentalement la même chose:

- (NSInteger)foo {
    static NSInteger timesCalled = 0;
    ++timesCalled;
    return timesCalled;
}

Mais je n'arrive pas à faire quoi que ce soit de ce genre à Swift. J'ai essayé de déclarer la variable des manières suivantes:

static var timesCalledA = 0
var static timesCalledB = 0
var timesCalledC: static Int = 0
var timesCalledD: Int static = 0

Mais tout cela entraîne des erreurs.

  • La première se plaint "Les propriétés statiques ne peuvent être déclarées que sur un type".
  • La seconde se plaint "Déclaration attendue" (où static est) et "Modèle attendu" (où timesCalledB est)
  • Le troisième se plaint "Les instructions consécutives sur une ligne doivent être séparées par un ';'" (dans l'espace entre le signe deux-points et static) et un "type attendu" (où static est)
  • La quatrième se plaint "Les déclarations consécutives sur une ligne doivent être séparées par ';'" (dans l'espace entre Int et static) et "Déclaration attendue" (sous le signe d'égalité)
86
nhgrif

Je ne pense pas que Swift supporte les variables statiques sans les avoir attachées à une classe/structure. Essayez de déclarer une structure privée avec une variable statique.

func foo() -> Int {
    struct Holder {
        static var timesCalled = 0
    }
    Holder.timesCalled += 1
    return Holder.timesCalled
}

  7> foo()
$R0: Int = 1
  8> foo()
$R1: Int = 2
  9> foo()
$R2: Int = 3
138
Bryan Chen

Une autre solution

func makeIncrementerClosure() -> () -> Int {
    var timesCalled = 0
    func incrementer() -> Int {
        timesCalled += 1
        return timesCalled
    }
    return incrementer
}

let foo = makeIncrementerClosure()
foo()  // returns 1
foo()  // returns 2
22
monadis

Swift 1.2 avec Xcode 6.3 supporte maintenant statique comme prévu. Dans les notes de publication de la version bêta de Xcode 6.3:

Les méthodes et propriétés "statiques" sont désormais autorisées dans les classes (en tant qu'alias pour "classe final"). Vous êtes maintenant autorisé à déclarer des propriétés stockées statiques dans des classes disposant d'un stockage global et initialisées paresseusement lors du premier accès (comme des variables globales). Les protocoles déclarent maintenant les exigences de type en tant qu'exigences "statiques" au lieu de les déclarer en tant qu'exigences de "classe". (17198298)

Il semble que les fonctions ne peuvent pas contenir de déclarations statiques (comme demandé en question). Au lieu de cela, la déclaration doit être faite au niveau de la classe.

Exemple simple montrant une propriété statique incrémentée dans une fonction de classe (ou statique), bien qu'une fonction de classe ne soit pas requise:

class StaticThing
{
    static var timesCalled = 0

    class func doSomething()
    {
        timesCalled++

        println(timesCalled)
    }
}

StaticThing.doSomething()
StaticThing.doSomething()
StaticThing.doSomething()

Sortie:

1
2
3
18
Daniel

Une autre solution

class Myclass {
    static var timesCalled = 0
    func foo() -> Int {
        Myclass.timesCalled += 1
        return Myclass.timesCalled
    }
}
0
J.q