Swift 如何将此实用函数转换为扩展函数?
我在Swift 4中编写了这个实用函数: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")
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
}
}
[编辑]我刚刚阅读了哈米什的所有回复,意识到他已经给出了相同的答案(本质上),并利用了集代数(我不知道)来做与我“重新发明”的集类型相同的事情。你应该接受哈米什的答案