错误:' Int'不能转换为' @lvalue Float'

时间:2014-07-12 13:38:16

标签: struct swift lvalue

给出以下功能:

func greatestCommonDenominator(first: Int, second: Int) -> Int {
    return second == 0 ? first : greatestCommonDenominator(second, first % second)
}

结构中包含以下内容:

struct Fraction {
    var numerator: Int
    var denominator: Int

    func reduce() {
        let gcd = greatestCommonDenominator(numerator,denominator)
        self.numerator /= gcd
        self.denominator /= gcd
    }

    // stuff
}

我收到以下错误:

error: 'Int' is not convertible to '@lvalue Float'
       self.numerator /= gcd
           ^

error: 'Int' is not convertible to '@lvalue Float'
       self.denominator /= gcd
           ^

'@lvalue Float'?!?!?什么?我在这里的任何地方都没有Float。并且文档似乎建议/=应该返回Int,因为我将两个Int分开。我该如何解决这个问题?


ADDENDUM:我在一个结构中遇到了这个问题,但问题似乎在任何地方都可以重现。

let a = 10
a /= 5

这会产生同样的问题。即使我们明确地将a键入为Int

let a: Int = 10
a /= 5

同样的问题依然存在。 Swift似乎认为两个Ints之间的/=运算符的结果是Float。


编辑:附录的问题实际上并非a /= 5无法正常工作。它实际上确实!

var a: Int = 4
var b: Int = 3
a /= b

现在a是3.附录中的问题类似于结构。在附录中,a被声明为let而不是var,因此它是无法分配的。

1 个答案:

答案 0 :(得分:4)

如果您首先将功能更改为以下内容,则会收到更有用的错误消息:

func reduce() {
    let gcd = greatestCommonDenominator(numerator,denominator)
    self.numerator = self.numerator / gcd
    self.denominator = self.denominator / gcd
}

现在错误变为:

error: cannot assign to 'numerator' in 'self'
        self.numerator = self.numerator / gcd
        ~~~~~~~~~~~~~~ ^

对于我们这些来自Objective-C(或者没有RTFM)的人来说,显而易见的是,默认情况下,结构中的函数不允许更改结构的属性。你可以通过明确地将函数声明为变异函数来解决这个问题:

mutating func reduce() {
    let gcd = greatestCommonDenominator(numerator,denominator)
    self.numerator /= gcd
    self.denominator /= gcd
}

变异词解决了两个错误。

/=的情况下,错误非常神秘且无益。我将提交错误报告,并鼓励其他人也这样做。


编辑:此处的实际问题与结构或复合赋值运算符无关。

这里的问题与我们试图分配给无法分配的右值这一事实有关。在结构的情况下,rvalue是不可分配的,因为该函数未被声明为变异。对于let变量,它是无法分配的,因为let的工作原理。但错误信息仍然具有误导性和混乱性。错误应该通知我们rvalue是无法分配的,就像我们尝试在Objective-C中分配const一样,而不是建议可能存在类型不匹配。