2017-08-30 4 views
0

Ich rufe eine Methode an, die einen String... Variadic-Parameter erwartet, aber das einzige, was es von der umschließenden Funktion empfängt, ist eine einfache String.Swift 3: Methode, die variadic erwartet String-Parameter kann nur einzelnes String-Argument empfangen

Meine Methode sieht wie folgt aus:

public func deleteKeys(keysReceived:String..., completionHandler:@escaping() -> Void) 
{ 
     RedisClient.getClient(withIdentifier: RedisClientIdentifier()) { 
      c in 
      do { 
       let client = try c() 
       client.delete(keys: keysReceived){} 
       completionHandler() 
      } 
//... 
      } 
    } 

Der Compiler-Fehler ist

Cannot convert value of type '[String]' to expected argument type 'String' 

Diese Methode (client.delete()) ist von einem Redis API für Perfect-Swift, so kann ich die Signatur nicht ändern, aber Ich kann die umschließende Funktion ändern (deleteKeys). Ich kann die Funktion auch nicht direkt aufrufen, weil sie sich innerhalb eines Callback-Abschlusses befindet.

Irgendwelche Vorschläge, wie ich einen empfangenen Variadic-Parameter an eine eingeschlossene Variadic-Funktion übergeben kann? Ich kann das Array brechen zu Einzelsaiten und löschen einzeln, aber das scheint nicht sehr effizient

+0

Haben Sie das als 'obj.deleteKeys (keysReceived:" Hallo "," Welt "," Etwas ") {}'? Das sollte funktionieren. – nayem

+0

@nayem wird es nicht kompilieren und ich rufe es noch nicht – Tyress

+0

Kannst du die 'delete (keys:)' Methode Signatur zeigen? – nayem

Antwort

2

A variadische Parameter bedeutet, dass es eine Art von drei Punkten gefolgt ist, wie String... Sie werden verwendet, um eine variable Menge von Werten des gleichen Typs zu übergeben. Sie können den variadischen Parameter einer Methode nicht an eine andere Methode übergeben. Innerhalb der Methode wird es eine Array, die nicht als variadic ohne viele Tricks, die Sie wirklich in diesem Fall nicht belästigen wollen, übergeben werden kann.

können wir jedoch von der source sehen:

public extension RedisClient { 
    /// Get the key value. 
    func delete(keys: String..., callback: @escaping redisResponseCallback) { 
     self.sendCommand(name: "DEL \(keys.joined(separator: " "))", callback: callback) 
    } 
} 

Das alles, was sie tun, ist die Array mit einem Raum als Trenn Beitritt auf.So können Sie diese auf Ihrem eigenen Code auf höchstem Niveau hinzuzufügen:

public extension RedisClient { 
    /// Get the key value. 
    func delete(keys: [String], callback: @escaping redisResponseCallback) { 
     self.delete(keys: keys.joined(separator: " "), callback: callback) 
    } 
} 

Dann können Sie es mit rufen:

client.delete(keys: keysReceived){} 

Beachten Sie, dass dies nur funktioniert, in diesem speziellen Fall, weil intern das Original Verfahren wandelt die Zeichenketten in:

delete(keys: "one", "two", "three"){} 

zu:

["one", "two", "three"] 

dann zu:

"one two three" 

ich dies manuell zu tun und es die letzte Zeichenkette wie:

delete(keys: "one two three"){} 

, die wird:

["one two three"] 

und dann ist joined zu:

"one two three" 

So ist das Endergebnis das gleiche, wenn es self.sendCommand aufruft.

Dies wird höchstwahrscheinlich nicht mit anderen variadischen Methoden funktionieren, da es intern auf der Methode joined basiert.

+0

Danke, ich fürchte, dass ich die Quelle nicht bearbeiten kann, wegen der Art, wie das Projekt bereitgestellt wird. Irgendwelche Hinweise auf die Tricks wie du erwähnt hast? – Tyress

+0

Sie bearbeiten die Quelle nicht, fügen Sie nur die zweite Erweiterung zu Ihrem eigenen Code hinzu. – ColGraff

+0

Wenn Sie eine Methode 'delete (keys: String ...)' haben, kann es beliebig viele 'String' Werte annehmen. Innerhalb der Methode wird der variadische Parameter (der Typ, dem drei Punkte folgen) von 'keys: String ...' zu 'keys: [String]'. In diesem Fall führt die Methode dann 'keys.joined (separator:" ")' aus, das alle "String" -Werte zu einer "String" verbindet, wobei jedes Original durch "" getrennt ist. ** Dies geschieht nicht bei jeder Methode, die einen variablen Parameter verwendet! ** – ColGraff

1

Ich glaube, Sie haben eine Alternative zu verwenden, da nach der Dokumentation

Die Werte an einen variadische Parameter übergeben innerhalb die körpereigene Funktion als Array des entsprechenden Typs

so können Sie entweder die Arbeit innerhalb der Rückruf von getClient tun zur Verfügung gestellt und Zeichenfolgen übergeben Komma Sie getrennt oder als die

ich das Array bis auf Einzelsaiten brechen können und individuell

oder Sie können so etwas tun löschen:

func deleteKeyForAPI(_ receivedKeys: String...) { 

     //here reveivedKeys is an array... 
     print(receivedKeys) //here you can separate keys 


} 

func yourDeleteKeyFunction(_ receivedKeys: String){ 
     deleteKeyForAPI(receivedKeys) 
} 

let myKeys = "s1, s2, s3" 
yourDeleteKeyFunction(myKeys) 
Verwandte Themen