Swift 如何将此实用函数转换为扩展函数?

Swift 如何将此实用函数转换为扩展函数?,swift,dictionary,compiler-errors,set,swift-extensions,Swift,Dictionary,Compiler Errors,Set,Swift Extensions,我在Swift 4中编写了这个实用函数: func insert(value:Element,进入字典:inout[Key:Set],在Key:Key处){ 如果let=字典[键]{ 字典[键]?.插入(值) } 否则{ var set=set() set.insert(值) 字典[键]=集合 } } 这是这样使用的: insert("foo", into: &myDictionary, at: "bar") myDictionary.insert("foo", at: "bar")

我在Swift 4中编写了这个实用函数:

func insert(value:Element,进入字典:inout[Key:Set],在Key:Key处){
如果let=字典[键]{
字典[键]?.插入(值)
}
否则{
var set=set()
set.insert(值)
字典[键]=集合
}
}
这是这样使用的:

insert("foo", into: &myDictionary, at: "bar")
myDictionary.insert("foo", at: "bar")
extension Dictionary where Value == Set<AnyHashable> {
    mutating func insert(_ value: Value.Element, at key: Key) { // Error here
        if let _ = self[key] {
            self[key]?.insert(value)
        } else {
            var set = Set<Value.Element>() // Error here
            set.insert(value)
            self[key] = set
        }
    }
}
。。。但我想这样使用它:

insert("foo", into: &myDictionary, at: "bar")
myDictionary.insert("foo", at: "bar")
extension Dictionary where Value == Set<AnyHashable> {
    mutating func insert(_ value: Value.Element, at key: Key) { // Error here
        if let _ = self[key] {
            self[key]?.insert(value)
        } else {
            var set = Set<Value.Element>() // Error here
            set.insert(value)
            self[key] = set
        }
    }
}
我试着这样宣布:

insert("foo", into: &myDictionary, at: "bar")
myDictionary.insert("foo", at: "bar")
extension Dictionary where Value == Set<AnyHashable> {
    mutating func insert(_ value: Value.Element, at key: Key) { // Error here
        if let _ = self[key] {
            self[key]?.insert(value)
        } else {
            var set = Set<Value.Element>() // Error here
            set.insert(value)
            self[key] = set
        }
    }
}
扩展字典,其中Value==Set{
mutating func insert(value:value.Element,在key:key处){//此处出错
如果let=self[键]{
自[键]?.插入(值)
}否则{
var set=set()//此处出错
set.insert(值)
自[键]=设置
}
}
}
。。。但我得到以下错误:

/path/to/Sequence Extensions.swift:2:41:错误:“Element”不是“Dictionary.Value”的成员类型
变异func插入(value:value.Element,在key:key处){
~~~~~ ^
Swift.Set:608:22:注意:你的意思是“元素”吗?
公共类型别名元素=元素
^
Swift._IndexableBase:3:22:注意:您是指“_元素”吗?
公共类型别名_元素=Self.Element
/路径/到/序列扩展。swift:6:23:错误:类型“Value.Element”不符合协议“Hashable”
var set=set()
^

不幸的是,Swift目前不支持(在扩展声明中引入类型变量的能力),因此您目前无法直接表达“对某些
集具有约束的扩展”的概念但是,它是泛型宣言的一部分,所以希望它能成为该语言未来版本的一部分

即使您的扩展名带有
约束为
设置并)

尽管如此,我目前正在为
字典
下标(u:default:)
修复此问题,以便可以在适当的位置对集合进行变异

在修复之前,解决方案是先从字典中删除集合,然后再进行变异:

extension Dictionary where Value : SetAlgebra {

    mutating func insert(_ value: Value.Element, at key: Key) {
        var set = removeValue(forKey: key) ?? []
        set.insert(value)
        self[key] = set
    }
}
在这种情况下,使用扩展是完全合理的


