在协议扩展上进行数学运算的通用方法

Max*_*Max 10 generics protocols swift

目标

我想延长基本类型,如Int,Double,Float...更灵活的特性,使之在我的应用程序在图表中呈现的.例如,我制作的图表绘制仅适用于显示Int但不能真正显示Float.我想确保当我将参数传递给此视图时它将正确显示.

所以我制作了一个协议(这个例子就是这样的):

protocol SimplyChartable { 
        static func max(_ dataSet: [SimplyChartable]) -> SimplyChartable
}
Run Code Online (Sandbox Code Playgroud)

然后为某些类型进行扩展:

extension Int: SimplyChartable { }
extension Double: SimplyChartable { } 
extension Float: SimplyChartable { } 
Run Code Online (Sandbox Code Playgroud)

等等 ...

问题

这将是所有数字类型,每当我将它作为数字类型传递给func我时,我需要像这样扩展所有扩展:

public static func max(_ dataSet: [SimplyChartable]) -> SimplyChartable { 
    return (dataSet as? [Int])?.max() ?? 0
}
Run Code Online (Sandbox Code Playgroud)

但对于Doublefunc将是相同的.

因此,对于min,我将最终得到类似的功能,对于除法,添加,一些其他数学也是如此...有一种方法可以将其写入一次并重用于扩展此协议的每种类型?

我发现:

    let dataType = type(of: maxValue) /* where `maxValue` is SimplyChartable*/
Run Code Online (Sandbox Code Playgroud)

将原始类型返回为rawValue.但是方法的输出type(of是a Metatype,我不能从函数返回它,然后添加这种类型的两个值.所以例如这段代码不起作用:

let val1 = SimplyChartable(4)
let val2 = SimplyChartable(2)
let sum = val1 + val2
Run Code Online (Sandbox Code Playgroud)

以及如何使其工作不会像这样的3个函数结束:

let val1 = SimplyChartable(4)
let val2 = SimplyChartable(2)
let sum = (val1 as! Int) + (val2 as! Int)
Run Code Online (Sandbox Code Playgroud)

kor*_*pok 3

既然它们都是数字类型,为什么不使用 Comparable 呢?

extension SimplyChartable {

    static func max<T: Comparable>(dataSet: [T]) -> T? {
        return dataSet.max()
    }

    static func min<T: Comparable>(dataSet: [T]) -> T? {
        return dataSet.min()
    }
}

extension Int: SimplyChartable { }
extension Double: SimplyChartable { }

Double.max([1.2, 1.1, 1.3])  // 1.3
Int.min([12, 11, 13])  // 11
Run Code Online (Sandbox Code Playgroud)

只值我的两分钱...