Swift 二元运算符“+”不能应用于两个 CGFloat 操作数

Posted

技术标签:

【中文标题】Swift 二元运算符“+”不能应用于两个 CGFloat 操作数【英文标题】:Swift binary operator '+' cannot be applied to two CGFloat operands 【发布时间】:2015-08-21 01:21:11 【问题描述】:

我正在用 Swift 编写一个函数来检测我点击的是哪个六边形。但是我遇到了一条特殊的错误消息,指出我无法添加两个 CGFloat。无论我做什么,例如将let 更改为var,分别声明和分配,不起作用。我想肯定有其他问题,但我找不到它。代码如下:

func pointToCoordinate(position: CGPoint) -> (Int, Int) 
        var gridHeight = 2 * singleRadius / sqrt(CGFloat(3)) * 1.5
        var gridWidth = 2 * singleRadius
        var halfWidth = singleRadius

        var relativePosition = CGPoint(x: position.x - totalRadius / 2, y: position.y - totalRadius / 2)
        println((relativePosition.y / gridHeight))
        var row = -(cgfloatToInt)(relativePosition.y / gridHeight)
        var column: Int

        println((relativePosition.x + halfWidth * CGFloat(row + 1)) / (gridWidth))
        column = cgfloatToInt((relativePosition.x + halfWidth * CGFloat(row + 1)) / (gridWidth))

//        var innerY: CGFloat = CGFloat(relativePosition.y) + CGFloat(gridHeight * row)
        var innerX = relativePosition.x
        var innerY = relativePosition.y

        innerY = innerY - CGFloat(gridHeight * row)

        println((innerX, innerY))
        return (column, row)
    

【问题讨论】:

【参考方案1】:

查看所有答案、强制转换、转换和扩展,我认为目前对 Swift 最好的解决方案是 运算符重载。下面是 Swift 3.0 的代码示例:

/// overloads -/+ between a cgfloat on the left and an int/double on the right
func - (left: CGFloat, right: Double) -> CGFloat 
    return left - CGFloat(right);


func - (left: CGFloat, right: Int) -> CGFloat 
    return left - CGFloat(right);


func + (left: CGFloat, right: Double) -> CGFloat 
    return left + CGFloat(right);


func + (left: CGFloat, right: Int) -> CGFloat 
    return left + CGFloat(right);

把它放到任何类的全局位置OUTSIDE。看看魔法发生了。

【讨论】:

【参考方案2】:

迟到了。根据 vacawama 的回答,大家都知道问题出在数据类型不一样。CGFloat 有时需要多次写入。我通过扩展发现这更容易。所以分享一个答案。您可以创建一个简单的扩展,如下所示。当然,这个扩展还可以进一步修改。

import CoreGraphics
extension Int 
    var cgf: CGFloat  return CGFloat(self) 
    var f: Float  return Float(self) 


extension Float 
    var cgf: CGFloat  return CGFloat(self) 


extension Double 
    var cgf: CGFloat  return CGFloat(self) 


extension CGFloat 
    var f: Float  return Float(self) 

现在我们可以写了

innerY = innerY - gridHeight * row.cgf

【讨论】:

【参考方案3】:

错误信息是错误的。问题是您试图将IntCGFloat 相乘。

替换:

innerY = innerY - CGFloat(gridHeight * row)

与:

innerY = innerY - gridHeight * CGFloat(row)

以上答案适用于您的代码的当前版本。对于与您发布的错误消息相对应的注释掉的版本:

替换:

var innerY: CGFloat = CGFloat(relativePosition.y) + CGFloat(gridHeight * row)

var innerY: CGFloat = CGFloat(relativePosition.y) + gridHeight * CGFloat(row)

【讨论】:

"The error message is wrong" 对于 Xcode 8/Swift 3 中的同一消息仍然非常相关。 @SpaceDog 我发现 Swift 编译器错误从告诉您需要知道的内容开始,准确但仅对编译器编写者有帮助,而且完全是错误的。这个案子完全错了。 @vacawama - 我刚才是通过将 CGFloat 添加到 Float 的,错误消息是“二元运算符 + 不能应用于 CGFloat”,这是一条废话消息。正确的信息必须是“你不能添加 CGFloats 和 Floats”。二元运算符是一个令人困惑的术语,因为您会想到二元运算。我从 2008 年开始创建应用程序。我从未见过一条 Xcode 错误消息指出正确的问题。它们都是为了造成最大的痛苦而创造的。【参考方案4】:

确实,还有其他问题,这行得通:

import QuartzCore

let a:CGFloat = 1
let b:CGFloat = 2

let c = a + b
var innerY: CGFloat = CGFloat(1.0) + CGFloat(2.0)

CGFloat 实现了FloatingPointType 类型

【讨论】:

以上是关于Swift 二元运算符“+”不能应用于两个 CGFloat 操作数的主要内容,如果未能解决你的问题,请参考以下文章

解析 / Swift 问题与 tableviewcell“二元运算符'=='不能应用于单元格和 nil 类型的操作数”

Swift 3:二元运算符不能应用于 int 和“Int”类型的操作数?

二元运算符“==”不能应用于“字符串?”类型的操作数和 Swift 3 中的“布尔”

二元运算符“==”不能应用于“布尔”和“字符串?”类型的操作数对于 2020 年的 Swift [重复]

二元运算符“===”不能应用于“任何?”类型的操作数和“UIBarButtonItem!”

NSError 代码检查:二元运算符“==”不能应用于两个 Int 操作数