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 variablelet
: used to create a constantstatic
: used to create type properties with eitherlet
orvar
. 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 constantstatic var cnt = 0
: type property that is a variablelet 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 var
for 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 alllazy
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 (notstatic
) property belongs to the instance. So its initializer's value cannot refer toself
becauseself
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 propertylazy
(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
Alamofire: Finished with Error - Code: -1001
Doing Undo and Redo with Cglayer Drawing
iOS Scatter Core Plot with a Gap
Undo with Multitouch Drawing in iOS
Parsing JSON Within JSON in Objective-C
Integrate Google Contacts API into My Swift 3 App
Delete App from Itunes Connect
Xmlparser.Sharedparser.Decode() in Swift3
Make Timer Run on Background iOS for More Than 3 Minutes
JSON Text Did Not Start with Array or Object and Option to Allow Fragments Not Set
How to Load Icarousel View from Storyboard or Xib
iOS Web Page Errors Over Cellular Data But Not Over Wifi? Recent Change to At&T Cellular Network
How to Completely Hide the Status Bar in iOS Using Cordova
Can't Submit Apps to Appstore: Error Itms-90534: "Invalid Toolchain