Protocolswift 6.0.1Swift
Equatable
A type that can be compared for value equality.
protocol Equatable
Types that conform to the Equatable
protocol can be compared for equality using the equal-to operator (==
) or inequality using the not-equal-to operator (!=
). Most basic types in the Swift standard library conform to Equatable
.
Some sequence and collection operations can be used more simply when the elements conform to Equatable
. For example, to check whether an array contains a particular value, you can pass the value itself to the contains(_:)
method when the array’s element conforms to Equatable
instead of providing a closure that determines equivalence. The following example shows how the contains(_:)
method can be used with an array of strings.
let students = ["Kofi", "Abena", "Efua", "Kweku", "Akosua"]
let nameToCheck = "Kofi"
if students.contains(nameToCheck) {
print("\(nameToCheck) is signed up!")
} else {
print("No record of \(nameToCheck).")
}
// Prints "Kofi is signed up!"
Conforming to the Equatable Protocol
Adding Equatable
conformance to your custom types means that you can use more convenient APIs when searching for particular instances in a collection. Equatable
is also the base protocol for the Hashable
and Comparable
protocols, which allow more uses of your custom type, such as constructing sets or sorting the elements of a collection.
You can rely on automatic synthesis of the Equatable
protocol’s requirements for a custom type when you declare Equatable
conformance in the type’s original declaration and your type meets these criteria:
For a
struct
, all its stored properties must conform toEquatable
.For an
enum
, all its associated values must conform toEquatable
. (Anenum
without associated values hasEquatable
conformance even without the declaration.)
To customize your type’s Equatable
conformance, to adopt Equatable
in a type that doesn’t meet the criteria listed above, or to extend an existing type to conform to Equatable
, implement the equal-to operator (==
) as a static method of your type. The standard library provides an implementation for the not-equal-to operator (!=
) for any Equatable
type, which calls the custom ==
function and negates its result.
As an example, consider a StreetAddress
class that holds the parts of a street address: a house or building number, the street name, and an optional unit number. Here’s the initial declaration of the StreetAddress
type:
class StreetAddress {
let number: String
let street: String
let unit: String?
init(_ number: String, _ street: String, unit: String? = nil) {
self.number = number
self.street = street
self.unit = unit
}
}
Now suppose you have an array of addresses that you need to check for a particular address. To use the contains(_:)
method without including a closure in each call, extend the StreetAddress
type to conform to Equatable
.
extension StreetAddress: Equatable {
static func == (lhs: StreetAddress, rhs: StreetAddress) -> Bool {
return
lhs.number == rhs.number &&
lhs.street == rhs.street &&
lhs.unit == rhs.unit
}
}
The StreetAddress
type now conforms to Equatable
. You can use ==
to check for equality between any two instances or call the Equatable
-constrained contains(_:)
method.
let addresses = [StreetAddress("1490", "Grove Street"),
StreetAddress("2119", "Maple Avenue"),
StreetAddress("1400", "16th Street")]
let home = StreetAddress("1400", "16th Street")
print(addresses[0] == home)
// Prints "false"
print(addresses.contains(home))
// Prints "true"
Equality implies substitutability—any two instances that compare equally can be used interchangeably in any code that depends on their values. To maintain substitutability, the ==
operator should take into account all visible aspects of an Equatable
type. Exposing nonvalue aspects of Equatable
types other than class identity is discouraged, and any that are exposed should be explicitly pointed out in documentation.
Since equality between instances of Equatable
types is an equivalence relation, any of your custom types that conform to Equatable
must satisfy three conditions, for any values a
, b
, and c
:
a == a
is alwaystrue
(Reflexivity)a == b
impliesb == a
(Symmetry)a == b
andb == c
impliesa == c
(Transitivity)
Moreover, inequality is the inverse of equality, so any custom implementation of the !=
operator must guarantee that a != b
implies !(a == b)
. The default implementation of the !=
operator function satisfies this requirement.
Equality is Separate From Identity
The identity of a class instance is not part of an instance’s value. Consider a class called IntegerRef
that wraps an integer value. Here’s the definition for IntegerRef
and the ==
function that makes it conform to Equatable
:
class IntegerRef: Equatable {
let value: Int
init(_ value: Int) {
self.value = value
}
static func == (lhs: IntegerRef, rhs: IntegerRef) -> Bool {
return lhs.value == rhs.value
}
}
The implementation of the ==
function returns the same value whether its two arguments are the same instance or are two different instances with the same integer stored in their value
properties. For example:
let a = IntegerRef(100)
let b = IntegerRef(100)
print(a == a, a == b, separator: ", ")
// Prints "true, true"
Class instance identity, on the other hand, is compared using the triple-equals identical-to operator (===
). For example:
let c = a
print(c === a, c === b, separator: ", ")
// Prints "true, false"
Requirements
Type members
static func == (lhs: Self, rhs: Self
) -> Bool Returns a Boolean value indicating whether two values are equal.
Citizens in Swift
Type members
static func != (lhs: Self, rhs: Self
) -> Bool Returns a Boolean value indicating whether two values are not equal.
Subtypes
protocol AdditiveArithmetic
A type with values that support addition and subtraction.
protocol BinaryFloatingPoint
A radix-2 (binary) floating-point type.
protocol BinaryInteger
An integer type with a binary representation.
protocol Comparable
A type that can be compared using the relational operators
<
,<=
,>=
, and>
.protocol DurationProtocol
A type that defines a duration for a given
InstantProtocol
type.protocol FixedWidthInteger
An integer type that uses a fixed size for every instance.
protocol FloatingPoint
A floating-point numeric type.
protocol Hashable
A type that can be hashed into a
Hasher
to produce an integer hash value.protocol InstantProtocol<Duration>
protocol Numeric
A type with values that support multiplication.
protocol OptionSet
A type that presents a mathematical set interface to a bit set.
protocol SIMD<Scalar>
A SIMD vector of a fixed number of elements.
protocol SetAlgebra<Element>
A type that provides mathematical set operations.
protocol SignedInteger
An integer type that can represent both positive and negative values.
protocol SignedNumeric
A numeric type with a negation operation.
protocol Strideable<Stride>
A type representing continuous, one-dimensional values that can be offset and measured.
protocol StringProtocol
A type that can represent a string as a collection of characters.
protocol UnsignedInteger
An integer type that can represent only nonnegative values.
Available in Distributed
Subtypes
protocol DistributedActor
Common protocol to which all distributed actors conform implicitly.
Available in Cxx
Subtypes
protocol UnsafeCxxInputIterator
Bridged C++ iterator that allows to traverse the elements of a sequence using a for-in loop.
protocol UnsafeCxxMutableInputIterator
protocol UnsafeCxxMutableRandomAccessIterator
protocol UnsafeCxxRandomAccessIterator
Bridged C++ iterator that allows computing the distance between two of its instances, and advancing an instance by a given number of elements.
Available in FoundationEssentials
Subtypes
protocol AttributedStringProtocol
protocol DiscreteFormatStyle<FormatInput, FormatOutput>
A format style that transforms a continuous input into a discrete output and provides information about its discretization boundaries.
protocol FormatStyle
A type that can convert a given data type into a representation.
protocol ParseStrategy
A type that can parse a representation of a given data type.
protocol ParseableFormatStyle
A type that can convert a given data type into a representation.
protocol SortComparator<Compared>
A comparison algorithm for a given type.
Available in Foundation
Subtypes
protocol ReferenceConvertible
Decorates types which are backed by a Foundation reference type.
Extension in _RopeModule
Subtypes
protocol RopeSummary
A commutative group that is used to augment a tree, enabling quick lookup operations.
Extension in Crypto
Subtypes
protocol Digest
A type that represents the output of a hash.
protocol MessageAuthenticationCode
A type that represents a message authentication code.
Extension in NIOCore
Subtypes
protocol ChannelOption
A configuration option that can be set on a
Channel
to configure different behaviour.
Extension in RealModule
Subtypes
protocol AlgebraicField
A type modeling an algebraic field. Refines the
SignedNumeric
protocol, adding division.protocol ElementaryFunctions
A type that has elementary functions available.
protocol Real
A type that models the real numbers.
protocol RealFunctions
Extension in SwiftProtobuf
Subtypes
protocol Enum
Generated enum types conform to this protocol.
protocol ExtensionField
The regular ExtensionField type exposes the value directly.
Show implementation details (1)
Hide implementation details
protocol _MessageImplementationBase
Implementation base for all messages; not intended for client use.