Home > database >  Is there a way to make the following code compile in Swift 5.7?
Is there a way to make the following code compile in Swift 5.7?

Time:07-04

Created a Vehicle Protocol then I created two structs for Car and Bus. Then I built 4 instances of Car. For cars instances 3 and 4 I use the some keyword and then created a carArrays. I called the function travel2 using the carArrays which accepts an array of some Vehicle, but I still get an error. It does work if I remove the some keyword

protocol Vehicle {
    func travel(to destination: String)
}
struct Car: Vehicle {
    func travel(to destination: String) {
        print("I'am driving to \(destination) by car")
    }
}

struct Bus: Vehicle {
    func travel(to destination: String) {
        print("I'am driving to \(destination) by bus")
    }
}

let car1 = Car()
let car2 = Car()
let bus1 = Bus()


func travel<T: Vehicle>(to destinations: [String], using vehicle: T) {
    for destination in destinations {
        vehicle.travel(to: destination)
    }
}
let car3: some Vehicle = Car()
let car4: some Vehicle = Car()
let bus2: some Vehicle = Bus()

var carArrays: [some Vehicle] = [car3, car4] // I get the following
// error on carArrays: Type of expression is ambiguous
// without more context

func travel2(to destinations: [String], using vehicles: [ some Vehicle]) {
    for destination in destinations {
        for vehicle in vehicles {
            vehicle.travel(to: destination)
        }
    }
}

travel2(to: ["New Jersey", "New York"], using: carArrays)

CodePudding user response:

You meant any, not some. some is for one type, not more than one.

The compiler doesn't know that a some Car is equivalent to another, so you need to type your variables with something that the compiler can understand. (We can't tell what you need, with what you've provided.)

Then, your functions can be:

func travel(to destinations: some Sequence<String>, using vehicle: some Vehicle) {
  destinations.forEach(vehicle.travel)
}

import Algorithms

func travel(
  to destinations: some Collection<String>,
  using vehicles: some Collection<any Vehicle>
) {
  for (destination, vehicle) in product(destinations, vehicles) {
    vehicle.travel(to: destination)
  }
}

Or, if it's actually important to constrain specifically to Arrays…

func travel(to destinations: [String], using vehicle: some Vehicle) {
func travel(to destinations: [String], using vehicles: [any Vehicle]) {
  • Related