值得注意的是,这里使用协议约束是通用的解决方案(在某些情况下是解决方法)解决了没有参数化扩展的问题。它允许您实现所需的占位符作为该协议的关联类型。有关如何创建自己的协议以实现该目的的示例,请参阅。

不幸的是,Swift目前不支持(在扩展声明中引入类型变量的功能),因此您目前无法直接表达“对某个
集合
具有约束的扩展”的概念。然而,它是泛型宣言的一部分,因此希望它能成为该语言未来版本的一部分

即使您的扩展名带有
约束为
设置并)

尽管如此,我目前正在为
字典
下标(u:default:)
修复此问题,以便可以在适当的位置对集合进行变异

在修复之前,解决方案是先从字典中删除集合,然后再进行变异:

extension Dictionary where Value : SetAlgebra {

    mutating func insert(_ value: Value.Element, at key: Key) {
        var set = removeValue(forKey: key) ?? []
        set.insert(value)
        self[key] = set
    }
}
在这种情况下,使用扩展是完全合理的


值得注意的是,这里使用协议约束是通用的解决方案(在某些情况下是解决方法)解决了没有参数化扩展的问题。它允许您实现所需的占位符作为该协议的关联类型。有关如何创建自己的协议以实现该目的的示例,请参阅。

您可以使用协议来标识集合:

protocol SetType
{
   associatedtype Element:Hashable
   init()
   mutating func insert(_ : Element) ->  (inserted: Bool, memberAfterInsert: Element)
}

extension Set:SetType 
{}

extension Dictionary where Value : SetType 
{
   mutating func insert(_ value:Value.Element, at key:Key)
   {
      var valueSet:Value = self[key] ?? Value()
      valueSet.insert(value)
      self[key] = valueSet
   }
}

var oneToMany:[String:Set<String>] = [:]

oneToMany.insert("Dog", at: "Animal")
oneToMany.insert("Cat", at: "Animal")
oneToMany.insert("Tomato", at: "Vegetable")
更合适的实现将使用与集合的insert()函数相同的返回值,但是:

extension Dictionary where Value : SetType 
{
   @discardableResult
   mutating func insert(_ value:Value.Element, at key:Key) ->  (inserted: Bool, memberAfterInsert: Value.Element)
   {
      var valueSet:Value = self[key] ?? Value()
      let result = valueSet.insert(value)
      if result.inserted 
      { self[key] = valueSet }
      return result
   }
}

[编辑]我刚刚阅读了哈米什的所有回答,意识到他已经给出了相同的答案(本质上)并利用了SETALOGRAGE(我不知道),它与我“改造”的SetType做了相同的事情。你应该接受哈米什的答案。

你可以使用协议来识别集合:

protocol SetType
{
   associatedtype Element:Hashable
   init()
   mutating func insert(_ : Element) ->  (inserted: Bool, memberAfterInsert: Element)
}

extension Set:SetType 
{}

extension Dictionary where Value : SetType 
{
   mutating func insert(_ value:Value.Element, at key:Key)
   {
      var valueSet:Value = self[key] ?? Value()
      valueSet.insert(value)
      self[key] = valueSet
   }
}

var oneToMany:[String:Set<String>] = [:]

oneToMany.insert("Dog", at: "Animal")
oneToMany.insert("Cat", at: "Animal")
oneToMany.insert("Tomato", at: "Vegetable")
更合适的实现将使用与集合的insert()函数相同的返回值,但是:

extension Dictionary where Value : SetType 
{
   @discardableResult
   mutating func insert(_ value:Value.Element, at key:Key) ->  (inserted: Bool, memberAfterInsert: Value.Element)
   {
      var valueSet:Value = self[key] ?? Value()
      let result = valueSet.insert(value)
      if result.inserted 
      { self[key] = valueSet }
      return result
   }
}
[编辑]我刚刚阅读了哈米什的所有回复,意识到他已经给出了相同的答案(本质上),并利用了集代数(我不知道)来做与我“重新发明”的集类型相同的事情。你应该接受哈米什的答案