I can see these definitions in the Swift library:
extension Bool : BooleanLiteralConvertible { static func convertFromBooleanLiteral(value: Bool) -> Bool } protocol BooleanLiteralConvertible { typealias BooleanLiteralType class func convertFromBooleanLiteral(value: BooleanLiteralType) -> Self }
What's the difference between a member function defined as static func
and another one defined as class func
? Is it simply that static
is for static functions of structs and enums, and class
for classes and protocols? Are there any other differences that one should know about? What is the rationale for having this distinction in the syntax itself?
But what's the difference? The main difference is static is for static functions of structs and enums, and class for classes and protocols. From the Chris Lattner the father of Swift. We considered unifying the syntax (e.g. using "type" as the keyword), but that doesn't actually simply things.
There is no difference really. They couldn't use class func in a struct I guess, hence static func. struct func would have been a good candidate. This is a bit edgy if you ask me but well, those are the words.
Swift allows us to use a static prefix on methods and properties to associate them with the type that they're declared on rather than the instance. We can also use static properties to create singletons of our objects which, as you have probably heard before is a huge anti-pattern.
static: used for properties or functions of class or struct and can be accessed by class/struct level. With static keyword, we cannot override. final: used for class and class members (properties or functions). With final keyword, we cannot override.
To be clearer, I make an example here,
class ClassA { class func func1() -> String { return "func1" } static func func2() -> String { return "func2" } /* same as above final class func func2() -> String { return "func2" } */ }
static func
is same as final class func
Because it is final
, we can not override it in subclass as below:
class ClassB : ClassA { override class func func1() -> String { return "func1 in ClassB" } // ERROR: Class method overrides a 'final` class method override static func func2() -> String { return "func2 in ClassB" } }
Is it simply that static is for static functions of structs and enums, and class for classes and protocols?
That's the main difference. Some other differences are that class functions are dynamically dispatched and can be overridden by subclasses.
Protocols use the class keyword, but it doesn't exclude structs from implementing the protocol, they just use static instead. Class was chosen for protocols so there wouldn't have to be a third keyword to represent static or class.
From Chris Lattner on this topic:
We considered unifying the syntax (e.g. using "type" as the keyword), but that doesn't actually simply things. The keywords "class" and "static" are good for familiarity and are quite descriptive (once you understand how + methods work), and open the door for potentially adding truly static methods to classes. The primary weirdness of this model is that protocols have to pick a keyword (and we chose "class"), but on balance it is the right tradeoff.
And here's a snippet that shows some of the override behavior of class functions:
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With