What's New / App Services, Foundation & Diagnostics

What's new in Swift

+44 NewiOS · macOS · tvOS · watchOS · visionOS

The standard library's collection and sequence machinery: the protocols and adapter types that define how values are iterated and how spans of contiguous memory are walked.

The 27 SDK adds 44 APIs, with no deprecations or removals. New iteration primitives arrive as the BorrowingIteratorProtocol and BorrowingSequence protocols and the BorrowingIteratorAdapter and SpanIterator structs. Existing collection types gain borrowing-iteration conformances and members, including Collection, CollectionOfOne, EmptyCollection, Dictionary.Keys, MutableRawSpan, and InlineArray's BorrowingIterator with makeBorrowingIterator.

New

44
struct

BorrowingIteratorAdapter

NewiOSmacOStvOSvisionOSwatchOS
public struct BorrowingIteratorAdapter<Iterator> : BorrowingIteratorProtocol where Iterator : IteratorProtocol
Declaration
@frozen public struct BorrowingIteratorAdapter<Iterator> : BorrowingIteratorProtocol where Iterator : IteratorProtocol {

    public typealias Element = Iterator.Element

    public init(iterator: Iterator)

    /// Returns a span over the next group of elements that are ready to by visited,
    /// up to the specifed maximum.
    ///
    /// If the underlying type stores its elements in one or more blocks of
    /// contiguous memory, then the returned span typically directly
    /// addresses one of those buffers. On the other hand, if the underlying type
    /// materializes its elements on demand, then the returned span addresses
    /// a temporary buffer managed by the iterator itself. Consequently, the returned
    /// span is tied to this particular invocation of `nextSpan`, and it cannot
    /// survive beyond the next invocation of this method.
    ///
    /// If the iterator has not yet reached the end of the underlying elements,
    /// then this method returns a non-empty span of at most `maximumCount`
    /// elements and updates the iterator's current position to the element
    /// following the last item in the returned span. The `maximumCount`
    /// argument allows callers to avoid getting more items than they are
    /// able to process in one go, simplifying usage, and
    /// avoiding materializing more elements than needed.
    ///
    /// If the iterator's current position is at the end of the container, then
    /// this method returns an empty span without updating the position.
    ///
    /// This method can be used to efficiently process the items of a container
    /// in bulk, by directly iterating over its piecewise contiguous pieces of
    /// storage:
    ///
    ///     var it = items.makeBorrowingIterator()
    ///     while true {
    ///       let span = it.nextSpan(maximumCount: .max)
    ///       if span.isEmpty { break }
    ///       // Process items in `span`
    ///     }
    ///
    /// The spans returned by this method are not guaranteed to be disjunct.
    /// Iterators that materialize elements on demand typically reuse the same
    /// buffer over and over again; and even some proper containers may link to a
    /// single storage chunk (or parts of a storage chunk) multiple times, for
    /// example to repeat their contents.
    public mutating func nextSpan(maximumCount: Int) -> Span<Iterator.Element>
}
protocol

BorrowingIteratorProtocol

NewiOSmacOStvOSvisionOSwatchOS
public protocol BorrowingIteratorProtocol<Element> : ~Copyable, ~Escapable

A type that provides borrowed access to the values of a borrowing sequence.

Declaration
public protocol BorrowingIteratorProtocol<Element> : ~Copyable, ~Escapable {

    associatedtype Element : ~Copyable

