Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.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 定义在其他协议中声明的typeliases_Swift_Inheritance_Protocols - Fatal编程技术网

Swift 定义在其他协议中声明的typeliases

Swift 定义在其他协议中声明的typeliases,swift,inheritance,protocols,Swift,Inheritance,Protocols,我正在创建一个从CollectionType扩展而来的协议,但是,我正在引入新的类型别名,以消除CollectionType中对元素的需要(或者更确切地说,它们允许我计算它) 我将使用一个简单的MapType协议作为示例: protocol MapType : CollectionType, DictionaryLiteralConvertible { typealias Key typealias Value func updateValue(theNewValue:

我正在创建一个从
CollectionType
扩展而来的协议,但是,我正在引入新的类型别名,以消除
CollectionType
中对
元素的需要(或者更确切地说,它们允许我计算它)

我将使用一个简单的
MapType
协议作为示例:

protocol MapType : CollectionType, DictionaryLiteralConvertible {
    typealias Key
    typealias Value

    func updateValue(theNewValue:Value, forKey theKey:Key) -> Value?
}
在上面的示例中,我真正需要做的是将
元素
重新定义为元组
(键、值)
,但我不确定如何在协议中而不是在结构或类中实现这一点

简单地添加
typealias元素=(Key,Value)
不会产生任何错误,但在协议上下文中似乎也不会实际执行任何操作,例如,以下操作将不起作用:

extension MapType {
    var firstKey:Key? { return self.generate().next()?.0 }
}
这会产生错误,因为生成器未被识别为返回元组(即-它没有成员
.0

在这种情况下,将
元素
定义为
(键、值)
的最佳方法是什么,以便我可以在协议扩展中使用它?这可能吗?

我们不能强制从
集合类型
协议继承的
元素
类型必须是由
类型从
映射类型
组成的元组

但是,我们可以将协议扩展限制为仅使用
where
语句将
firstKey
方法添加到那些确实符合协议的方法中

考虑这个简化的例子:

protocol Base {
    typealias Element

    func first() -> Element?
}

protocol Child: Base {
    typealias Key
    typealias Value

    func last() -> (Key, Value)?
}

extension Child where Self.Element == (Self.Key, Self.Value) {
    var firstKey:Key? { return self.first()?.0 }
}

struct ChildStruct: Child {
    func first() -> (String, Int)? {
        return ("Foo", 1)
    }

    func last() -> (String, Int)? {
        return ("Bar", 2)
    }
}

let c = ChildStruct()
let first = c.first()
let firstKey = c.firstKey

您基本上是在协议中创建一个
where
子句。这在今天的Swift中是不可能的。不能基于其他关联类型约束关联类型。也许有一天,但不是今天


你需要重新思考你是如何解决这个问题的。可能的解决方案是使用泛型结构而不是协议(否则,代码中会出现大量重复的
where
子句)。您可以查看这篇最新文章,了解更多详细的示例。

您真正想做的是什么?什么是MapType的集合,它在什么意义上是集合?@matt似乎是基于此处内容的大致有序词典。
MapType
。顺便说一句,请注意,“typealias”一词的使用在Swift 2.2中消失了:它将被称为“associatedtype”。
MapType
只是一个简单的例子,但这确实是一个我需要定义的协议,因为我们没有抽象类(实际上我正在实现一组结构)。在发布这篇文章之后,我探索了独立于
CollectionType
定义MapType的可能性,但现在似乎没有完美的选择,因此像nhgrif建议的
where
子句可能是我目前最好的选择。