Swift中表示“类型范围作用域”这一概念有两个不同的关键字,它们分别是static和class。这两个关键字确实都表达了这个意思,但是在其他一些语言,包括Objective-C中,我们并不会特别地区分类变量/类方法和静态变量/静态函数。但是在Swift的早期版本中,这两个关键字却是不能用混的。
在非class的类型上下文中,我们统一使用static来描述类型作用域。这包括在enum和struct中表述类型方法和类型属性时。在这两个值类型中,我们可以在类型范围内声明并使用存储属性、计算属性和方法。static适用的场景如下:
enum的情况与这个十分类似,就不再列举了。
class关键字相对就明白许多,是专门用在class类型的上下文中的,可以用来修饰类方法及类的计算属性。但要注意,class中现在是不能出现存储属性的,我们如果写类似这样的代码:
编译时会得到一个错误:
class variables not yet supported
在Swift1.2之后,我们可以在class中使用static来声明一个类作用域的变量。也即:
这样的写法是合法的。有了这个特性之后,像单例(见第106页)的写法就可以回归到我们所习惯的方式了。
有一个比较特殊的是protocol。在Swift中class、struct和enum都是可以实现protocol的。那么如果我们想在protocol里定义一个类型域上的方法或者计算属性,应该用哪个关键字呢?答案是使用static进行定义。在使用时,struct或enum中仍然使用static,而在class中既可以使用class关键字,也可以使用static,它们的结果是相同的:
在Swift1.2之前protocol中使用class作为关键字,但这确实是不合逻辑的。Swift1.2和2.0分两次对此进行了改进。现在只需要记住结论,在任何时候使用static应该都是没有问题的。