我们如何创建通用数组扩展来汇总Swift中的数字类型?

神话

Swift可让您创建一个将Integer与之相加的Array扩展:

extension Array {
    func sum() -> Int {
        return self.map { $0 as Int }.reduce(0) { $0 + $1 }
    }
}

现在可以用来总结Int[]如下:

[1,2,3].sum() //6

但是我们如何制作一个通用的版本,该版本也支持对其他Number类型进行求和Double[]

[1.1,2.1,3.1].sum() //fails

这个问题不是如何对数字求和,而是如何创建通用数组扩展来实现。


越来越近

如果可以帮助任何人更接近解决方案,这是我能够获得的最接近的结果:

您可以创建一个可以满足我们需要做的协议,即:

protocol Addable {
    func +(lhs: Self, rhs: Self) -> Self
    init()
}

然后扩展我们想要支持的符合上述协议的每种类型:

extension Int : Addable {
}

extension Double : Addable {
}

然后添加具有该约束的扩展:

extension Array {
    func sum<T : Addable>(min:T) -> T
    {
        return self.map { $0 as T }.reduce(min) { $0 + $1 }
    }
}

现在可以将其用于我们为支持该协议而扩展的数字,即:

[1,2,3].sum(0) //6
[1.1,2.1,3.1].sum(0.0) //6.3

不幸的是,我不得不提供一个参数就无法使它工作,即:

func sum<T : Addable>(x:T...) -> T?
{
    return self.map { $0 as T }.reduce(T()) { $0 + $1 }
}

修改后的方法仍然可以使用1个参数:

[1,2,3].sum(0) //6

但是在不带参数调用时无法解析该方法,即:

[1,2,3].sum() //Could not find member 'sum'

添加Integer到方法签名也无助于方法解析:

func sum<T where T : Integer, T: Addable>() -> T?
{
    return self.map { $0 as T }.reduce(T()) { $0 + $1 }
}

但是希望这将帮助其他人更接近解决方案。


一些进展

从@GabrielePetronella答案来看,如果我们在调用站点上明确指定类型,则可以调用上述方法:

let i:Int = [1,2,3].sum()
let d:Double = [1.1,2.2,3.3].sum()
贝克·史密斯

从Swift 2开始,可以使用协议扩展来做到这一点。(有关更多信息,请参见Swift编程语言:协议)。

首先,该Addable协议:

protocol Addable: IntegerLiteralConvertible {
    func + (lhs: Self, rhs: Self) -> Self
}

extension Int   : Addable {}
extension Double: Addable {}
// ...

接下来,扩展SequenceType以添加Addable元素序列

extension SequenceType where Generator.Element: Addable {
    var sum: Generator.Element {
        return reduce(0, combine: +)
    }
}

用法:

let ints = [0, 1, 2, 3]
print(ints.sum) // Prints: "6"

let doubles = [0.0, 1.0, 2.0, 3.0]
print(doubles.sum) // Prints: "6.0"

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

我们如何在 awk 中创建数组?

来自分类Dev

我们如何扩展所有枚举类型?

来自分类Dev

我们可以以任何方式拖放扩展图标/符号来改变它们的位置。我们如何在 Ubuntu 20.04 LTS 中轻松控制它?

来自分类Dev

我们如何创建一个我们应该实现的对象的“骨架类型”?

来自分类Dev

我们如何使用循环从数组中创建检查按钮并打印所选检查按钮的值?

来自分类Dev

我们可以通过不同的方式来创建类,而不能将其子类化(扩展)?

来自分类Dev

我们如何防止参数扩展?

来自分类Dev

我们如何在Liferay中创建后退按钮

来自分类Dev

我们如何在 React 中创建动态元素

来自分类Dev

我们如何在 LogDNA 中创建变量?

来自分类Dev

我们如何显示数组中的收集数据

来自分类Dev

我们如何从数组中过滤文本

来自分类Dev

我们如何选择数组中的随机元素?

来自分类Dev

通过遵循Swift 2中的协议来扩展类型数组

来自分类Dev

我们如何在Swift中评估bool值?

来自分类Dev

我们如何在Excel中汇总时间序列?

来自分类Dev

我们如何在yml中创建一个由2个属性组成的数组?

来自分类Dev

我们可以在 java 中创建哪些不同类型的文件(文件类型)?

来自分类Dev

您能告诉我们如何或什么方式来创建Android游戏吗?

来自分类Dev

我们如何访问多维数组

来自分类Dev

我们可以使用动态扩展磁盘在Azure中创建VM吗?

来自分类常见问题

我们可以在Android中创建自定义的Synthetic Kotlin扩展吗?

来自分类Dev

如何扩展接受数组通用元素的类型?

来自分类Dev

如何正确扩展数组的通用返回类型

来自分类Dev

如何扩展接受数组通用元素的类型?

来自分类Dev

我们如何创建一个递归函数来查找数字的最高位数?

来自分类Dev

我们如何为Acumatica中的自定义新屏幕添加通用搜索

来自分类Dev

我们如何在Django中通过基于类的通用视图保存表单

来自分类Dev

如何在Java中创建类型安全的通用数组?

Related 相关文章

  1. 1

    我们如何在 awk 中创建数组?

  2. 2

    我们如何扩展所有枚举类型?

  3. 3

    我们可以以任何方式拖放扩展图标/符号来改变它们的位置。我们如何在 Ubuntu 20.04 LTS 中轻松控制它?

  4. 4

    我们如何创建一个我们应该实现的对象的“骨架类型”?

  5. 5

    我们如何使用循环从数组中创建检查按钮并打印所选检查按钮的值?

  6. 6

    我们可以通过不同的方式来创建类,而不能将其子类化(扩展)?

  7. 7

    我们如何防止参数扩展?

  8. 8

    我们如何在Liferay中创建后退按钮

  9. 9

    我们如何在 React 中创建动态元素

  10. 10

    我们如何在 LogDNA 中创建变量?

  11. 11

    我们如何显示数组中的收集数据

  12. 12

    我们如何从数组中过滤文本

  13. 13

    我们如何选择数组中的随机元素?

  14. 14

    通过遵循Swift 2中的协议来扩展类型数组

  15. 15

    我们如何在Swift中评估bool值?

  16. 16

    我们如何在Excel中汇总时间序列?

  17. 17

    我们如何在yml中创建一个由2个属性组成的数组?

  18. 18

    我们可以在 java 中创建哪些不同类型的文件(文件类型)?

  19. 19

    您能告诉我们如何或什么方式来创建Android游戏吗?

  20. 20

    我们如何访问多维数组

  21. 21

    我们可以使用动态扩展磁盘在Azure中创建VM吗?

  22. 22

    我们可以在Android中创建自定义的Synthetic Kotlin扩展吗?

  23. 23

    如何扩展接受数组通用元素的类型?

  24. 24

    如何正确扩展数组的通用返回类型

  25. 25

    如何扩展接受数组通用元素的类型?

  26. 26

    我们如何创建一个递归函数来查找数字的最高位数?

  27. 27

    我们如何为Acumatica中的自定义新屏幕添加通用搜索

  28. 28

    我们如何在Django中通过基于类的通用视图保存表单

  29. 29

    如何在Java中创建类型安全的通用数组?

热门标签

归档