    /// Returns a span over the next group of elements that are ready to by visited,
    /// up to the specifed maximum.
    ///
    /// If the underlying type stores its elements in one or more blocks of
    /// contiguous memory, then the returned span typically directly
    /// addresses one of those buffers. On the other hand, if the underlying type
    /// materializes its elements on demand, then the returned span addresses
    /// a temporary buffer managed by the iterator itself. Consequently, the returned
    /// span is tied to this particular invocation of `nextSpan`, and it cannot
    /// survive beyond the next invocation of this method.
    ///
    /// If the iterator has not yet reached the end of the underlying elements,
    /// then this method returns a non-empty span of at most `maximumCount`
    /// elements and updates the iterator's current position to the element
    /// following the last item in the returned span. The `maximumCount`
    /// argument allows callers to avoid getting more items than they are
    /// able to process in one go, simplifying usage, and
    /// avoiding materializing more elements than needed.
    ///
    /// If the iterator's current position is at the end of the container, then
    /// this method returns an empty span without updating the position.
    ///
    /// This method can be used to efficiently process the items of a container
    /// in bulk, by directly iterating over its piecewise contiguous pieces of
    /// storage:
    ///
    ///     var it = items.makeBorrowingIterator()
    ///     while true {
    ///       let span = it.nextSpan(maximumCount: .max)
    ///       if span.isEmpty { break }
    ///       // Process items in `span`
    ///     }
    ///
    /// The spans returned by this method are not guaranteed to be disjunct.
    /// Iterators that materialize elements on demand typically reuse the same
    /// buffer over and over again; and even some proper containers may link to a
    /// single storage chunk (or parts of a storage chunk) multiple times, for
    /// example to repeat their contents.
    mutating func nextSpan(maximumCount: Int) -> Span<Self.Element>

    /// Advances the position of this iterator by the specified offset, or until
    /// the end of the underlying type's elements.
    ///
    /// - Parameter maximumOffset: The maximum number of elements
    ///   to offset the position of this iterator. `maximumOffset` must be
    ///   nonnegative.
    /// - Returns: The number of items that were skipped. If the returned count
    ///   is less than `maximumOffset`, then the underlying type did not have
    ///   enough elements left to skip the requested number of items.
    ///   In that case, the iterator's position is set to the end of the underlying type.
    mutating func skip(by maximumOffset: Int) -> Int
}
extension

BorrowingIteratorProtocol

NewiOSmacOStvOSvisionOSwatchOS
extension BorrowingIteratorProtocol where Self : ~Copyable, Self : ~Escapable, Self.Element : ~Copyable
Declaration
extension BorrowingIteratorProtocol where Self : ~Copyable, Self : ~Escapable, Self.Element : ~Copyable {

    /// Returns a span over the next group of elements that are ready to by visited,
    /// up to the specifed maximum.
    public mutating func nextSpan() -> Span<Self.Element>

    /// Advances the position of this iterator by the specified offset, or until
    /// the end of the underlying type's elements.
    ///
    /// - Parameter maximumOffset: The maximum number of elements
    ///   to offset the position of this iterator. `maximumOffset` must be
    ///   nonnegative.
    /// - Returns: The number of items that were skipped. If the returned count
    ///   is less than `maximumOffset`, then the underlying type did not have
    ///   enough elements left to skip the requested number of items.
    ///   In that case, the iterator's position is set to the end of the underlying type.
    public mutating func skip(by offset: Int) -> Int
}
protocol

BorrowingSequence

NewiOSmacOStvOSvisionOSwatchOS
public protocol BorrowingSequence<Element> : ~Copyable, ~Escapable

A type that provides sequential, borrowing access to its elements.

Declaration
public protocol BorrowingSequence<Element> : ~Copyable, ~Escapable {

    /// A type representing the sequence's elements.
    associatedtype Element : ~Copyable where Self.Element == Self.BorrowingIterator.Element

    /// A type that provides the sequence's iteration interface and
    /// encapsulates its iteration state.
    associatedtype BorrowingIterator : BorrowingIteratorProtocol, ~Copyable, ~Escapable

    /// Returns a borrowing iterator over the elements of this sequence.
    func makeBorrowingIterator() -> Self.BorrowingIterator

    /// A value less than or equal to the number of elements in the sequence,
    /// calculated nondestructively.
    var underestimatedCount: Int { get }
}
extension

BorrowingSequence

NewiOSmacOStvOSvisionOSwatchOS
extension BorrowingSequence where Self : ~Copyable, Self : ~Escapable, Self.Element : ~Copyable
Declaration
extension BorrowingSequence where Self : ~Copyable, Self : ~Escapable, Self.Element : ~Copyable {

    /// A value less than or equal to the number of elements in the sequence,
    /// calculated nondestructively.
    @inlinable public var underestimatedCount: Int { get }
}
extension

Collection

NewiOSmacOStvOSvisionOSwatchOS
extension Collection where Self : BorrowingSequence
Declaration
extension Collection where Self : BorrowingSequence {

