Difference between Some and Any with Protocols in Swift

Difference between Some and Any with Protocols in Swift

In Swift, the terms some and any are often used in conjunction with protocols. While they may seem similar at first glance, they have distinct differences that are important to understand when working with protocols.

Let's start with a brief definition of protocols in Swift. A protocol is a set of rules that a type must conform to be considered an instance of that protocol. In other words, a protocol defines a blueprint for a type to follow.

Now, let's look at the differences between some and any when working with protocols in Swift.

Some:

Introduced in Swift 5.1. The some keyword is used to indicate that a protocol must be satisfied by at least one concrete type. In other words, the type that conforms to the protocol is known but may vary from one instance to another.

Here's an example:

protocol Animal {
    func makeSound()
}

struct Dog: Animal {
    func makeSound() {
        print("Woof!")
    }
}

struct Cat: Animal {
    func makeSound() {
        print("Meow!")
    }
}

func makeAnimalSound(animal: some Animal) {
    animal.makeSound()
}

let myDog = Dog()
let myCat = Cat()

makeAnimalSound(animal: myDog) // Output: "Woof!"
makeAnimalSound(animal: myCat) // Output: "Meow!"

In this example, the makeAnimalSound function takes a parameter of type some Animal. This means that the parameter can be any type that conforms to the Animal protocol. The type is known, but it can vary from one instance to another.

Any:

Introduced in Swift 5.6. The any keyword is used to indicate that a protocol can be satisfied by any type, even those that are not known at compile time. In other words, the type that conforms to the protocol is not known until runtime.

Here's an example:

protocol Vehicle {
    func drive()
}

class Car: Vehicle {
    func drive() {
        print("Driving a car.")
    }
}

class Motorcycle: Vehicle {
    func drive() {
        print("Driving a motorcycle.")
    }
}

func driveVehicle(vehicle: any Vehicle) {
    vehicle.drive()
}

let myCar = Car()
let myMotorcycle = Motorcycle()

driveVehicle(vehicle: myCar) // Output: "Driving a car."
driveVehicle(vehicle: myMotorcycle) // Output: "Driving a motorcycle."

In this example, the driveVehicle function takes a parameter of type any Vehicle. This means that the parameter can be any type that conforms to the Vehicle protocol, even if the type is not known until runtime.

Conclusion:

In summary, the some keyword is used to indicate that a protocol must be satisfied by at least one concrete type, while any keyword is used to indicate that a protocol can be satisfied by any type, even those that are not known at compile time. Generally, you should use some over any whenever you can.

Understanding the differences between these keywords is important when working with protocols in Swift, as it can help you write more efficient and effective code.

For more information check out the WWDC sessions What’s new in Swift and Embrace Swift generics or these excellent articles from Donny Wals and SwiftBySundell.

I hope that you found this article useful. If you have any questions, comments, or feedback, then feel free to reach out via either Twitter or email.