arrays - Swift3:泛型扩展中的类型推断

标签 arrays swift extension-methods concat swift3

我需要做这样的事情:

extension Array { 
    func flat() -> Element { return self.flatMap { $0 } }
}

但是类型推断有问题:

'flatMap' produces '[SegmentOfResult.Iterator.Element]', not the expected contextual result type 'Element'

编辑:使用示例:

[[1,2],[3,4,5],[6]].flat()

应该产生 [1,2,3,4,5,6] 与:

[[1,2],[3,4,5],[6]].flatMap { $0 }

最佳答案

如果你看一下 flatMap(_:)签名,

extension Sequence {
    // ...
    public func flatMap<SegmentOfResult : Sequence>(_ transform: (Self.Iterator.Element) throws -> SegmentOfResult) rethrows -> [SegmentOfResult.Iterator.Element]
    // ...
}

您会看到它返回一个 [SegmentOfResult.Iterator.Element],其中 SegmentOfResult 是您传递给它的函数返回的类型。这不一定与 Element 的类型相同(因为您的扩展适用于所有 数组),这就是您的代码无法编译的原因。

为了使用元素为序列的数组,您需要限制您的扩展,以便 Element : Sequence

此外,由于您传递给 flatMap(_:) 的函数是恒等变换(它只返回作为输入接收的元素),您需要更改返回类型到 [Element.Iterator.Element](内部元素的数组)。

extension Array where Element : Sequence {
    func flat() -> [Element.Iterator.Element] {
        return self.flatMap { $0 }
    }
}

尽管如此,我看不出为什么这不应该是 Sequence 的扩展:

// An extension for a sequence of sequences
extension Sequence where Iterator.Element : Sequence {

    // returns an array of the inner element type (an array of the element of the element)
    func flat() -> [Iterator.Element.Iterator.Element] { 
        return self.flatMap { $0 }
    }
}

(但是,我一开始并没有真正看到为此创建扩展的必要性——array.flatMap{$0} 并不冗长!)

关于arrays - Swift3:泛型扩展中的类型推断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39517366/

相关文章:

C++ 整数数组转换和操作

java - 为什么在编译时不检查多重绑定(bind)泛型

clr - .NET 2.0中具有扩展属性的Escape Catch-22

javascript - 检查 jquery 对象数组是否匹配键。 += value 如果匹配,如果不匹配则推送新对象

javascript - 如何在 JavaScript 中创建对象/数组?

C: 无法接收指向结构数组的指针

swift - 如何添加可选的字符串扩展?

json - 可选(<OS_dispatch_data : data[0x7f97b145f2f0] = { leaf, 大小 = 17290,buf = 0x11a63f000 }>)

swift - 在 Swift 中传递关键字

linq - 通过扩展方法在 linq to sql 查询中封装逻辑