Simulating Type Properties for Classes in Swift

In Swift, static properties are only allowed with structs and enums, making the following construct illegal:

class A {
  static var typeProperty: Int = 1001
}

The compiler isn’t happy and we get this error message:

<REPL>:2:14: error: static properties are only allowed within structs and enums; use 'class' to declare a class property
      static var typeProperty: Int = 1001
      ~~~~~~ ^
      class

Lets follow the helpful message and replace static with class:

class A {
  static var typeProperty: Int = 1001
}

The compiler is still unhappy.

Playground execution failed: error: <REPL>:29:3: error: class variables not yet supported
  class var typeProperty: Int = 1001
  ^~~~~

Turns out that (for now) Swift only allows type properties in a class is through the use of getters/setters:

class B {
  class var typeProperty: Int {
    return 10001
  }
}

Now Swift is happy:

println(B.typeProperty)

and rewards us with the following output:

10001

So we know that (for now) class static/type properties must use getters/setters. The downside with getters is that the getter block is evaluated each time the type property is accessed. Since class variables are not yet supported (see friendly error message above), a workaround for a one-time evaluation is to use a nested struct:

class C {
  struct A {
    static var typeProperty: Int = 1001
  }
}

Nesting results in a longer access path:

println(C.A.typeProperty)
//prints 1001

We can wrap the nested call in a class variable / getter, to hide / reduce the path:

class C {
  struct A {
    static var typeProperty: Int = 1001
  }
  
  class var typeProperty: Int {
    return A.typeProperty
  }
}

println(C.A.typeProperty)
println(C.typeProperty)

The output is as expected:

1001
1001

Bottomline: use a nested struct for one-time lazily evaluated static/type variables in classes.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s