【问题标题】:Optimal Custom Operator with Generic Type Constraint for Numerical Type数值类型具有泛型约束的最优自定义算子
【发布时间】:2016-12-15 06:11:21
【问题描述】:

我正在(为一篇文章)实现两个自定义中缀运算符:

  • ¿% - 计算总数的百分比。
  • %? - 计算代表总数的百分比。

在调试了一些错误并查找信息后,我终于找到了让我的代码正常工作的方法:

protocol NumericType {
    static func *(lhs: Self, rhs: Self) -> Self
    static func *(lhs: Self, rhs: Int) -> Self
    static func /(lhs: Self, rhs: Self) -> Self
    static func /(lhs: Self, rhs: Int) -> Self
} // NumericType

extension Double : NumericType {
    internal static func *(lhs: Double, rhs: Int) -> Double {
        return lhs * Double(rhs)
    }

    internal static func /(lhs: Double, rhs: Int) -> Double {
        return lhs / Double(rhs)
    }
 }

extension Float  : NumericType {
    internal static func *(lhs: Float, rhs: Int) -> Float {
        return lhs * Float(rhs)
    }

    internal static func /(lhs: Float, rhs: Int) -> Float {
        return lhs / Float(rhs)
    }
 }

extension Int : NumericType { }

infix operator ¿%

func ¿% <T: NumericType>(percentage: T, ofThisTotalValue: T) -> T {

    return (percentage * ofThisTotalValue) / 100

} // infix operator ¿%

infix operator %?

func %? <T: NumericType>(segmentOf: T, thisTotalValue: T) -> T {

    return (segmentOf * 100) / thisTotalValue

} // infix operator %?

let percentage: Double = 8
let price: Double = 45

let save = percentage ¿% price

print("\(percentage) % of \(price) $ = \(save) $")

print("\(save) $ of \(price) $ = \(save %? price) %")

...输出:

8.0 % of 45.0 $ = 3.6 $
3.6 $ of 45.0 $ = 8.0 %

我的问题如下:

您认为还有更优化和更易读的方法吗?

是吗?您能给出一些建议或分享一个例子吗?

【问题讨论】:

  • 您的代码似乎按预期工作。如果您正在寻找可能改进的评论和建议,请将其发布到 codereview.stackexchange.com
  • 我会的,谢谢你的建议。

标签: swift generics swift3


【解决方案1】:

首先,我对为此使用自定义运算符持怀疑态度。 个人我宁愿只用一个函数来做这个计算:

func percent(of partial: Double, from amount: Double) -> Double {
    return partial / amount * 100
}

percent(of: 50, from: 100)
// -> 50

我觉得这在长期(和短期)的可读性和可维护性方面会容易得多。

话虽如此...如果您真的想创建这些自定义运算符,我会按照以下方式进行操作。

你走在正确的道路上!你会得到错误:

二元运算符“*”不能应用于“NumericType”和“Double”类型的操作数

然后你走上了实现函数的道路,以便 * 和 / 运算符可以用于 NumericTypeDouble 类型。

但实际上,与其重新定义 * 和 / 的签名来处理新类型,不如找到一种方法从泛型类型中获取双精度值并在计算中使用它会容易得多。

它的外观如下:

protocol NumericType {
    var doubleValue: Double { get }
}

infix operator ¿%
infix operator %?

func ¿% <T: NumericType>(percentage: T, ofTotal: Double) -> Double {
    return percentage.doubleValue * ofTotal / 100.0
}

func %? <T: NumericType>(segment: T, ofTotal: Double) -> Double {
    return segment.doubleValue * 100 / ofTotal
}

extension Double: NumericType {
    var doubleValue: Double { return self }
}

extension Int: NumericType {
    var doubleValue: Double { return Double(self) }
}

希望这会有所帮助,请重新考虑使用标准函数而不是这些自定义运算符!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-03
    • 1970-01-01
    • 1970-01-01
    • 2018-03-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多