Static class variables

I have a very simple class in Swift 2.0.


import UIKit
class ConsoleViewController: UIViewController {
    static let DEFAULT_Y_MARGIN: Float = 10.0
    var margin: Float = DEFAULT_Y_MARGIN
    
    func clear() {
        margin = DEFAULT_Y_MARGIN
    }
}


While the margin class variable seems okay, the compiler seems to have a problem with the setting the margin variable in the clear() method. I get the error message ConsoleViewController.swift:17:18: 'ConsoleViewController' does not have a member named 'DEFAULT_Y_MARGIN'. Is that a bug?


Alternatively, is there a better way to have static constant class variables that I'm missing? I'd like to be able to give constants a name, so I can use the much more readable DEFAULT_Y_MARGIN over 10.0. Is there a way to set this up where that variable is scoped to the class and I can use it like that?

When you set a default value for a stored property, the only properties which can be accessed are the static/type properties of the class, so the compiler is automatically accessing DEFAULT_Y_MARGIN as a static property to set the default value of the instance 'margin' property.


From within your instance methods like clear(), you need to access it as ConsoleViewController.DEFAULT_Y_MARGIN, because it is a static/type property and not an instance property.



As long as you are declaring one or two classes per file, using the private access level for a per-file constant seems to work well.


import UIKit

private let DEFAULT_Y_MARGIN: Float = 10.0

class ConsoleViewController: UIViewController
{
    var margin: Float = DEFAULT_Y_MARGIN
   
    func clear() {
        margin = DEFAULT_Y_MARGIN
    }
}

Are you coming from C#? As someone who mostly used C# before Swift, I didn't get this either, at first. In C#, you can reference a static member without the type name, but only from within the class in which it is defined. In Swift, you're not allowed to do that, which is actually awesome, because it allows you to have static and non-static members with the same name.


static let allCapsCanGoToHeck = Float(10)
var margin = allCapsCanGoToHeck
func clear() {
    margin = ConsoleViewController.allCapsCanGoToHeck
}

Private inside of the file looks like just what I want. Thanks for the help!

I quite like the construct


class ConsoleViewController:UIViewController {
     private struct Constants {
          static let DefaultYMargin = Float(10)
     }

     func clear() {
          margin = Constants.DefaultYMargin
     }
}


or if you want to be extra pedantic you can nest the constants


private struct Constants {
     struct DefaultMargins {
          static let Y = Float(10)
          static let X = Float(0)
     }
}
func clear() {
     margin = Constants.DefaultMargins.Y
}

Mr Bug, you are also thinking in C#. Tuples remove the need for data-only structs.

class ConsoleViewController: UIViewController {
    private static let defaultMargins = (
        x: Float(10),
        y: Float(0)
    )
      
    func clear() {
        margin = ConsoleViewController.defaultMargins.x
    }

If you try to wrap defaultMargins in a tuple named constants, it won't compile until you add something that is not defaultMargins. Constants are such an integral part of Swift that I don't see a point in marking them as such, however.

Static class variables
 
 
Q