Override typecasting with custom operators

2019-09-03 09:58发布

问题:

Let say I have something like this:

var x: Int = 6
var y: Float = 11.5

so, the result has to be written like this

var result = Float(x) * y

or

var result = x * Int(y)

This makes sense, right ?
However, I think that a little clumsy, so I'm trying to make some custom operators for this:

infix operator *~ { associativity left precedence 150 } //floating

func *~ (lhs: Float, rhs: Int) -> Float {
    return lhs * Float(rhs)
}

func *~ (lhs: Int, rhs: Float) -> Float {
    return rhs * Float(lhs)
}


infix operator *| { associativity left precedence 150 } //Integer

func *| (lhs: Float, rhs: Int) -> Int {
    return Int(lhs) * rhs
}

func *| (lhs: Int, rhs: Float) -> Int {
    return Int(rhs) * lhs
}

It works but there are too many of them, so I'm trying to make a generic version for these functions. My attempt so far:

func *~ <T: FloatingPointType, V:IntegerType>(lhs: T, rhs: V) -> T {
    return lhs * T(rhs) 
    // error:
    // Could not find an overload for 'init' that accepts the supplied arguments
}

Can somebody help please ? Thank you.

回答1:

protocol Fraction {
    init(_ value: Double)
    var asDouble: Double { get }
}

extension Int     : Fraction { var asDouble : Double { return Double(self) } }
extension Double  : Fraction { var asDouble : Double { return self         } }
extension Float   : Fraction { var asDouble : Double { return Double(self) } }
extension CGFloat : Fraction { var asDouble : Double { return Double(self) } }

infix operator ** { associativity left precedence 170 }

func **(lhs:Int, rhs:Int) -> Int {
    return lhs * rhs
}
func **<T:Fraction, U:Fraction>(lhs:T, rhs:U) -> Double {
    return lhs.asDouble * rhs.asDouble

}

2 ** 2     // 4
2 ** 2.2   // 4.4
2.5 ** 2   //  5.0
2.2 ** 2.2 // 4.84


回答2:

What you are doing is more than counter productive.

What you are calling clumsy is preventing one of the biggest sources of errors. So you want to invest lots of time and work to undo this, and make your source code unreadable in the process.

Anybody ever getting hold of your source code will first spend hours undoing your work and turning everything into normal Swift code.