2

Say you have a protocol ToString that is implemented for Int, and a function that takes an array of ToStrings.

Trying to pass an array of Ints to this function results in the error Cannot convert value of type '[Int]' to expected argument type '[ToString]'.

However, using map on the array before passing it to the function works. Is this the supposed way to do the type cast or is there a way that doesn't result in iterating over the array? Or is this optimized out by the compiler?

Full example:

protocol ToString {
  func toString() -> String
}

extension Int: ToString {
  func toString() -> String {
    return "\(self)"
  }
}

func log( values: [ToString]) {
  values.forEach { print( $0.toString()) }
}

let values: [Int] = [1, 2, 3]

// Error: Cannot convert value of type '[Int]' to expected argument type '[ToString]'
log( values)

// No error
log( values.map { $0 })
1
  • 3
    The reason for the error "Cannot convert value of type '[Int]' to expected argument type '[ToString]'" is explained here: Type conversion when using protocol in Swift: Converting [Int] to [ToString] requires conversion of each element. – So this is partly a duplicate. But since you asked for alternative solutions (and one is given below) I decided to leave it open. Commented Aug 2, 2016 at 5:36

1 Answer 1

3

This Q&A explains the problem. I will suggest a fix that avoids creation of a new array: make your log function generic, and add a type constraint on its type parameter, requiring it to conform to ToString protocol:

func log<T:ToString>( values: [T]) {
    values.forEach { print( $0.toString()) }
}

Now Swift lets you call your function with arrays of any type, as long as array elements conform to ToString protocol.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the link to the Q&A and the answer. It solves the problem from my question nicely, although the actual problem I have is that I want to cast an array from a sub-protocol to an array of a super-protocol and the actual types may not all be the same. But I think I'll add that issue to the linked Q&A.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.