    @available(anyAppleOS 27.0, *)
    @inlinable public var underestimatedCount: Int { get }
}
extension

CollectionOfOne

NewiOSmacOStvOSvisionOSwatchOS
extension CollectionOfOne : Equatable where Element : Equatable
Declaration
extension CollectionOfOne : Equatable where Element : Equatable {
}
extension

CollectionOfOne

NewiOSmacOStvOSvisionOSwatchOS
extension CollectionOfOne : Hashable where Element : Hashable
Declaration
extension CollectionOfOne : Hashable where Element : Hashable {
}
extension

Dictionary.Keys

NewiOSmacOStvOSvisionOSwatchOS
extension Dictionary.Keys : Hashable
Declaration
extension Dictionary.Keys : Hashable {
}
extension

EmptyCollection

NewiOSmacOStvOSvisionOSwatchOS
extension EmptyCollection : Hashable
Declaration
extension EmptyCollection : Hashable {
}
extension

MutableRawSpan

NewiOSmacOStvOSvisionOSwatchOS
extension MutableRawSpan : BorrowingSequence
Declaration
extension MutableRawSpan : BorrowingSequence {

    /// Returns a borrowing iterator over the elements of this sequence.
    @available(anyAppleOS 27.0, *)
    @inlinable public func makeBorrowingIterator() -> SpanIterator<UInt8>

    /// A type that provides the sequence's iteration interface and
    /// encapsulates its iteration state.
    @available(anyAppleOS 27.0, *)
    public typealias BorrowingIterator = SpanIterator<UInt8>

    /// A type representing the sequence's elements.
    @available(anyAppleOS 27.0, *)
    public typealias Element = UInt8
}
extension

MutableSpan

NewiOSmacOStvOSvisionOSwatchOS
extension MutableSpan : BorrowingSequence where Element : ~Copyable
Declaration
extension MutableSpan : BorrowingSequence where Element : ~Copyable {

    /// Returns a borrowing iterator over the elements of this sequence.
    @available(anyAppleOS 27.0, *)
    @inlinable public func makeBorrowingIterator() -> SpanIterator<Element>

    /// A type that provides the sequence's iteration interface and
    /// encapsulates its iteration state.
    @available(anyAppleOS 27.0, *)
    public typealias BorrowingIterator = SpanIterator<Element>
}
extension

RawSpan

NewiOSmacOStvOSvisionOSwatchOS
extension RawSpan : BorrowingSequence
Declaration
extension RawSpan : BorrowingSequence {

    /// Returns a borrowing iterator over the elements of this sequence.
    @available(anyAppleOS 27.0, *)
    @inlinable public func makeBorrowingIterator() -> SpanIterator<UInt8>

    /// A type that provides the sequence's iteration interface and
    /// encapsulates its iteration state.
    @available(anyAppleOS 27.0, *)
    public typealias BorrowingIterator = SpanIterator<UInt8>

    /// A type representing the sequence's elements.
    @available(anyAppleOS 27.0, *)
    public typealias Element = UInt8
}
extension

Sequence

NewiOSmacOStvOSvisionOSwatchOS
extension Sequence where Self : BorrowingSequence
Declaration
extension Sequence where Self : BorrowingSequence {

    @available(anyAppleOS 27.0, *)
    public func makeBorrowingIterator() -> BorrowingIteratorAdapter<Self.Iterator>
}
extension

Span

NewiOSmacOStvOSvisionOSwatchOS
extension Span : BorrowingSequence where Element : ~Copyable
Declaration
extension Span : BorrowingSequence where Element : ~Copyable {

    /// Returns a borrowing iterator over the elements of this sequence.
    @available(anyAppleOS 27.0, *)
    @inlinable public func makeBorrowingIterator() -> SpanIterator<Element>

    /// A type that provides the sequence's iteration interface and
    /// encapsulates its iteration state.
    @available(anyAppleOS 27.0, *)
    public typealias BorrowingIterator = SpanIterator<Element>
}
struct

SpanIterator

NewiOSmacOStvOSvisionOSwatchOS
public struct SpanIterator<Element> : BorrowingIteratorProtocol, ~Copyable, ~Escapable where Element : ~Copyable
Declaration
public struct SpanIterator<Element> : BorrowingIteratorProtocol, ~Copyable, ~Escapable where Element : ~Copyable {

