【发布时间】:2015-01-26 05:35:02
【问题描述】:
目标
我(像网络上的许多其他人一样)希望在 CGFloat 数学中使用 Int 变量和文字,因为到目前为止可读性和易于开发超过了可能的精度损失。当您在整个应用程序中使用手动布局而不是使用情节提要时,这一点最为明显。
因此,以下内容无需任何手动 CGFloat 强制转换即可工作:
let a = CGFloat(1)
let b = Int(2)
let c = a / b // Cannot invoke / with an arguments list of type (CGFloat, Int)
let d = b / a // Cannot invoke / with an arguments list of type (Int, CGFloat)
let e = a / 2 // => CGFloat(0.5)
let f = 2 / a // => CGFloat(2.0)
let g = 2 / b // => Int(1)
let h = b / 2 // => Int(1)
let i = 2 / 2 // => Int(1)
let j: CGFloat = a / b // Cannot invoke / with an arguments list of type (CGFloat, Int)
let k: CGFloat = b / a // Cannot invoke / with an arguments list of type (Int, CGFloat)
let l: CGFloat = a / 2 // => CGFloat(0.5)
let m: CGFloat = 2 / a // => CGFloat(2.0)
let n: CGFloat = 2 / b // Cannot invoke / with an arguments list of type (IntegerLiteralConvertible, Int)
let o: CGFloat = b / 2 // Cannot invoke / with an arguments list of type (Int, IntegerLiteralConvertible)
let p: CGFloat = 2 / 2 // => CGFloat(1.0)
方法
由于我们无法为 Swift 类型添加隐式转换,我必须添加适当的运算符,它们采用 CGFloat 和 Int。
func / (a: CGFloat, b: Int) -> CGFloat { return a / CGFloat(b) }
func / (a: Int, b: CGFloat) -> CGFloat { return CGFloat(a) / b }
问题
当 Swift 试图从整数文字隐式创建 CGFloat 值时,这两个运算符变得模棱两可。它不知道要转换两个操作数中的哪一个(例如p)。
let a = CGFloat(1)
let b = Int(2)
let c = a / b // => CGFloat(0.5)
let d = b / a // => CGFloat(2.0)
let e = a / 2 // => CGFloat(0.5)
let f = 2 / a // => CGFloat(2.0)
let g = 2 / b // => Int(1)
let h = b / 2 // => Int(1)
let i = 2 / 2 // => Int(1)
let j: CGFloat = a / b // => CGFloat(0.5)
let k: CGFloat = b / a // => CGFloat(2.0)
let l: CGFloat = a / 2 // => CGFloat(0.5)
let m: CGFloat = 2 / a // => CGFloat(2.0)
let n: CGFloat = 2 / b // => CGFloat(1.0)
let o: CGFloat = b / 2 // => CGFloat(1.0)
let p: CGFloat = 2 / 2 // Ambiguous use of operator /
问题
有没有什么方法可以用没有歧义且所有测试用例都成功的方式来声明操作符?
【问题讨论】:
-
我建议不要创建这些运算符并明确地向你想要投射的方向进行投射......为了将来维护你认为这个运算符会改进的任何代码。
-
@nhgrif 是什么原因?
-
@nhgrif 当您彻底命名变量时,代码完全可读,无需显式转换。当公式被强制转换污染时,它的可读性会降低。
.height = (100 * views.count) + 100完全没问题,.height = (100 * CGFloat(views.count)) + 100完全没必要。 -
无论你在那里做什么,你都应该使用自动布局...
-
@nhgrif 如果我想快速开发并保持应用程序性能,请不要这样做。无论如何,这两个讨论都是题外话。 Swift 应该是可扩展的,但这种能力在这里被破坏了——很可能是由于一个错误。
标签: swift casting implicit-conversion implicit-typing