通用字典类的 Swift 编译器错误:无法使用类型为“(forKey K)”的参数列表调用“removeValue”

Posted

技术标签:

【中文标题】通用字典类的 Swift 编译器错误:无法使用类型为“(forKey K)”的参数列表调用“removeValue”【英文标题】:Swift compiler error for generic dictionary class: cannot invoke 'removeValue' with an argument list of type '(forKey K)' 【发布时间】:2018-07-08 09:28:57 【问题描述】:

我创建了一个简单的字典类,用于跨多个线程同步访问字典。我正在使用 DispatchQueue 来同步从字典中读取和写入值。我使用的是泛型,因此它可以与任何字典类型一起使用 K:Hashable 作为键,T 用于对象。

这是一个类的例子:

public class SynchronizedDictionary<K, T> where K: Hashable 

    private var accessQueue: DispatchQueue!

    private var internalDict: [K: T]

    init(queueName: String) 
        accessQueue = DispatchQueue(label: queueName, qos: .default)
        internalDict = [:]
    

    func removeValue<K:Hashable>(forKey key: K) 
        accessQueue.async(flags: .barrier) 
            self.internalDict.removeValue(forKey: key)
        
    

尝试在字典类上调用 removeValue 函数时,编译器会出现以下错误: "不能使用类型为 '(forKey: K)' 的参数列表调用 'removeValue'

知道为什么我不能用泛型类型调用这个 removeValue 函数吗?

【问题讨论】:

与此处的错误基本相同:***.com/questions/33891280/… – func removeValue&lt;K:Hashable&gt;(...) 引入了新的本地通用占位符 K。就让它func removeValue(...) 【参考方案1】:

您已经将 K 设置为 Hashable 类型:

公共类 SynchronizedDictionary 其中 K: Hashable ...

所以在 removeValue 中:

func removeValue(forKey key: K) 
    accessQueue.async(flags: .barrier) 
        self.internalDict.removeValue(forKey: key)
    

【讨论】:

谢谢。看起来正确。我接受了上面类似的答案。【参考方案2】:

您不应该将removeValue 设为泛型,因为通过将其设为泛型,您将创建一个新的本地泛型类型K,它与您的类的泛型类型不同。只需从函数声明中删除泛型类型,然后使用 K,因为您正在定义泛型类型的新实例函数,所以您可以访问它。

public class SynchronizedDictionary<K, T> where K: Hashable 

    private var accessQueue: DispatchQueue!

    private var internalDict: [K: T]

    init(queueName: String) 
        accessQueue = DispatchQueue(label: queueName, qos: .default)
        internalDict = [:]
    

    func removeValue(forKey key: K) 
        accessQueue.async(flags: .barrier) 
            self.internalDict.removeValue(forKey: key)
        
    

【讨论】:

谢谢!这行得通。我接受了另一个具有相同细节的答案。【参考方案3】:

这就是removeValue 的实现方式。

func removeValue(forKey key: K) 
    accessQueue.async(flags: .barrier) 
        self.internalDict.removeValue(forKey: key)
    

请注意我是如何从方法中删除泛型参数K 并使用类声明中的泛型参数K

您不能使用 new 泛型类型参数 K,因为它可能与字典的键类型不同,即 类声明中的 K .如果你能做到这一点,这样的事情是可能的:

SynchronizedDictionary<Int, Int>(queueName: "myQueue").removeValue(forKey: "myKey")

removeValueK 参数将被推断为 String。显然这根本没有意义,所以你不能这样做。

【讨论】:

啊哈。谢谢!我删除了该方法的通用规范,并且能够成功编译和测试。

以上是关于通用字典类的 Swift 编译器错误:无法使用类型为“(forKey K)”的参数列表调用“removeValue”的主要内容,如果未能解决你的问题,请参考以下文章

Swift 编译器错误:“无法使用 '((_) -> _)' 类型的参数列表调用 'map'”

Swift语法[变量常亮区间运算符字典]

Swift 1D 字典到 2D

具有覆盖函数的嵌套类的编译器错误 - Swift Xcode6

更新到 Swift 3.0:上下文类型“AnyObject”不能与字典文字一起使用

如何使用swift在pubnub中将数据发布为Any类型的字典?