Type Inference
If a variable or constant declaration is not annotated explicitly with a type, the declaration's type is inferred from the initial value.
Basic Literals
Decimal integer literals and hex literals are inferred to type Int
.
_10let a = 1_10// `a` has type `Int`_10_10let b = -45_10// `b` has type `Int`_10_10let c = 0x02_10// `c` has type `Int`
Unsigned fixed-point literals are inferred to type UFix64
.
Signed fixed-point literals are inferred to type Fix64
.
_10let a = 1.2_10// `a` has type `UFix64`_10_10let b = -1.2_10// `b` has type `Fix64`
Similarly, for other basic literals, the types are inferred in the following manner:
Literal Kind | Example | Inferred Type (x) |
---|---|---|
String literal | let x = "hello" | String |
Boolean literal | let x = true | Bool |
Nil literal | let x = nil | Never? |
Array Literals
Array literals are inferred based on the elements of the literal, and to be variable-size. The inferred element type is the least common super-type of all elements.
_14let integers = [1, 2]_14// `integers` has type `[Int]`_14_14let int8Array = [Int8(1), Int8(2)]_14// `int8Array` has type `[Int8]`_14_14let mixedIntegers = [UInt(65), 6, 275, Int128(13423)]_14// `mixedIntegers` has type `[Integer]`_14_14let nilableIntegers = [1, nil, 2, 3, nil]_14// `nilableIntegers` has type `[Int?]`_14_14let mixed = [1, true, 2, false]_14// `mixed` has type `[AnyStruct]`
Dictionary Literals
Dictionary literals are inferred based on the keys and values of the literal. The inferred type of keys and values is the least common super-type of all keys and values, respectively.
_20let booleans = {_20 1: true,_20 2: false_20}_20// `booleans` has type `{Int: Bool}`_20_20let mixed = {_20 Int8(1): true,_20 Int64(2): "hello"_20}_20// `mixed` has type `{Integer: AnyStruct}`_20_20// Invalid: mixed keys_20//_20let invalidMixed = {_20 1: true,_20 false: 2_20}_20// The least common super-type of the keys is `AnyStruct`._20// But it is not a valid type for dictionary keys.
Ternary Expression
Ternary expression type is inferred to be the least common super-type of the second and third operands.
_10let a = true ? 1 : 2_10// `a` has type `Int`_10_10let b = true ? 1 : nil_10// `b` has type `Int?`_10_10let c = true ? 5 : (false ? "hello" : nil)_10// `c` has type `AnyStruct`
Functions
Functions are inferred based on the parameter types and the return type.
_10let add = (a: Int8, b: Int8): Int {_10 return a + b_10}_10_10// `add` has type `fun(Int8, Int8): Int`
Type inference is performed for each expression / statement, and not across statements.
Ambiguities
There are cases where types cannot be inferred. In these cases explicit type annotations are required.
_10// Invalid: not possible to infer type based on array literal's elements._10//_10let array = []_10_10// Instead, specify the array type and the concrete element type, e.g. `Int`._10//_10let array: [Int] = []_10_10// Or, use a simple-cast to annotate the expression with a type._10let array = [] as [Int]
_11// Invalid: not possible to infer type based on dictionary literal's keys and values._11//_11let dictionary = {}_11_11// Instead, specify the dictionary type and the concrete key_11// and value types, e.g. `String` and `Int`._11//_11let dictionary: {String: Int} = {}_11_11// Or, use a simple-cast to annotate the expression with a type._11let dictionary = {} as {String: Int}