    public init(_ elements: Span<Element>)

    /// Returns a span over the next group of elements that are ready to by visited,
    /// up to the specifed maximum.
    ///
    /// If the underlying type stores its elements in one or more blocks of
    /// contiguous memory, then the returned span typically directly
    /// addresses one of those buffers. On the other hand, if the underlying type
    /// materializes its elements on demand, then the returned span addresses
    /// a temporary buffer managed by the iterator itself. Consequently, the returned
    /// span is tied to this particular invocation of `nextSpan`, and it cannot
    /// survive beyond the next invocation of this method.
    ///
    /// If the iterator has not yet reached the end of the underlying elements,
    /// then this method returns a non-empty span of at most `maximumCount`
    /// elements and updates the iterator's current position to the element
    /// following the last item in the returned span. The `maximumCount`
    /// argument allows callers to avoid getting more items than they are
    /// able to process in one go, simplifying usage, and
    /// avoiding materializing more elements than needed.
    ///
    /// If the iterator's current position is at the end of the container, then
    /// this method returns an empty span without updating the position.
    ///
    /// This method can be used to efficiently process the items of a container
    /// in bulk, by directly iterating over its piecewise contiguous pieces of
    /// storage:
    ///
    ///     var it = items.makeBorrowingIterator()
    ///     while true {
    ///       let span = it.nextSpan(maximumCount: .max)
    ///       if span.isEmpty { break }
    ///       // Process items in `span`
    ///     }
    ///
    /// The spans returned by this method are not guaranteed to be disjunct.
    /// Iterators that materialize elements on demand typically reuse the same
    /// buffer over and over again; and even some proper containers may link to a
    /// single storage chunk (or parts of a storage chunk) multiple times, for
    /// example to repeat their contents.
    public mutating func nextSpan(maximumCount: Int) -> Span<Element>

    /// Advances the position of this iterator by the specified offset, or until
    /// the end of the underlying type's elements.
    ///
    /// - Parameter maximumOffset: The maximum number of elements
    ///   to offset the position of this iterator. `maximumOffset` must be
    ///   nonnegative.
    /// - Returns: The number of items that were skipped. If the returned count
    ///   is less than `maximumOffset`, then the underlying type did not have
    ///   enough elements left to skip the requested number of items.
    ///   In that case, the iterator's position is set to the end of the underlying type.
    public mutating func skip(by offset: Int) -> Int
}
extension

UnownedTaskExecutor

NewiOSmacOStvOSvisionOSwatchOS
extension UnownedTaskExecutor : Hashable
Declaration
extension UnownedTaskExecutor : Hashable {

    /// The hash value.
    ///
    /// Hash values are not guaranteed to be equal across different executions of
    /// your program. Do not save hash values to use during a future execution.
    ///
    /// - Important: `hashValue` is deprecated as a `Hashable` requirement. To
    ///   conform to `Hashable`, implement the `hash(into:)` requirement instead.
    ///   The compiler provides an implementation for `hashValue` for you.
    public var hashValue: Int { get }
}
func

withTaskCancellationShield

NewiOSmacOStvOSvisionOSwatchOS
public func withTaskCancellationShield<Value, Failure>(operation: () throws(Failure) -> Value) throws(Failure) -> Value where Failure : Error

Enters a scope in which a task cancellation shield is active.

Cancellation shields are primarily used to ensure some cleanup code will definitely run, even if the context in which the cleanup functions are called from is a cancelled task, and the functions may otherwise return early (due to observing the cancellation of the current task).

For example, a resource cleanup function might internally check for cancellation, which could cause it to skip important cleanup work:

let resource = await makeResource()
defer {
  await withTaskCancellationShield {
    await resource.finish() // runs to completion, even if task was cancelled earlier
  }
}

