I'm calling a method expecting a String...
variadic parameter, but the only thing it allows receiving from the enclosing function is a plain String
.
My method looks like this:
public func deleteKeys(keysReceived:String..., completionHandler:@escaping () -> Void)
{
RedisClient.getClient(withIdentifier: RedisClientIdentifier()) {
c in
do {
let client = try c()
client.delete(keys: keysReceived){}
completionHandler()
}
//...
}
}
The compile error is
Cannot convert value of type '[String]' to expected argument type 'String'
This method (client.delete()
) is from a Redis API for Perfect-Swift so I cannot change the signature, but I can change the enclosing function (deleteKeys). I also cannot call the function directly because it is within a callback closure
Any suggestions on how I can pass a received variadic parameter to an enclosed variadic function? I can break the array down to Single strings and delete individually but that doesn't seem very efficient
A variadic parameter means it is a type followed by three dots, such as String...
They are used to pass in a variable amount of values of the same type. You can't pass a method's variadic parameter to another method. Inside the method it becomes an Array
which can't be passed as a variadic without lots of trickery that you really don't want to bother with in this instance.
However, we can see from the source:
public extension RedisClient {
/// Get the key value.
func delete(keys: String..., callback: @escaping redisResponseCallback) {
self.sendCommand(name: "DEL \(keys.joined(separator: " "))", callback: callback)
}
}
That all they are doing is joining up the Array
with a space as a separator. So you can add this to your own code at a top level:
public extension RedisClient {
/// Get the key value.
func delete(keys: [String], callback: @escaping redisResponseCallback) {
self.delete(keys: keys.joined(separator: " "), callback: callback)
}
}
Then you can call it with:
client.delete(keys: keysReceived){}
Note that this only works in this particular case because, internally, the original method converts the strings in:
delete(keys: "one", "two", "three"){}
to:
["one", "two", "three"]
then to:
"one two three"
I'm doing this manually and passing it the last string like:
delete(keys: "one two three"){}
which becomes:
["one two three"]
and then is joined
to:
"one two three"
So the final result is the same when it calls self.sendCommand
.
This will most likely not work with other variadic methods since it relies on the method using the joined
method internally.