数字类型具有通用类型约束的最佳自定义运算符 [英] Optimal Custom Operator with Generic Type Constraint for Numerical Type

查看:32
本文介绍了数字类型具有通用类型约束的最佳自定义运算符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm implementing (for an article) two custom infix operators:

  • ¿% - 计算总数的百分比.
  • %?- 计算代表总数的一部分的百分比.

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

After debugging some errors and looking for information I finally found a way to get my code working:

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 %

我的问题如下:

您认为还有更优化和可读性更好的方法吗?

Do you thinks there could be a more optimal and readable approach?

是吗?你能提供一些建议或分享一个例子吗?

Yes? Could you give some advice or share an example?

推荐答案

首先,我有点怀疑为此使用自定义运算符.个人我宁愿有一个函数来做这个计算:

First of all, I'm a little skeptical of using a custom operator for this. Personally I'd rather just have a functions that do this calculation:

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

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

我觉得从长期(和短期)来看,可读性和可维护性会容易得多.

I feel like that's going to be a lot easier in long (and short) term for readability and maintainability.

话虽如此...如果你真的想创建这些自定义运算符,我会这样做.

Having said that... If you do really want to create these custom operators here's how I'd approach it.

你走对了路!你会得到错误:

You were on the right path! you would have gotten the error:

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

binary operator '*' cannot be applied to operands of type 'NumericType' and 'Double'

并且您走上了实现函数的道路,以便 * 和/运算符可以用于 NumericTypeDouble 类型.

And you went down the path of implementing functions so that the * and / operators can be used on types NumericType and Double.

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

But actually, rather than redefining signatures for * and / to work on new types, it's going to be a lot easier to find a way to get a double value from your generic type and use that in the calculation.

可能的样子:

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) }
}

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

Hope this helps, and please please please reconsider using a standard function instead of these custom operators!

这篇关于数字类型具有通用类型约束的最佳自定义运算符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