简体   繁体   中英

Access static variables within class in Swift

Is ClassName.staticVaribale the only way to access static variable within the class? I want something like self , but for class. Like class.staticVariable .

There are two ways to access a static property/method from a non-static property/method:

  1. As stated in your question, you can prefix the property/method name with that of the type:

     class MyClass { static let staticProperty = 0 func method() { print(MyClass.staticProperty) } } 
  2. Swift 2: You can use dynamicType :

     class MyClass { static let staticProperty = 0 func method() { print(self.dynamicType.staticProperty) } } 

    Swift 3: You can use type(of:) (thanks @Sea Coast of Tibet):

     class MyClass { static let staticProperty = 0 func method() { print(type(of: self).staticProperty) } } 

If you're inside a static property/method you do not need to prefix the static property/method with anything:

class MyClass {
    static let staticProperty = 0

    static func staticMethod() {
        print(staticProperty)
    }
}

There is a way in Swift to make Marcel's answer satisfy even most picky style-guide gods

class MyClass {

    private typealias `Self` = MyClass

    static let MyConst = 5

    func printConst() {
        print(Self.MyConst)
    }
}

That makes Self available like in protocols when you want access associated type declaration. I am not sure about Swift 1 because never tried it but in Swift 2 it works perfectly

In a future Swift 3 version (yet to be released) you can use Self (yes, that's with a capital) to reference to the containing class. A proposal for this was accepted, but the feature is not implemented yet.

For example:

struct CustomStruct {          
 static func staticMethod() { ... } 

 func instanceMethod() {          
   Self.staticMethod() // in the body of the type          
 }          
}

Source: https://github.com/apple/swift-evolution/blob/master/proposals/0068-universal-self.md

You could work around this by defining a self referencing typealias.

class MyClassWithALongName {
  typealias CLASS = MyClassWithALongName

  static let staticFoo = "foo"

  func someInstanceMethod() -> String {
    return CLASS.staticFoo
  }
}

Though the style-guide gods may not approve.

It looks like in Swift 4.2 the inner class and instance variable can directly access the static variable without the prefix of the class name. However, you still need the class name within a function.

class MyClass {
    static let staticProperty = 0
    let property = staticProperty //YES

    class Inner {
        func method() {
            print(staticProperty) //YES
        }
    }

    func method() {
        print(staticProperty) //NO
        print(MyClass.staticProperty) //YES
    }
}

I don't like the typealias way in this case. My workaround is:

class MyClass {

   static let myStaticConst: Int = 1
   var myStaticConst:Int {
      return type(of: self).myStaticConst
   }

   func method() {
      let i:Int = myStaticConst
   }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM