### 运算比较 (01:06)

float   w = 5;
double  x = 10;
int     y = 15;

CGFloat z = w + x + y;

let w:Float  = 5
let x:Double = 10
let y:Int    = 15
let z:CGFloat = CGFloat(w) + CGFloat(x) + CGFloat(y)

### Swift 2.0 之前的版本 (01:31)

extension Double {
var c:CGFloat {
return CGFloat(self)
}
//. . .
}

extension Int {
var c:CGFloat {
return CGFloat(self)
}
//. . .
}

extension Float {
var c:CGFloat {
return CGFloat(self)
}
//. . .
}

//let y:CGFloat = 1 + x.c

### 数值转换是如何实现的？ (02:54)

init(_ v: Float ), init(_ v: Double)
let x: Float = 5.0
let y = Float(x) 或者 let y = Float.init(x)

CGFloat 有一点奇葩，它并没有定义在标准库当中——它是 Core Graphics 中的一部分。和标准库中的数字不同，它并没有初始化转换方法。不过幸运的是，我们可以简单创建一个扩展，然后使用 self = value 来添加初始化转换方法。

protocol NumberConvertible {
init (_ value: Int)
init (_ value: Float)
init (_ value: Double)
init (_ value: CGFloat)
}

extension CGFloat : NumberConvertible {}
extension Double  : NumberConvertible {}
extension Float   : NumberConvertible {}
extension Int     : NumberConvertible {}

extension CGFloat{
public  init(_ value: CGFloat){
self = value
}
}

### 模式匹配 (05:02)

switch self {
case let x as CGFloat:
print("x is a CGFloat")
case let x as Float:
print("x is a CGFloat")
case let x as Int:
print("x is a CGFloat")
case let x as Double:
print("x is a CGFloat")

default:
print("x is unknown..")
}

### 建立扩展 (05:56)

extension NumberConvertible {

private func convert<T: NumberConvertible>() -> T {
switch self {
case let x as CGFloat:
return T(x) //T.init(x)
case let x as Float:
return T(x)
case let x as Double:
return T(x)
case let x as Int:
return T(x)
default:
assert(false, "NumberConvertible convert cast failed!")
return T(0)
}
}
public var c:CGFloat{
return convert()
}
//...
}

### 不借助构造器实现转换 (07:29)

let w: Double = 4.4
let x: Int = 5
let y: Float = w.convert() + x.convert()

let x: Int = 5
let y: CGFloat = 10
let z: Double = x + y

func + <T:NumberConvertible, U:NumberConvertible, V:NumberConvertible>(lhs: T, rhs: U) -> V {
let v: Double = lhs.convert()
let w: Double = rhs.convert()
return (v + w).convert()
}

let x:Int     = 5
let y:CGFloat = 10
let z:Float   = 15

//`Float` is not convertible to `Double`
let res:Double = x + y + z

### 处理编译器 (10:51)

public typealias PreferredType = Double

public func + <T:NumberConvertible, U:NumberConvertible>(lhs: T, rhs: U) -> PreferredType
{
let v: PreferredType = lhs.convert()
let w: PreferredType = rhs.convert()
return v+w
}

### 优化运算符 (13:39)

extension NumberConvertible {
private typealias CombineType = (Double,Double) -> Double
private func operate<T:NumberConvertible,V:NumberConvertible>(b:T, @noescape combine:CombineType) -> V{
let x:Double = self.convert()
let y:Double =    b.convert()
return combine(x,y).convert()
}
}

public func + <T:NumberConvertible, U:NumberConvertible,V:NumberConvertible>(lhs: T, rhs: U) -> V {
return lhs.operate(rhs, combine: + )
}
public func - <T:NumberConvertible, U:NumberConvertible,V:NumberConvertible>(lhs: T, rhs: U) -> V {
return lhs.operate(rhs, combine: - )
}

### 问与答 (17:51)

Q：Swify 的 & 操作符明确指出了数字运算溢出的可能性。由于这种情况可能会导致数据丢失，我们是否应该使用其他的运算符来规避这种可能？

Rich: 这个主意很不错。我自己出于兴趣简单的实现了一下，但是处于可读性的考虑，这只是一个有待考虑的想法。

This content has been published here with the express permission of the author.

#### Richard Fox

Rich is an iOS Developer at Propeller Labs where he has been developing in Swift since the beginning of 2015. In January 2014, he moved to the Bay Area from Hangzhou, China, where he lived for four years while completing a master’s program in teaching Mandarin as a second language, studied the game of Go, and worked at Viva Video on an iOS video editing app. Currently obsessed with Swift 2.0, he tweets about it @RGfox, and blogs about it at foxinswift.com.

4 design patterns for a RESTless mobile integration »