struct Resource {
  func finish() {
    guard !Task.isCancelled() else { return } // returns early if task was cancelled!
    // real work happens here
  }

While inside a cancellation shield, Task.isCancelled returns false and Task.checkCancellation() does not throw, even if the surrounding task has been cancelled. Similarly task cancellation handlers do not trigger while executing in a shielded block of code.

Once the shield scope exits, the task's actual cancellation status becomes observable again. Cancellation shields to not prevent the task from becoming cancelled, but only prevent observing the cancellation while executing inside a shielded scope.

Cancellation shields also prevent cancellation from propagating to child tasks created within the shielded scope:

let task = Task {
  withUnsafeCurrentTask { $0?.cancel() } // cancel the task

  await withTaskCancellationShield {
    // Child tasks created here do NOT observe the parent's cancellation
    // and therefore start as not cancelled. They can be individually cancelled though.
    await withTaskGroup(of: Void.self) { group in
      group.addTask {
        print(Task.isCancelled) // false
      }
      for await _ in group {}

      group.cancelAll() // explicitly cancelling the group does cancel child tasks of the group
      group.addTask {
        print(Task.isCancelled) // true
      }
    }
  }
}

Note that shielding the addTask call itself does not shield the child task:

await withTaskGroup(of: Void.self) { group in
  group.cancelAll()
  withTaskCancellationShield {
    group.addTask { print(Task.isCancelled) } // true - child IS cancelled
  }
  group.addTask {
    withTaskCancellationShield { print(Task.isCancelled) } // false - shielded inside child
  }
}
func

withTaskCancellationShield

NewiOSmacOStvOSvisionOSwatchOS
nonisolated(nonsending) public func withTaskCancellationShield<Value, Failure>(operation: nonisolated(nonsending) () async throws(Failure) -> Value) async throws(Failure) -> Value where Failure : Error

Enters a scope in which a task cancellation shield is active.

Cancellation shields are primarily used to ensure some cleanup code will definitely run, even if the context in which the cleanup functions are called from is a cancelled task, and the functions may otherwise return early (due to observing the cancellation of the current task).

For example, a resource cleanup function might internally check for cancellation, which could cause it to skip important cleanup work:

let resource = await makeResource()
defer {
  await withTaskCancellationShield {
    await resource.finish() // runs to completion, even if task was cancelled earlier
  }
}

struct Resource {
  func finish() {
    guard !Task.isCancelled() else { return } // returns early if task was cancelled!
    // real work happens here
  }

While inside a cancellation shield, Task.isCancelled returns false and Task.checkCancellation() does not throw, even if the surrounding task has been cancelled. Similarly task cancellation handlers do not trigger while executing in a shielded block of code.

Once the shield scope exits, the task's actual cancellation status becomes observable again. Cancellation shields to not prevent the task from becoming cancelled, but only prevent observing the cancellation while executing inside a shielded scope.

Cancellation shields also prevent cancellation from propagating to child tasks created within the shielded scope:

let task = Task {
  withUnsafeCurrentTask { $0?.cancel() } // cancel the task

  await withTaskCancellationShield {
    // Child tasks created here do NOT observe the parent's cancellation
    // and therefore start as not cancelled. They can be individually cancelled though.
    await withTaskGroup(of: Void.self) { group in
      group.addTask {
        print(Task.isCancelled) // false
      }
      for await _ in group {}

      group.cancelAll() // explicitly cancelling the group does cancel child tasks of the group
      group.addTask {
        print(Task.isCancelled) // true
      }
    }
  }
}

Note that shielding the addTask call itself does not shield the child task:

await withTaskGroup(of: Void.self) { group in
  group.cancelAll()
  withTaskCancellationShield {
    group.addTask { print(Task.isCancelled) } // true - child IS cancelled
  }
  group.addTask {
    withTaskCancellationShield { print(Task.isCancelled) } // false - shielded inside child
  }
}
typealias

InlineArray.BorrowingIterator

NewiOSmacOStvOSvisionOSwatchOS
public typealias BorrowingIterator = SpanIterator<Element>

A type that provides the sequence's iteration interface and encapsulates its iteration state.

func

InlineArray.makeBorrowingIterator

NewiOSmacOStvOSvisionOSwatchOS
public func makeBorrowingIterator() -> SpanIterator<Element>

Returns a borrowing iterator over the elements of this sequence.

typealias

MutableRawSpan.BorrowingIterator

NewiOSmacOStvOSvisionOSwatchOS
public typealias BorrowingIterator = SpanIterator<UInt8>

A type that provides the sequence's iteration interface and encapsulates its iteration state.

typealias

MutableRawSpan.Element

NewiOSmacOStvOSvisionOSwatchOS
public typealias Element = UInt8

A type representing the sequence's elements.

func

MutableRawSpan.makeBorrowingIterator

NewiOSmacOStvOSvisionOSwatchOS
public func makeBorrowingIterator() -> SpanIterator<UInt8>

Returns a borrowing iterator over the elements of this sequence.

typealias

MutableSpan.BorrowingIterator

NewiOSmacOStvOSvisionOSwatchOS
public typealias BorrowingIterator = SpanIterator<Element>

A type that provides the sequence's iteration interface and encapsulates its iteration state.

func

MutableSpan.makeBorrowingIterator

NewiOSmacOStvOSvisionOSwatchOS
public func makeBorrowingIterator() -> SpanIterator<Element>

Returns a borrowing iterator over the elements of this sequence.

typealias

RawSpan.BorrowingIterator

NewiOSmacOStvOSvisionOSwatchOS
public typealias BorrowingIterator = SpanIterator<UInt8>

A type that provides the sequence's iteration interface and encapsulates its iteration state.

typealias

RawSpan.Element

NewiOSmacOStvOSvisionOSwatchOS
public typealias Element = UInt8

A type representing the sequence's elements.

func

RawSpan.makeBorrowingIterator

NewiOSmacOStvOSvisionOSwatchOS
public func makeBorrowingIterator() -> SpanIterator<UInt8>

Returns a borrowing iterator over the elements of this sequence.

func

Sequence.makeBorrowingIterator

NewiOSmacOStvOSvisionOSwatchOS
public func makeBorrowingIterator() -> BorrowingIteratorAdapter<Self.Iterator>
typealias

Span.BorrowingIterator

NewiOSmacOStvOSvisionOSwatchOS
public typealias BorrowingIterator = SpanIterator<Element>

A type that provides the sequence's iteration interface and encapsulates its iteration state.

func

Span.makeBorrowingIterator

NewiOSmacOStvOSvisionOSwatchOS
public func makeBorrowingIterator() -> SpanIterator<Element>

Returns a borrowing iterator over the elements of this sequence.

func

String.isTriviallyIdentical

NewiOSmacOStvOSvisionOSwatchOS
public func isTriviallyIdentical(to other: String) -> Bool

Returns a boolean value indicating whether this string is identical to other.

Two string values are identical if there is no way to distinguish between them.

For any values a, b, and c:

