【问题标题】:Swift 3: Method expecting variadic String parameter can only receive single String argumentSwift 3:期望可变字符串参数的方法只能接收单个字符串参数
【发布时间】:2018-02-07 14:39:20
【问题描述】:

我正在调用一个需要String... 可变参数的方法,但它唯一允许从封闭函数接收的是一个普通的String

我的方法是这样的:

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

编译错误是

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

此方法 (client.delete()) 来自 Perfect-Swift 的 Redis API,因此我无法更改签名,但我可以更改封闭函数 (deleteKeys)。我也不能直接调用该函数,因为它在回调闭包中

关于如何将接收到的可变参数传递给封闭的可变参数函数有什么建议吗?我可以将数组分解为单个字符串并单独删除,但这似乎不是很有效

【问题讨论】:

  • 您是否称其为obj.deleteKeys(keysReceived: "Hello", "World", "Something") { }?那应该可以。
  • @nayem 它不会编译,我什至还没有调用它
  • 你能显示delete(keys:)方法的签名吗?
  • @nayem 这是client.delete(keys: String..., callback: RedisClient.redisResponseCallback),没有其他重载
  • 没有意义,因为您的呼叫没有callback 参数。你能分享那个 API 的链接吗?

标签: swift swift3 variadic perfect


【解决方案1】:

可变参数表示它是一个后跟三个点的类型,例如String...,它们用于传入可变数量的相同类型的值。您不能将方法的可变参数传递给另一个方法。在方法内部,它变成了一个Array,如果没有很多你真的不想在这种情况下打扰的诡计,它就不能作为可变参数传递。

不过,我们可以从source看到:

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

他们所做的只是将Array 与一个空格作为分隔符连接起来。因此,您可以在顶层将其添加到您自己的代码中:

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

然后你可以调用它:

client.delete(keys: keysReceived){}

请注意,这只适用于这种特殊情况,因为在内部,原始方法将字符串转换为:

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

到:

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

然后到:

"one two three"

我正在手动执行此操作并将最后一个字符串传递给它,例如:

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

变成:

["one two three"]

然后是joined到:

"one two three"

所以调用self.sendCommand时最终的结果是一样的。

这很可能不适用于其他可变参数方法,因为它依赖于在内部使用 joined 方法的方法。

【讨论】:

  • 谢谢,由于项目的部署方式,恐怕我无法编辑源代码。关于你提到的诡计的任何提示?
  • 您无需编辑源代码,只需将第二个扩展添加到您自己的代码中即可。
  • 如果你有一个方法 delete(keys: String...) 它可以接受任意数量的 String 值。在方法内部,keys: String... 的可变参数(后跟三个点的类型)将变为keys: [String]。在这种情况下,该方法然后执行keys.joined(separator: " "),它将所有String 值连接成一个String,每个原始值用“”分隔。 这不会发生在每个使用可变参数的方法中!
  • 感谢您的帮助,谢谢。删除了我之前的评论,以免混淆任何人。
  • 没问题,在你这么说之后,我看到我的回答可能令人困惑,我澄清了它。很高兴它帮助了你!
【解决方案2】:

我认为您必须使用一些替代方法,因为根据文档

传递给可变参数的值在 函数体作为适当类型的数组

因此,您可以在 getClient 的回调中完成工作并传递逗号分隔的字符串,或者按照您的说法

我可以将数组分解为单个字符串并单独删除

或者你可以这样做:

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)

【讨论】:

    猜你喜欢
    • 2016-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-01
    相关资源
    最近更新 更多