我可以在Swift库中看到这些定义:
extension Bool : BooleanLiteralConvertible {
static func convertFromBooleanLiteral(value: Bool) -> Bool
}
protocol BooleanLiteralConvertible {
typealias BooleanLiteralType
class func convertFromBooleanLiteral(value: BooleanLiteralType) -> Self
}
定义为静态函数
的成员函数和定义为类函数
的成员函数之间有什么区别?简单地说,static
是用于结构和枚举的静态函数,而class
是用于类和协议吗?还有什么其他的不同之处是你应该知道的吗?语法本身有这种区别的理由是什么?
简单地说,static是用于结构和枚举的静态函数,而class是用于类和协议吗?
这是主要的区别。其他一些不同之处在于类函数是动态调度的,并且可以被子类重写。
协议使用class关键字,但它并不排除structs实现协议,它们只是使用static。为协议选择了Class,这样就不必有第三个关键字来表示static或Class。
来自Chris Lattner关于这个话题:
我们考虑过统一语法(例如,使用“type”作为关键字),但这实际上并不简单。关键字“class”和“static”对于熟悉性很好,并且具有相当的描述性(一旦您理解了+方法的工作原理),并且为潜在地将真正静态的方法添加到类中打开了大门。这个模型的主要怪异之处在于,协议必须选择一个关键字(我们选择了“class”),但总的来说,这是一个正确的折衷。
下面的片段显示了类函数的一些重写行为:
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
更清楚地说,我在这里举个例子,
class ClassA {
class func func1() -> String {
return "func1"
}
static func func2() -> String {
return "func2"
}
/* same as above
final class func func2() -> String {
return "func2"
}
*/
}
静态函数
与最终类函数
相同
因为它是final
,所以我们不能在子类中重写它,如下所示:
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"
}
}
我在操场上做了一些实验,得到了一些结论。
您可以看到,在类
的情况下,使用类函数
或静态函数
只是一个习惯问题。
游乐场示例及说明:
class Dog {
final func identity() -> String {
return "Once a woofer, forever a woofer!"
}
class func talk() -> String {
return "Woof woof!"
}
static func eat() -> String {
return "Miam miam"
}
func sleep() -> String {
return "Zzz"
}
}
class Bulldog: Dog {
// Can not override a final function
// override final func identity() -> String {
// return "I'm once a dog but now I'm a cat"
// }
// Can not override a "class func", but redeclare is ok
func talk() -> String {
return "I'm a bulldog, and I don't woof."
}
// Same as "class func"
func eat() -> String {
return "I'm a bulldog, and I don't eat."
}
// Normal function can be overridden
override func sleep() -> String {
return "I'm a bulldog, and I don't sleep."
}
}
let dog = Dog()
let bullDog = Bulldog()
// FINAL FUNC
//print(Dog.identity()) // compile error
print(dog.identity()) // print "Once a woofer, forever a woofer!"
//print(Bulldog.identity()) // compile 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()) // compile 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()) // compile 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()) // compile error
print(dog.sleep()) // print "Zzz"
//print(Bulldog.sleep()) // compile error
print(bullDog.sleep()) // print "I'm a bulldog, and I don't sleep."