我可以在Swift库中看到这些定义:
extension Bool : BooleanLiteralConvertible {
static func convertFromBooleanLiteral(value: Bool) -> Bool
}
protocol BooleanLiteralConvertible {
typealias BooleanLiteralType
class func convertFromBooleanLiteral(value: BooleanLiteralType) -> Self
}
定义为static func
的成员函数和定义为class func
的成员函数之间有什么区别?static
用于结构和枚举的静态函数,而class
用于类和协议,这是简单的吗?还有什么其他的区别是我们应该知道的吗?在语法本身中有这种区别的理由是什么?
9条答案
按热度按时间tv6aics11#
为了更清楚,我在这里举一个例子,
static func
与final class func
相同因为它是
final
,我们不能在子类中覆盖它,如下所示:dy1byipe2#
static是用于结构和枚举的静态函数,而class是用于类和协议吗?
这是主要的区别。其他一些区别是类函数是动态调度的,并且可以被子类重写。
协议使用class关键字,但它并不排除实现协议的结构,它们只是使用static。Class被选择用于协议,因此不必使用第三个关键字来表示static或class。
Chris Lattner关于这个主题:
我们考虑统一语法(例如,使用“type”作为关键字),但这实际上并不简单。关键字“class”和“static”对于熟悉性和描述性都很好(一旦你理解了+方法是如何工作的),并且为潜在地向类添加真正的静态方法打开了大门。这个模型的主要奇怪之处在于,协议必须选择一个关键字(我们选择了“class”),但总的来说,这是正确的权衡。
这里有一个片段,显示了类函数的一些重写行为:
bqucvtff3#
我在操场上做了一些实验,得到了一些结论。
TL;DR
正如您所看到的,在
class
的情况下,使用class func
或static func
只是一个习惯问题。Playground示例及说明:
kmynzznz4#
若要声明类型变量属性,请使用
static
声明修饰符标记声明。类可以用class
声明修饰符来标记类型计算属性,以允许子类重写超类的实现。类型属性中讨论了类型属性。在类声明中,关键字
static
的效果与同时使用class
和final
声明修饰符标记声明的效果相同。来源:Swift编程语言-类型变量属性
aoyhnmkz5#
static和class关键字都允许我们将方法附加到类而不是类的示例。例如,您可以创建一个具有name和age等属性的Student类,然后创建一个由Student类本身而不是单个示例拥有的静态方法numberOfStudents。
static和class的不同之处在于它们如何支持继承。当你创建一个静态方法时,它被类拥有,不能被子类改变,而当你使用类时,如果需要的话,它可以被重写。
下面是一个示例代码:
b4lqfgs46#
这个例子将明确每一个方面!
输出:x1c 0d1x
vyu0f0g17#
根据Apple发布的Swift 2.2 Book:
“您可以通过在方法的func关键字之前写入
static
关键字来指示类型方法。类也可以使用class
关键字来允许子类覆盖该方法的超类实现。qgzx9mmu8#
在Swift2.0中,Apple表示:
“在协议中定义类型属性要求时,始终将static关键字作为前缀。即使类型属性要求在由类实现时可以使用class或static关键字作为前缀,该规则也适用:“
ki1q1bka9#
这被称为类型方法,并且使用点语法调用,就像示例方法一样。但是,您是在类型上调用类型方法,而不是在该类型的示例上调用.下面是如何在名为SomeClass的类上调用类型方法: