Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
泛型字典类的Swift编译器错误:无法调用';移除值';具有类型为';(forKey K)和"x27 ;;_Swift_Generics_Concurrency - Fatal编程技术网

泛型字典类的Swift编译器错误:无法调用';移除值';具有类型为';(forKey K)和"x27 ;;

泛型字典类的Swift编译器错误:无法调用';移除值';具有类型为';(forKey K)和"x27 ;;,swift,generics,concurrency,Swift,Generics,Concurrency,我创建了一个简单的dictionary类,用于跨多个线程同步访问字典。我正在使用DispatchQueue来同步字典中值的读取和写入。我使用的是generic,因此它可以与任何字典类型一起使用,K:Hashable表示键,T表示对象 下面是该类的一个示例: public class SynchronizedDictionary<K, T> where K: Hashable { private var accessQueue: DispatchQueue! pri

我创建了一个简单的dictionary类,用于跨多个线程同步访问字典。我正在使用DispatchQueue来同步字典中值的读取和写入。我使用的是generic,因此它可以与任何字典类型一起使用,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)
        }
    }
}
public类SynchronizedDictionary其中K:Hashable{
私有var访问队列:DispatchQueue!
私有var internalDict:[K:T]
初始化(队列名称:字符串){
accessQueue=DispatchQueue(标签:queueName,qos:.默认值)
internalDict=[:]
}
func removeValue(分叉键:K){
accessQueue.async(标志:。屏障){
self.internalDict.removeValue(forKey:key)
}
}
}
尝试调用dictionary类上的removeValue函数时,编译器会出现以下错误: 无法使用类型为“(forKey:K)”的参数列表调用“removeValue”


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

您已经用以下类型将K设置为可哈希类型:

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

因此,在removeValue中:

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

您不应该将
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)
        }
    }
}
public类SynchronizedDictionary其中K:Hashable{
私有var访问队列:DispatchQueue!
私有var internalDict:[K:T]
初始化(队列名称:字符串){
accessQueue=DispatchQueue(标签:queueName,qos:.默认值)
internalDict=[:]
}
func removeValue(分叉键:K){
accessQueue.async(标志:。屏障){
self.internalDict.removeValue(forKey:key)
}
}
}

这就是
removeValue
应该如何实现的

func removeValue(forKey key: K) {
    accessQueue.async(flags: .barrier) {
        self.internalDict.removeValue(forKey: key)
    }
}
请注意,我是如何从方法中删除泛型参数
K
,而是从类声明中使用泛型参数
K

您不能使用新的泛型类型参数
K
,因为该类型可能与字典的键类型不同,而字典的键类型是类声明中的
K
。如果您可以这样做,则可以执行类似操作:

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

removeValue
K
参数将被推断为
String
。显然这毫无意义,因此不允许这样做。

基本上与此处相同的错误:–
func removeValue(…)
引入了一个新的本地通用占位符
K
。只需将其设为
func removeValue(…)
Aha.谢谢!我删除了该方法的通用规范,并且能够成功编译和测试。谢谢!这很有效。我接受了另一个具有相同细节的答案。谢谢。看起来是正确的。我接受了上面类似的答案。