Optional

enum Optional

A type that represents either a wrapped value or nil, the absence of a value.

Inheritance ExpressibleByNilLiteral, CustomDebugStringConvertible, CustomReflectable

You use the Optional type whenever you use optional values, even if you never type the word Optional. Swift's type system usually shows the wrapped type's name with a trailing question mark (?) instead of showing the full type name. For example, if a variable has the type Int?, that's just another way of writing Optional<Int>. The shortened form is preferred for ease of reading and writing code.

The types of shortForm and longForm in the following code sample are the same:

let shortForm: Int? = Int("42")
let longForm: Optional<Int> = Int("42")

The Optional type is an enumeration with two cases. Optional.none is equivalent to the nil literal. Optional.some(Wrapped) stores a wrapped value. For example:

let number: Int? = Optional.some(42)
let noNumber: Int? = Optional.none
print(noNumber == nil)
// Prints "true"

You must unwrap the value of an Optional instance before you can use it in many contexts. Because Swift provides several ways to safely unwrap optional values, you can choose the one that helps you write clear, concise code.

The following examples use this dictionary of image names and file paths:

let imagePaths = ["star": "/glyphs/star.png",
                  "portrait": "/images/content/portrait.jpg",
                  "spacer": "/images/shared/spacer.gif"]

Getting a dictionary's value using a key returns an optional value, so imagePaths["star"] has type Optional<String> or, written in the preferred manner, String?.

Optional Binding

To conditionally bind the wrapped value of an Optional instance to a new variable, use one of the optional binding control structures, including if let, guard let, and switch.

if let starPath = imagePaths["star"] {
    print("The star image is at '\(starPath)'")
} else {
    print("Couldn't find the star image")
}
// Prints "The star image is at '/glyphs/star.png'"

Optional Chaining

To safely access the properties and methods of a wrapped instance, use the postfix optional chaining operator (postfix ?). The following example uses optional chaining to access the hasSuffix(_:) method on a String? instance.

if imagePaths["star"]?.hasSuffix(".png") == true {
    print("The star image is in PNG format")
}
// Prints "The star image is in PNG format"

Using the Nil-Coalescing Operator

Use the nil-coalescing operator (??) to supply a default value in case the Optional instance is nil. Here a default path is supplied for an image that is missing from imagePaths.

let defaultImagePath = "/images/default.png"
let heartPath = imagePaths["heart"] ?? defaultImagePath
print(heartPath)
// Prints "/images/default.png"

The ?? operator also works with another Optional instance on the right-hand side. As a result, you can chain multiple ?? operators together.

let shapePath = imagePaths["cir"] ?? imagePaths["squ"] ?? defaultImagePath
print(shapePath)
// Prints "/images/default.png"

Unconditional Unwrapping

When you're certain that an instance of Optional contains a value, you can unconditionally unwrap the value by using the forced unwrap operator (postfix !). For example, the result of the failable Int initializer is unconditionally unwrapped in the example below.

let number = Int("42")!
print(number)
// Prints "42"

You can also perform unconditional optional chaining by using the postfix ! operator.

let isPNG = imagePaths["star"]!.hasSuffix(".png")
print(isPNG)
// Prints "true"

Unconditionally unwrapping a nil instance with ! triggers a runtime error.

Cases

case none Required

The absence of a value.

In code, the absence of a value is typically written using the nil literal rather than the explicit .none enumeration case.

Declaration

case none
case some Required

The presence of a value, stored as Wrapped.

Declaration

case some(: Wrapped)

Initializers

init init(_:) Required

Creates an instance that stores the given value.

Declaration

public init(_ some: Wrapped)
init init(nilLiteral:) Required

Creates an instance initialized with nil.

Do not call this initializer directly. It is used by the compiler when you initialize an Optional instance with a nil literal. For example:

var i: Index? = nil

In this example, the assignment to the i variable calls this initializer behind the scenes.

Declaration

public init(nilLiteral: ())

Instance Variables

var customMirror Required

The custom mirror for this instance.

If this type has value semantics, the mirror should be unaffected by subsequent mutations of the instance.

Declaration

var customMirror: Mirror
var debugDescription Required

A textual representation of this instance, suitable for debugging.

Declaration

var debugDescription: String
var unsafelyUnwrapped Required

The wrapped value of this instance, unwrapped without checking whether the instance is nil.

The unsafelyUnwrapped property provides the same value as the forced unwrap operator (postfix !). However, in optimized builds (-O), no check is performed to ensure that the current instance actually has a value. Accessing this property in the case of a nil value is a serious programming error and could lead to undefined behavior or a runtime error.

In debug builds (-Onone), the unsafelyUnwrapped property has the same behavior as using the postfix ! operator and triggers a runtime error if the instance is nil.

The unsafelyUnwrapped property is recommended over calling the unsafeBitCast(_:) function because the property is more restrictive and because accessing the property still performs checking in debug builds.

Warning: This property trades safety for performance. Use unsafelyUnwrapped only when you are confident that this instance will never be equal to nil and only after you've tried using the postfix ! operator.

Declaration

var unsafelyUnwrapped: Wrapped

Instance Methods

func flatMap(_ transform: (Wrapped) throws -> U?) rethrows -> U? Required

Evaluates the given closure when this Optional instance is not nil, passing the unwrapped value as a parameter.