  • a.isTriviallyIdentical(to: a) is always true. (Reflexivity)
  • a.isTriviallyIdentical(to: b) implies b.isTriviallyIdentical(to: a).

(Symmetry)

  • If a.isTriviallyIdentical(to: b) and b.isTriviallyIdentical(to: c)

are both true, then a.isTriviallyIdentical(to: c) is also true. (Transitivity)

  • a.isTriviallyIdentical(b) implies a == b. a == b does not imply a.isTriviallyIdentical(b)

Values produced by copying the same value, with no intervening mutations, will compare identical:

let d = c
print(c.isTriviallyIdentical(to: d))
// Prints true

Comparing strings this way includes comparing (normally) hidden implementation details such as the memory location of any underlying string storage object. Therefore, identical strings are guaranteed to compare equal with ==, but not all equal strings are considered identical.

Complexity: O(1)

func

String.UnicodeScalarView.isTriviallyIdentical

NewiOSmacOStvOSvisionOSwatchOS
public func isTriviallyIdentical(to other: String.UnicodeScalarView) -> Bool

Returns a boolean value indicating whether this unicode scalar view is trivially identical to other.

Complexity: O(1)

func

String.UTF16View.isTriviallyIdentical

NewiOSmacOStvOSvisionOSwatchOS
public func isTriviallyIdentical(to other: String.UTF16View) -> Bool

Returns a boolean value indicating whether this UTF16 view is trivially identical to other.

Complexity: O(1)

func

String.UTF8View.isTriviallyIdentical

NewiOSmacOStvOSvisionOSwatchOS
public func isTriviallyIdentical(to other: String.UTF8View) -> Bool

Returns a boolean value indicating whether this UTF8 view is trivially identical to other.

Complexity: O(1)

func

Substring.isTriviallyIdentical

NewiOSmacOStvOSvisionOSwatchOS
public func isTriviallyIdentical(to other: Substring) -> Bool

Returns a boolean value indicating whether this substring is identical to other.

Two substring values are identical if there is no way to distinguish between them.

For any values a, b, and c:

