2014-07-12 62 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

相關問題