Use the flatMap method with a closure that returns an optional value. This example performs an arithmetic operation with an optional result on an optional integer.

let possibleNumber: Int? = Int("42")
let nonOverflowingSquare = possibleNumber.flatMap { x -> Int? in
    let (result, overflowed) = x.multipliedReportingOverflow(by: x)
    return overflowed ? nil : result
}
print(nonOverflowingSquare)
// Prints "Optional(1764)"
  • Parameter transform: A closure that takes the unwrapped value of the instance.

Declaration

@inlinable public func flatMap<U>(_ transform: (Wrapped) throws -> U?) rethrows -> U?
func map(_ transform: (Wrapped) throws -> U) rethrows -> U? Required

Evaluates the given closure when this Optional instance is not nil, passing the unwrapped value as a parameter.

Use the map method with a closure that returns a non-optional value. This example performs an arithmetic operation on an optional integer.

let possibleNumber: Int? = Int("42")
let possibleSquare = possibleNumber.map { $0 * $0 }
print(possibleSquare)
// Prints "Optional(1764)"

let noNumber: Int? = nil
let noSquare = noNumber.map { $0 * $0 }
print(noSquare)
// Prints "nil"
  • Parameter transform: A closure that takes the unwrapped value of the instance.

Declaration

@inlinable public func map<U>(_ transform: (Wrapped) throws -> U) rethrows -> U?

Type Methods

func !=(lhs: Wrapped?, rhs: _OptionalNilComparisonType) -> Bool Required

Returns a Boolean value indicating whether the left-hand-side argument is not nil.

You can use this not-equal-to operator (!=) to test whether an optional instance is not nil even when the wrapped value's type does not conform to the Equatable protocol.

The following example declares the stream variable as an optional instance of a hypothetical DataStream type. Although DataStream is not an Equatable type, this operator allows checking whether stream wraps a value and is therefore not nil.

var stream: DataStream? = fetchDataStream()
if stream != nil {
    print("The data stream has been configured.")
}
// Prints "The data stream has been configured."

Declaration

public static func !=(lhs: Wrapped?, rhs: _OptionalNilComparisonType) -> Bool
func !=(lhs: _OptionalNilComparisonType, rhs: Wrapped?) -> Bool Required

Returns a Boolean value indicating whether the right-hand-side argument is not nil.

You can use this not-equal-to operator (!=) to test whether an optional instance is not nil even when the wrapped value's type does not conform to the Equatable protocol.

The following example declares the stream variable as an optional instance of a hypothetical DataStream type. Although DataStream is not an Equatable type, this operator allows checking whether stream wraps a value and is therefore not nil.

var stream: DataStream? = fetchDataStream()
if nil != stream {
    print("The data stream has been configured.")
}
// Prints "The data stream has been configured."

Declaration

public static func !=(lhs: _OptionalNilComparisonType, rhs: Wrapped?) -> Bool
func ==(lhs: Wrapped?, rhs: _OptionalNilComparisonType) -> Bool Required

Returns a Boolean value indicating whether the left-hand-side argument is nil.

You can use this equal-to operator (==) to test whether an optional instance is nil even when the wrapped value's type does not conform to the Equatable protocol.

The following example declares the stream variable as an optional instance of a hypothetical DataStream type. Although DataStream is not an Equatable type, this operator allows checking whether stream is nil.

var stream: DataStream? = nil
if stream == nil {
    print("No data stream is configured.")
}
// Prints "No data stream is configured."

Declaration

public static func ==(lhs: Wrapped?, rhs: _OptionalNilComparisonType) -> Bool
func ==(lhs: _OptionalNilComparisonType, rhs: Wrapped?) -> Bool Required

Returns a Boolean value indicating whether the right-hand-side argument is nil.

You can use this equal-to operator (==) to test whether an optional instance is nil even when the wrapped value's type does not conform to the Equatable protocol.

The following example declares the stream variable as an optional instance of a hypothetical DataStream type. Although DataStream is not an Equatable type, this operator allows checking whether stream is nil.

var stream: DataStream? = nil
if nil == stream {
    print("No data stream is configured.")
}
// Prints "No data stream is configured."

Declaration

public static func ==(lhs: _OptionalNilComparisonType, rhs: Wrapped?) -> Bool
func ~=(lhs: _OptionalNilComparisonType, rhs: Wrapped?) -> Bool Required

Returns a Boolean value indicating whether an argument matches nil.

You can use the pattern-matching operator (~=) to test whether an optional instance is nil even when the wrapped value's type does not conform to the Equatable protocol. The pattern-matching operator is used internally in case statements for pattern matching.

The following example declares the stream variable as an optional instance of a hypothetical DataStream type, and then uses a switch statement to determine whether the stream is nil or has a configured value. When evaluating the nil case of the switch statement, this operator is called behind the scenes.

var stream: DataStream? = nil
switch stream {
case nil:
    print("No data stream is configured.")
case let x?:
    print("The data stream has \(x.availableBytes) bytes available.")
}
// Prints "No data stream is configured."

Note: To test whether an instance is nil in an if statement, use the equal-to operator (==) instead of the pattern-matching operator. The pattern-matching operator is primarily intended to enable case statement pattern matching.

Declaration

public static func ~=(lhs: _OptionalNilComparisonType, rhs: Wrapped?) -> Bool