A Full Overview of Variables and Constants in Swift
CSC630 Full Stack App Development
A Full Overview of Variables and Constants in Swift
Rachna Lewis April 22, 2019
It can be difficult to navigate the unique type system associated with Swift, especially when it comes to understanding the declaration of variables and constants. In this blog post, we will review the difference between the declarative statements"`var`" and "`let`," the difference between using a colon (`:`) and an equals sign (`=`) in various situations, how to use optionals, and generally how the statically typed, strongly typed, and type inferenced aspects of the language function within Swift.
Variables ___
The term "`var`" is used to declare a **variable** in Swift. These are values that are anticipated to change during runtime. Examples of variables in Swift are numbers, text, buttons, or images.
You can declare a variable in one of the following ways:
1. Initialize a value for a general "`var`" and allow type inferencing to take care of defining the data type
2. Declare its data type explicity and then set a value for it
3. Declare its data type and initialize a value all on one line
Another thing to note is that you can declare multiple variables of the same type or multiple variables of different types and/or values all on the same line as seen below:
An **invalid** way to declare a variable would look something like this:
You would recieve an error statement such as:
This is because Swift is a statically typed language, so all variables, constants, and functions must have their types declared in advance (more on that later).
Constants ___
The term "`let`" is used to declare a **constant** in Swift. These are immutable values, which means they cannot be changed after their declaration.
You can declare a constant in one of the following ways:
1. Use "`let`" to initialize a value for a general constant and allow type inferencing to take care of defining the data type
2. Declare its data type explicity and then set a value for it
3. Declare its data type and initialize a value all on one line
Just like with variables, you can also declare multiple constants of the same type or multiple constants of different types and values all on the same line as well.
An **invalid** way to declare a constant would look something like this:
You would recieve the same error statement as we did above by simply typing "`var s`," again due to Swift's statically typed nature.
(Note: A fun feature of Swift is that you can use almost any character you like for constant and variable names, including Unicode characters, emojis, etc.) So, a declaritive statement such as...
would be completely valid.
Colon vs. Equals Sign ___
As you may have already figured out, the **colon** in Swift is used to **declare the type** of a variable or constant whereas the **equals sign** is used to **assign a value** to it. The various data types in Swift include*: * Integer (`Int`) * Small numbers between -128 to 127 (`Int8`) * Zero or any positive value (`UInt`) * String (`String`) * Boolean (`Bool`) * Float (`Float`) * Double (`Double`) * Character (`Character`) * Tuple - a group of various values represented as one ***Note:** I included the declaritive statement for each data type in parenthesis next to their name
An **invalid** use of the colon and the equlas sign to declare a variable or constant would look something like this:

You cannot use an equals sign to declare a data type just as you cannot use a colon to instantiate a value.
**Classes and Functions** ___When dealing with classes and functions, the colon means something entirely different.
For a class declaration, such as:

The class names following the colon represent **superclasses**. The word "`class`" comes right before the class name, `AppDelegate`. Following the colon to the right of the class name are the names of the superclasses, `UIResponder` and `UIApplicationDelegate`, which are the classes that `AppDelegate` inherits methods from. When dealing with superclasses, Swift checks that all overrided methods, properties, and subscripts belonging to their superclass are correct by comparing the override definition with the superclass definition and making sure they match.
For a function declaration, such as:

The word following the colon represents the **parameter type**. The word "`func`" comes right before the function name, `applicationWillResignActive`. Following the first open parenthesis, there is an underscore( `_` ), which supresses something known as the "arguement label" for all the parameters in the function (in this case there is only one parameter). Each item listed after the underscore is in the form `parameter name : parameter type`. An arguement label is simply an alternative name for the parameter name which, if provided in place of that underscore, would have to be used in all method or function calls.
**Optionals (? vs. !)** ___
Optional types can also be used when declaring a variable or constant. They handel the absence of a value and prevent you from being able to encounter null pointer exception in Swift. There are two symbols for optionals:
`?` - explicitly wrapped optional (used for optional binding or optional chaining) - use `?` after the type of a value to indicate that the variable/constant either contains a value or is `nil` to show that the value is missing
`!` - implicitly wrapped optional (used for forced unwrapping) - only use `!` if you are absolutely certain that the optional you are accessing contains a value
In order to understand the nature of variables and constants within Swift (i.e. why declarations as simple as "`var s=3`" work) we must learn about certain aspects of the overall type system of Swift.
There are a few key aspects of Swift that make up its type system. >It's statically typed
>It's strongly typed
>It uses type inference
>It's a type-safe language
**Statically Typed** ___Every variable, constant, and function in Swift is required to have its type declared in advance for it to be valid. Because of this, Swift is said to be "statically typed." When you declare a variable, you can either declare its type directly or leave it to be inferred.
**Strongly Typed** ___During Swift's compile time, it is constantly checking data types and ensuring that they match up. So, whenever you provide an arguement for a function or use a variable or constant, Swift will constantly re-check data types. You are not allowed to pass a string to a function expecting an integer, etc. and that makes Swift "strongly typed." For functions specifically, each function is given a "type-signature" based on its individual parameters and its return type. This type-signature must match up with the type-signature produced by a function call with any and all arguements you provide to a given program.
**Type Inference** ___Type inference, as mentioned above, is the way in which Swift infers the data type of a given variable or constant that does not have one explicitly stated. There are a few steps the compiler undergoes when implementing type inference on a certain variable/constant such as: **1.** _lectical analysis_ - splits input file bytes to units like numbers and strings (ex. `var`, `str`, `=`, `"`, `string`, `"` are all separate) **2.** _syntax analysis_ - also known as parsing, compiler constructs and verifies an [abstract syntax tree](https://en.wikipedia.org/wiki/Abstract_syntax_tree) based on the grammar of the language (ex. constructs the abstract syntax tree for a variable declaration statement: `var variable_name = expression` where expression is a string literal) **3.** _semantic analysis_ (with type inference) - type inference infers the type of the given expression (ex. the expression is a string literal so the compiler would infer the type to be a `String`) **4.** _final steps_ - the compiler typically generates intermediate code, optimizes the intermediate code, and generates assembly code. Then, the tool chain outside of the compiler usually has a linking phase that produces the final executable product Type inference adds a certain amount of convenience to your code to not have to declare your data type every time one is initialized (though you will get the same amount of compiler errors nonetheless so some consider it to be a false benefit).
**Type-Safe** ___Type safety in Swift simply means that when a variable is declared or infered to be of a certain type, you may not modify it later on with or change it into a different data type.
**Reference Sources** https://learnappmaking.com/swift-variables-constants-how-to/ https://docs.swift.org/swift-book/LanguageGuide/TheBasics.html https://stackoverflow.com/questions/34333173/difference-between-and https://stackoverflow.com/questions/24002092/what-is-the-difference-between-let-and-var-in-swift https://www.aidanf.net/learn-swift/types_and_type_inference https://www.programiz.com/swift-programming/data-types https://docs.swift.org/swift-book/ReferenceManual/Declarations.html#grammar_constant-declaration https://stackoverflow.com/questions/28779843/how-does-type-inference-automatic-type-detection-works-in-swift https://stackoverflow.com/questions/24057171/what-the-meaning-of-question-mark-in-swift https://docs.swift.org/swift-book/LanguageGuide/TheBasics.html#//apple_ref/doc/uid/TP40014097-CH5-ID334 https://docs.swift.org/swift-book/LanguageGuide/Inheritance.html