Quelle est la différence entre func statique et func de classe dans Swift?

Je peux voir ces définitions dans la bibliothèque Swift:

extension Bool : BooleanLiteralConvertible { static func convertFromBooleanLiteral(value: Bool) -> Bool } protocol BooleanLiteralConvertible { typealias BooleanLiteralType class func convertFromBooleanLiteral(value: BooleanLiteralType) -> Self } 

Quelle est la différence entre une fonction membre définie en tant que static func et une autre définie en tant que class func ? Est-ce simplement que la static est pour les fonctions statiques des structures et des énumérations, et la class pour les classes et les protocoles? Y a-t-il d’autres différences à connaître? Quelle est la raison d’être de cette distinction dans la syntaxe elle-même?

Est-ce simplement que la statique est pour les fonctions statiques des structures et des énumérations, et la classe pour les classes et les protocoles?

C’est la principale différence. Parmi les autres différences, les fonctions de classe sont dissortingbuées dynamicment et peuvent être remplacées par des sous-classes.

Les protocoles utilisent le mot-clé class, mais n’excluent pas les structures d’implémentation du protocole, elles utilisent simplement le statique. La classe a été choisie pour les protocoles, il n’y aurait donc pas de troisième mot-clé pour représenter le statique ou la classe.

De Chris Lattner à ce sujet:

Nous avons envisagé unifier la syntaxe (par exemple, en utilisant “type” comme mot-clé), mais cela ne signifie pas simplement des choses. Les mots-clés “class” et “static” sont bons pour la familiarité et sont assez descriptifs (une fois que vous avez compris comment + les méthodes fonctionnent), et ouvrent la porte à l’ajout potentiel de méthodes vraiment statiques aux classes. La principale bizarrerie de ce modèle est que les protocoles doivent choisir un mot-clé (et nous avons choisi “class”), mais tout compte fait, c’est le bon compromis.

Et voici un extrait qui montre une partie du comportement de substitution des fonctions de classe:

 class MyClass { class func myFunc() { println("myClass") } } class MyOtherClass: MyClass { override class func myFunc() { println("myOtherClass") } } var x: MyClass = MyOtherClass() x.dynamicType.myFunc() //myOtherClass x = MyClass() x.dynamicType.myFunc() //myClass 

Pour être plus clair, je fais un exemple ici,

 class ClassA { class func func1() -> Ssortingng { return "func1" } static func func2() -> Ssortingng { return "func2" } /* same as above final class func func2() -> Ssortingng { return "func2" } */ } 

static func est la même que final class func

Parce que c’est final , nous ne pouvons pas le remplacer dans la sous-classe comme ci-dessous:

 class ClassB : ClassA { override class func func1() -> Ssortingng { return "func1 in ClassB" } // ERROR: Class method overrides a 'final` class method override static func func2() -> Ssortingng { return "func2 in ClassB" } } 

J’ai fait des expériences dans la cour de récréation et j’ai tiré des conclusions.

TL; DR entrer la description de l'image ici

Comme vous pouvez le voir, dans le cas de la class , l’utilisation de class func ou static func n’est qu’une question d’habitude.

Exemple de terrain de jeu avec explication:

 class Dog { final func identity() -> Ssortingng { return "Once a woofer, forever a woofer!" } class func talk() -> Ssortingng { return "Woof woof!" } static func eat() -> Ssortingng { return "Miam miam" } func sleep() -> Ssortingng { return "Zzz" } } class Bulldog: Dog { // Can not override a final function // override final func identity() -> Ssortingng { // return "I'm once a dog but now I'm a cat" // } // Can not override a "class func", but redeclare is ok func talk() -> Ssortingng { return "I'm a bulldog, and I don't woof." } // Same as "class func" func eat() -> Ssortingng { return "I'm a bulldog, and I don't eat." } // Normal function can be overridden override func sleep() -> Ssortingng { return "I'm a bulldog, and I don't sleep." } } let dog = Dog() let bullDog = Bulldog() // FINAL FUNC //print(Dog.identity()) // comstack error print(dog.identity()) // print "Once a woofer, forever a woofer!" //print(Bulldog.identity()) // comstack error print(bullDog.identity()) // print "Once a woofer, forever a woofer!" // => "final func" is just a "normal" one but prevented to be overridden nor redeclared by subclasses. // CLASS FUNC print(Dog.talk()) // print "Woof woof!", called directly from class //print(dog.talk()) // comstack error cause "class func" is meant to be called directly from class, not an instance. print(Bulldog.talk()) // print "Woof woof!" cause it's called from Bulldog class, not bullDog instance. print(bullDog.talk()) // print "I'm a bulldog, and I don't woof." cause talk() is redeclared and it's called from bullDig instance // => "class func" is like a "static" one, must be called directly from class or subclassed, can be redeclared but NOT meant to be overridden. // STATIC FUNC print(Dog.eat()) // print "Miam miam" //print(dog.eat()) // comstack error cause "static func" is type method print(Bulldog.eat()) // print "Miam miam" print(bullDog.eat()) // print "I'm a bulldog, and I don't eat." // NORMAL FUNC //print(Dog.sleep()) // comstack error print(dog.sleep()) // print "Zzz" //print(Bulldog.sleep()) // comstack error print(bullDog.sleep()) // print "I'm a bulldog, and I don't sleep." 

Pour déclarer une propriété de variable de type, marquez la déclaration avec le modificateur de déclaration static . Les classes peuvent marquer les propriétés calculées avec le modificateur de déclaration de class au lieu d’autoriser les sous-classes à remplacer l’implémentation de la super-classe. Les propriétés de type sont décrites dans Propriétés du type.

REMARQUE
Dans une déclaration de classe, le mot-clé static a le même effet que le marquage de la déclaration avec les modificateurs de déclaration de class et de déclaration final .

Source: Le langage de programmation Swift – Propriétés des variables de type

Selon le Swift 2.2 Book publié par apple:

«Vous indiquez des méthodes de type en écrivant le mot-clé static avant le mot-clé func de la méthode. Les classes peuvent également utiliser le mot class clé class pour autoriser les sous-classes à remplacer l’implémentation de cette méthode par la super-classe .

À partir de Swift2.0, Apple dit:

“Lorsque vous les définissez dans un protocole, préfixez toujours les exigences de type type avec le mot-clé static. Cette règle s’applique même si les exigences de propriété de type peuvent être précédées du mot-clé class ou static lorsqu’elles sont implémentées par une classe:”

La principale différence est que les structs sont des types de valeur et que les classes sont des types de référence.

Lorsque vous faites une copie d’un type de valeur, il copie toutes les données de la chose que vous copiez dans la nouvelle variable. Ils sont 2 choses séparées et changer l’un n’affecte pas l’autre

Lorsque vous effectuez une copie d’un type de référence, la nouvelle variable fait référence au même emplacement de mémoire que celui que vous copiez. Cela signifie que changer l’un changera l’autre car ils se réfèrent tous deux au même emplacement mémoire