When to Use Static Constant and Variable in Swift

When to use static constant and variable in Swift?

When you define a static var/let into a class (or struct), that information will be shared among all the instances (or values).

Sharing information

class Animal {
static var nums = 0

init() {
Animal.nums += 1
}
}

let dog = Animal()
Animal.nums // 1
let cat = Animal()
Animal.nums // 2

As you can see here, I created 2 separate instances of Animal but both do share the same static variable nums.

Singleton

Often a static constant is used to adopt the Singleton pattern. In this case we want no more than 1 instance of a class to be allocated.
To do that we save the reference to the shared instance inside a constant and we do hide the initializer.

class Singleton {
static let sharedInstance = Singleton()

private init() { }

func doSomething() { }
}

Now when we need the Singleton instance we write

Singleton.sharedInstance.doSomething()
Singleton.sharedInstance.doSomething()
Singleton.sharedInstance.doSomething()

This approach does allow us to use always the same instance, even in different points of the app.

What is the use of static keyword if let keyword used to define constants/immutables in swift?

I will break them down for you:

  • var : used to create a variable
  • let : used to create a constant
  • static : used to create type properties with either let or var. These are shared between all objects of a class.

Now you can combine to get the desired out come:

  • static let key = "API_KEY" : type property that is constant
  • static var cnt = 0 : type property that is a variable
  • let id = 0 : constant (can be assigned only once, but can be assigned at run time)
  • var price = 0 : variable

So to sum everything up var and let define mutability while static and lack of define scope. You might use static var to keep track of how many instances you have created, while you might want to use just varfor a price that is different from object to object. Hope this clears things up a bit.

Example Code:

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

What is the purpose of using static on a constant in a Swift structure?

It has multiple applications, including but not limited by the following:

1) To give a constant separate namespace, if constants have same names.

struct A {
static let width: Int = 100
}

struct B {
static let width: Int = 100
}
print(A.width)
print(B.width)

2) Static constants are 'lazy' by design, so if you are about to use lazy-behaved global constant, it might be handy to put it in a structure.

3) To show your coworkers that constant is applicable to specific domain where given structure is used.

4) Organize your configuration in sections:Theme.Layout.itemHeight or Label.Font.avenirNext

Why can I define a static constant that depends on another static constant in the same type, but not for properties?

Type and instance.

  • The type MyStruct always exists. static properties belong to the type. So they just sit there and can do anything they like or be related in any way. Okay, yes, it has to come into existence when the program starts, but under the hood the static property initializers are all lazy so it's okay for one to depend on another (not in a circular way of course).

  • An instance of MyStruct is a thing that has to be created, each time you say MyStruct(...). When you say that, the instance properties must be initialized. An instance (not static) property belongs to the instance. So its initializer's value cannot refer to self because self is exactly what we are in the middle of creating, i.e. the instance. This line:

    let myInstancePlusOne = myInstance + 1

    ...really means

    let myInstancePlusOne = self.myInstance + 1

    ...but that is exactly what you are not allowed to say; at the time you are initializing this property there is no self yet, it is what you are initializing. And you can work around this by declaring that property lazy (with other adjustments in the syntax).

static let vs let for declaring class specific constants

Neither. Use an uninhabited (caseless) enum to create a Constant namespace; it reads better.

class CurrencyConverter {
private enum Constant {
static let conversionRate = 1.3
}
func convertToForeign(fromlocal local: Double) -> Double {
return local * Constant.conversionRate
}
}

let c = CurrencyConverter()
print(c.convertToForeign(fromlocal: 5))

Static var being treated as let constant?

You are confusing the compiler here. First your syntax is wrong in terms of how you pass parameters, it should be : instead of =, then you should remove the static and change the order of the parameters:

struct someUrl {
var keywords = String()
var someUrlStart = String()
var someUrlEnd = String()
}

class Url {
var someUrlConstructor: someUrl

init(keywords: String, someUrlEnd: String, someUrlStart: String) {
self.someUrlConstructor = someUrl(keywords: keywords, someUrlStart: someUrlStart, someUrlEnd: someUrlEnd)
}
}

Alternatively if you want to keep them static remove the parameters completely since now they are static variables and not member / instance variables:

struct someUrl {
static var keywords = String()
static var someUrlStart = String()
static var someUrlEnd = String()
}

class Url {
var someUrlConstructor: someUrl

init(keywords: String, someUrlEnd: String, someUrlStart: String) {
self.someUrlConstructor = someUrl()
}
}

What the compiler thought you were doing (or basically what you were in fact doing writing =) was trying to change the someUrlEnd (and the other two) you were given as a initializer parameter which is in fact a constant.


Apart from the wrong syntax I do not see a use for the static or for the class Url, just take the struct someUrl, its default initializer and go from there. General note: please upper case the first letter of the struct: SomeUrl.

What does static imply on constant within an enum or struct

It means myVariable is a type property – a single property that all instances of the type can use. Essentially a global variable associated with MyEnum.

In the case of constants declared with let, this is a way of declaring constants that are scoped to the type that don’t take up space within each instance of that type, i.e.:

struct MySlimStruct {
static let myVariable = "some value"
}

sizeof(MySlimStruct) // returns 0

struct MyFatStruct {
let myVariable = "some value"
}

sizeof(MyFatStruct) // returns 24

In the case of static variables declared with var, this is a good way of introducing undiagnosable bugs and crashes into your program.

How to define static constant in a generic class in swift?

You can define global constant with fileprivate or private access level in the same .swift file where your generic class is defined. So it will not be visible outside of this file and will not pollute global (module) namespace.

If you need to access this constant from outside of current file then declare it as internal (default access level) or public and name it like ClassConstant so it will be obvious that it relates to Class.

Read more about access levels in Swift 3.



Related Topics



Leave a reply



Submit