如果“ let”关键字用于快速定义常量/不可变变量,那么“ static”关键字有什么用?


68

我对在Swift中使用static关键字有些困惑。众所周知,swift引入了let关键字来声明不可变对象。就像声明表视图单元格的ID一样,该ID在其生命周期中很可能不会改变。现在在一些类似struct的声明中使用static关键字是什么:

struct classConstants
{
    static let test = "test"
    static var totalCount = 0
}

关键字做同样的事情。在目标C中,我们使用static声明了一些常量,例如

static NSString *cellIdentifier=@"cellId";

除了让我更好奇的是,还使用了static关键字以及letvar关键字。有人可以解释一下该静态关键字在哪里使用吗?更重要的是,我们真的需要快速静态化吗?


8
如果您不知道什么是静态的,建议您先阅读一些OOP书籍,然后再开始快速撰写。静态变量在对象的所有实例之间共享,如果它是const(let),那么它就是不可变的
Daniel Krom

4
@DanielKrom:据我了解,我使用static声明了C语言(目标C)中的某些常数。因此,我认为letstatic是相同的。
波兰人

10
在C和Objective-C中,静态不是常数(除非您将它们定义为常数),您可能不太了解这一点,这很好,没有人出生于知识,静态是一种全局变量
Daniel Krom

静态定义一个类型属性:“类型属性实例属性是属于特定类型实例的属性。每次创建该类型的新实例时,它都有自己的一组属性值,与其他任何实例分开。您还可以定义属于类型本身的属性,而不是属于该类型的任何一个实例的属性。无论您创建了多少个该类型的实例,这些属性将永远只有一个副本。这些属性称为类型属性。” “ Swift编程语言(Swift 3)”。
abanet

1
这是一个好问题。当实例属性的值在编译时完全已知(例如let =“ hello,world”)时,就会出现一个合理的问题:为什么要对实例属性使用静态属性?有人认为编译器足够聪明,可以优化重复值。静态属性会带来一些不便(在使用该属性之前必须包括类型命名空间)。
Womble

Answers:


128

我将为您分解它们:

  • var :用于创建变量
  • let :用于创建常量
  • static:用于创建类型属性与任一letvar。这些在类的所有对象之间共享。

现在,您可以结合起来以得到想要的效果:

  • static let key = "API_KEY" :常量的类型属性
  • static var cnt = 0 :类型属性是一个变量
  • let id = 0 :常量(只能分配一次,但可以在运行时分配)
  • var price = 0 :变量

因此,将所有内容归纳为var,让其定义为可变性,而使之静态且缺少定义范围。您可能会static var一直跟踪自己创建了多少个实例,而您可能只想使用var一个价格因对象而异的对象。希望这能使事情变得顺利。

示例代码:

class MyClass{
    static let typeProperty = "API_KEY"
    static var instancesOfMyClass = 0
    var price = 9.99
    let id = 5

}

let obj = MyClass()
obj.price // 9.99
obj.id // 5

MyClass.typeProperty // "API_KEY"
MyClass.instancesOfMyClass // 0

let:用于创建常量” =>用let关键字声明的变量可以在以后(即在构造函数中)赋值(仅一次),这与CONSTANT的定义矛盾。如果我们与其他语言(例如C#)进行比较,let则与C#readonly(不是const)相同
Hassan Tareq

这与static let目标c等效,因为我必须在视图控制器中定义uiaplicationdidenterbackground
iOS开发人员

3
尽管我认为从技术上讲它是正确的,但您从未提供过一个为什么我需要静态覆盖的示例。
YungGun

124

静态变量在类的所有实例之间共享。将此示例扔到操场上:

class Vehicle {
    var car = "Lexus"
    static var suv = "Jeep"
}

// changing nonstatic variable
Vehicle().car // Lexus
Vehicle().car = "Mercedes"
Vehicle().car // Lexus

// changing static variable
Vehicle.suv // Jeep
Vehicle.suv = "Hummer"
Vehicle.suv // Hummer

现在,当您更改静态属性的变量时,该属性现在将在以后的所有实例中更改。


Vehicle()。car,给出Lexus,但让vehObj = Vehicle(); vehObj.car,送给梅赛德斯。我不知道为什么 什么是差异?你可以引导我吗?
McDonal_19年

vehObj.car给了我雷克萨斯,我不知道你为什么要买梅塞德斯
Bobby

令suv = Vehicle(); suv.suv //吉普车;令suv2 = Vehicle(); suv2.suv =“悍马”; 令suv3 = Vehicle(); suv3.suv //悍马; 如果我随后转到“ suv.suv”,它将返回“吉普”或“悍马”吗?该值是针对该对象的所有实例还是仅将来的实例更改?如果仅针对将来的实例进行更改,那为什么呢?为什么不是所有实例?抱歉,这是一个愚蠢的问题。我想我还没有看到静态变量的大量应用。
Mikael Weiss

12

静态变量属于类型而不是类的实例。您可以使用类型的全名来访问静态变量。

码:

class IOS {

  var iosStoredTypeProperty = "iOS Developer"

  static var swiftStoredTypeProperty = "Swift Developer"

 }

 //Access the iosStoredTypeProperty by way of creating instance of IOS Class

let iOSObj = IOS()

print(iOSObj.iosStoredTypeProperty)  // iOS Developer


 //print(iOSObj.swiftStoredTypeProperty) 
 //Xcode shows the error 
 //"static member 'swiftStoredTypeProperty' cannot be used on instance of type IOS”


 //You can access the static property by using full name of the type
print(IOS.swiftStoredTypeProperty)  // Swift Developer

希望这对您有帮助。


1

要查看类型属性和/或方法与类属性和/或方法之间的区别,请查看苹果文档中的这个自我说明性示例

class SomeClass {
    static var storedTypeProperty = "Some value."
    static var computedTypeProperty: Int {
        return 27
    }
    class var overrideableComputedTypeProperty: Int {
        return 107
    }
}

静态属性只能在类型上声明,而不能在全局上声明。换句话说,静态属性=== Swift中的type属性。要声明类型属性,您必须使用static关键字。


1
您正在通过使用static本身来解释static。OP并没有真正意识到它的含义……
亲爱的,

3
@ asma22 ?? 关键字static在swift和c语言中具有完全不同的含义。快速的静态表示“类型”(属性或功能)。“静态”属性与“类”属性或函数之间的区别在于,“类”属性或函数可以被覆盖,而“静态”属性不能被重写。因为大多数有背景的人在其他情况下都使用“静态”,所以即使关键字是“静态”,苹果也建议使用“类型”一词进行解释
user3441734

1

对于来自C#背景的初学者(例如我),“ let关键字定义了一个常数”令人困惑。用C#术语,您可以将“ let”视为“ readonly”变量

(回答“ let”关键字在Swift中的工作原理如何?

同时使用staticlet定义常量

public static let pi = 3.1416            // swift

public const double pi = 3.1416;         // C#
public static final double pi = 3.1416   // Java     

每当我let用来定义常量时,就好像我在使用readonlyC#。因此,我同时使用staticlet来定义常量。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.