2014-07-12 23 views
4

鉴于以下功能:错误:“诠释”是无法转换为“@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 s分开。我该如何解决?


附录:我碰到这个问题一个结构中工作,但是这个问题似乎重现的任何地方。

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,因此它是不可分配的。

+0

注意那里的三元运算符 - 两个可选的数据类型被转换为相同的类型。我记得那些运营商导致不寻常的错误的一些codepuzzlers。我觉得你应该在这里摆脱它,并用更长的声明替换它。 – Johannes

+0

我很困惑你的评论。我在这里使用三元运算符时是否存在特定的问题,或者您是否总体上对它提出警告? – nhgrif

+0

我一般都很警惕,如果这里有问题,我无知。我认为第一个和最好的CommonDenominator的数据类型是不同的。可能会有一些幕后的演员正在进行编译,但打破了内联功能。在测试中困难的地方可能是一个问题。这不是你的代码中的问题,但我已经对它做了评论。代码中的问题与'/ ='有关......如果你把它写成= =(int)(a/b),它可能会消失。 – Johannes

回答

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 
} 

该变异词解决了这两个错误。

/=的情况下,该错误是相当神秘且无益的。我将提交一份错误报告,并鼓励其他人也这样做。


编辑:这里真正的问题无关,与结构或复合赋值运算符。

这里的问题与我们试图分配一个不可分配的右值有关。在结构的情况下,右值是不可分配的,因为该函数没有声明为变异。在let变量的情况下,它是不可分配的,因为这是let的工作原理。错误信息仍然令人误解和困惑。与提示可能存在类型不匹配相比,错误应该告诉我们右值不可分配,就像我们试图在Objective-C中分配const一样。

+0

啊 - 应该先读一下:) – Johannes

相关问题