How are they different? I get a bit confused because they seem to be similar concepts.
How does understanding them help with optimizing compilation time?
Type Safety and Type InferenceSwift is a type-safe language. A type safe language encourages you to be clear about the types of values your code can work with. If part of your code requires a String , you can't pass it an Int by mistake.
A Type Checker only verifies that the given declarations are consistent with their use. Examples: type checkers for Pascal, C. A Type Inference system generates consistent type declarations from information implicit in the program.
Type inference is the ability to automatically deduce, either partially or fully, the type of an expression at compile time. The compiler is often able to infer the type of a variable or the type signature of a function, without explicit type annotations having been given.
Standard ML is a strongly and statically typed programming language. However, unlike many other strongly typed languages, the types of literals, values, expressions and functions in a program will be calculated by the Standard ML system when the program is compiled. This calculation of types is called type inference.
Type Safety in Java. The Java language, by design, enforces type safety. It implies that Java prevents the programs from accessing memory in inappropriate ways by controlling the memory access of each object. Java does this by using objects (instantiated from classes) to perform operations.
Swift uses type inference extensively, allowing you to omit the type or part of the type of many variables and expressions in your code. For example, instead of writing var x: Int = 0 , you can write var x = 0 , omitting the type completely—the compiler correctly infers that x names a value of type Int .
From Swift's own documentation:
Swift is a type-safe language. A type safe language encourages you to be clear about the types of values your code can work with. If part of your code expects a String, you can’t pass it an Int by mistake.
var welcomeMessage: String
welcomeMessage = 22 // this would create an error because you
//already specified that it's going to be a String
If you don’t specify the type of value you need, Swift uses type inference to work out the appropriate type. Type inference enables a compiler to deduce the type of a particular expression automatically when it compiles your code, simply by examining the values you provide.
var meaningOfLife = 42 // meaningOfLife is inferred to be of type Int
meaningOfLife = 55 // it Works, because 55 is an Int
Type Safety & Type Inference together
var meaningOfLife = 42 // 'Type inference' happened here, we didn't specify that this an Int, the compiler itself found out.
meaningOfLife = 55 // it Works, because 55 is an Int
meaningOfLife = "SomeString" // Because of 'Type Safety' ability you will get an
//error message: 'cannot assign value of type 'String' to type 'Int''
Imagine the following protocol
protocol Identifiable {
associatedtype ID
var id: ID { get set }
}
You would adopt it like this:
struct Person: Identifiable {
typealias ID = String
var id: String
}
However you can also adopt it like this:
struct Website: Identifiable {
var id: URL
}
You can remove the typealias
. The compiler will still infer the type.
For more see Generics - Associated Types
Thanks to Swift’s type inference, you don’t actually need to declare a concrete Item of Int as part of the definition of IntStack. Because IntStack conforms to all of the requirements of the Container protocol, Swift can infer the appropriate Item to use, simply by looking at the type of the append(_:) method’s item parameter and the return type of the subscript. Indeed, if you delete the typealias Item = Int line from the code above, everything still works, because it’s clear what type should be used for Item.
Suppose you have the following code:
struct Helper<T: Numeric> {
func adder(_ num1: T, _ num2: T) -> T {
return num1 + num2
}
var num: T
}
T
can be anything that's numeric e.g. Int
, Double
, Int64
, etc.
However as soon as you type let h = Helper(num: 10)
the compiler will assume that T
is an Int
. It won't accept Double
, Int64
, for its adder
func anymore. It will only accept Int
.
This is again because of type-inference and type-safety.
Int
.T
is set to be of type Int
, it will no longer accept Int64
, Double
...As you can see in the screenshot the signature is now changed to only accept a parameter of type Int
The less type inference your code has to do the faster it compiles. Hence it's recommended to avoid collection literals. And the longer a collection gets, the slower its type inference becomes...
not bad
let names = ["John", "Ali", "Jane", " Taika"]
good
let names : [String] = ["John", "Ali", "Jane", " Taika"]
For more see this answer.
Also see Why is Swift compile time so slow?
The solution helped his compilation time go down from 10/15 seconds to a single second.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With