  • a.isTriviallyIdentical(to: a) is always true. (Reflexivity)
  • a.isTriviallyIdentical(to: b) implies b.isTriviallyIdentical(to: a).

(Symmetry)

  • If a.isTriviallyIdentical(to: b) and b.isTriviallyIdentical(to: c)

are both true, then a.isTriviallyIdentical(to: c) is also true. (Transitivity)

  • a.isTriviallyIdentical(b) implies a == b. a == b does not imply a.isTriviallyIdentical(b)

Values produced by copying the same value, with no intervening mutations, will compare identical:

let d = c
print(c.isTriviallyIdentical(to: d))
// Prints true

Comparing substrings this way includes comparing (normally) hidden implementation details such as the memory location of any underlying substring storage object. Therefore, identical substrings are guaranteed to compare equal with ==, but not all equal substrings are considered identical.

Complexity: O(1)

func

Substring.UnicodeScalarView.isTriviallyIdentical

NewiOSmacOStvOSvisionOSwatchOS
public func isTriviallyIdentical(to other: Substring.UnicodeScalarView) -> Bool

Returns a boolean value indicating whether this unicode scalar view is trivially identical to other.

Complexity: O(1)

func

Substring.UTF16View.isTriviallyIdentical

NewiOSmacOStvOSvisionOSwatchOS
public func isTriviallyIdentical(to other: Substring.UTF16View) -> Bool

Returns a boolean value indicating whether this UTF16 view is trivially identical to other.

Complexity: O(1)

func

Substring.UTF8View.isTriviallyIdentical

NewiOSmacOStvOSvisionOSwatchOS
public func isTriviallyIdentical(to other: Substring.UTF8View) -> Bool

Returns a boolean value indicating whether this UTF8 view is trivially identical to other.

Complexity: O(1)

var

Task.hasActiveCancellationShield

NewiOSmacOStvOSvisionOSwatchOS
public static var hasActiveCancellationShield: Bool { get }

Checks if the current task is executing in a scope with a task cancellation shield activated by the withTaskCancellationShield(operation:) function.

An active task cancellation shield prevents a task's ability to observe if it was cancelled, i.e. the isCancelled property will always return false when the task is executing with an active shield.

This property is primarily aimed at debugging and understanding cancellation behavior in complex call hierarchies, and should not be used in regular control flow.

Returns true when executing within a task that has an active cancellation shield.

Cancellation shields are not automatically inherited by child tasks; each child task must install its own shield if needed if it, independently, wanted to ignore cancellation during a specific scope.

  • SeeAlso: withTaskCancellationShield(operation:)
  • SeeAlso: hasActiveCancellationShield
var

Task.name

NewiOSmacOStvOSvisionOSwatchOS
public var name: String? { get }

Return the task's name, if it was set during its creation.

var

UnsafeCurrentTask.hasActiveCancellationShield

NewiOSmacOStvOSvisionOSwatchOS
public var hasActiveCancellationShield: Bool { get }

Checks if this task is executing in a scope with a task cancellation shield activated by the withTaskCancellationShield(operation:) function.

An active task cancellation shield prevents a task's ability to observe if it was cancelled, i.e. the isCancelled property will always return false when the task is executing with an active shield.

This property is primarily aimed at debugging and understanding cancellation behavior in complex call hierarchies, and should not be used in regular control flow.

Returns true when executing within a task that has an active cancellation shield.

Cancellation shields are not automatically inherited by child tasks; each child task must install its own shield if needed if it, independently, wanted to ignore cancellation during a specific scope.

  • SeeAlso: withTaskCancellationShield(operation:)
  • SeeAlso: hasActiveCancellationShield
var

UnsafeCurrentTask.name

NewiOSmacOStvOSvisionOSwatchOS
public var name: String? { get }

Return the task's name, if it was set during its creation.

No APIs match your filter.

← More in App Services, Foundation & Diagnostics