通用类型的Swift条件一致性

Mar*_*tin 8 swift

我正在尝试使用两种通用类型来开发Swift扩展。我试图举一个例子。

我们有一个盒子,可以放不同类型的盒子。

class Box<E> {
    var value: E
    init(val: E) {
        value = val
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我们有一个特殊的Itemtype,它又可以具有不同的类型

class Item<Type> {
    var value: Type
    init(val: Type) {
        value = val
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,我们可以轻松创建一个Box<Item<Int>>。但也许我们想将其更改为Box<Item<String>> 所以我想扩展一下以从更改Box<Item<A>>Box<Item<B>>

起作用的是以下内容

extension Box where E: Item<Any> {
    func mapOnItem(function: (Any) -> Any) -> Box<Item<Any>> {
        return Box<Item<Any>>(val: Item(val: function(value.value)))
    }
}
Run Code Online (Sandbox Code Playgroud)

但这不是很有用,因为我们没有从函数返回值到mapOnItem返回值的连接。

所以我尝试修复,但失败了。我的理解是在这里引入另一个通用变量。

extension Box<A> where E: Item<A> {
    func mapOnItem<B>(function: (A) -> B) -> Box<Item<B>> {
        return Box<Item<B>>(val: Item(val: function(value.value)))
    }
}
Run Code Online (Sandbox Code Playgroud)

我遇到了错误

约束扩展必须在非专用泛型类型“ Box”上声明,且其约束由“ where”子句指定

你对我有什么线索吗?可能吗?

谢谢你的帮助

马丁

Mar*_*n R 10

扩展的约束可以将占位符类型限制E为具体类型或协议,例如:

extension Box where E: Item<Any> {}
extension Box where E == String {}
extension Box where E: Numeric {}
Run Code Online (Sandbox Code Playgroud)

但是您不能对扩展名施加一般约束:

extension Box<A> where E: Item<A> {}
// Error: Constrained extension must be declared on the unspecialized generic
// type 'Box' with constraints specified by a 'where' clause
Run Code Online (Sandbox Code Playgroud)

解决方案是限制方法

extension Box  {
    func mapOnItem<A, B>(function: (A) -> B) -> Box<Item<B>> where E: Item<A> {
        return Box<Item<B>>(val: Item(val: function(self.value.value)))
    }
}
Run Code Online (Sandbox Code Playgroud)