Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Struct 错误:';Int';不可转换为'@左值浮动';_Struct_Swift_Lvalue - Fatal编程技术网

Struct 错误:';Int';不可转换为'@左值浮动';

Struct 错误:';Int';不可转换为'@左值浮动';,struct,swift,lvalue,Struct,Swift,Lvalue,鉴于以下功能: func greatestCommonDenominator(first: Int, second: Int) -> Int { return second == 0 ? first : greatestCommonDenominator(second, first % second) } mutating func reduce() { let gcd = greatestCommonDenominator(numerator,denominator)

鉴于以下功能:

func greatestCommonDenominator(first: Int, second: Int) -> Int {
    return second == 0 ? first : greatestCommonDenominator(second, first % second)
}
mutating func reduce() {
    let gcd = greatestCommonDenominator(numerator,denominator)
    self.numerator /= gcd
    self.denominator /= gcd
}
以及一个包含以下内容的结构:

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”
?!?!?什么?我这里没有浮子。文档似乎建议
/=
应该返回一个
Int
,因为我正在除以两个
Int
s。我该如何解决这个问题


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

let a = 10
a /= 5
这将产生同样的问题。即使我们将
a
显式输入为
Int

let a: Int = 10
a /= 5
同样的问题依然存在。斯威夫特似乎认为两个整数之间的
/=
运算符的结果是浮点


编辑:附录的问题实际上并不是
a/=5
不起作用。事实上是的

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

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

如果您开始将函数更改为以下内容,您会得到一条更有用的错误消息:

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)的人来说,可能不太明显的是,默认情况下,结构中的函数不允许更改结构的属性。您可以通过将函数显式声明为变异函数来解决此问题:

func greatestCommonDenominator(first: Int, second: Int) -> Int {
    return second == 0 ? first : greatestCommonDenominator(second, first % second)
}
mutating func reduce() {
    let gcd = greatestCommonDenominator(numerator,denominator)
    self.numerator /= gcd
    self.denominator /= gcd
}
变异词解决了这两个错误

/=
的情况下,该错误非常隐晦且没有帮助。我将提交一份bug报告,并鼓励其他人也这样做


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


这里的问题与我们试图分配给一个不可分配的右值有关。在结构的情况下,右值是不可分配的,因为函数没有声明为mutating。对于
let
变量,它是不可分配的,因为
let
就是这样工作的。然而,错误消息仍然具有误导性和迷惑性。与其说可能存在类型不匹配,不如说错误告诉我们右值是不可分配的,就像我们试图在Objective-C中分配一个
const
一样。

小心那里的三元运算符——两个可选数据类型被强制转换为同一类型。我记得有几个代码拼图游戏,那个操作员导致了不寻常的错误。我觉得你应该在这里把它去掉,换成一个较长的声明。你的评论让我感到困惑。我在这里使用三元运算符有什么特别的问题吗,或者你只是在一般情况下对它提出警告?我在一般情况下对它提出警告,我不知道这是否是一个问题。我认为第一个和最大公分母的数据类型是不同的。在正在进行的带香味的角色转换背后,可能有一些编译但破坏了intendet功能。在测试过程中,很难确定可能存在问题的情况。但这不是代码中的问题,所以我对其进行了评论。代码中的问题与“/=”有关。。。如果你把它写成a=(int)(a/b),它可能会消失。它们都是
int
数据类型。递归调用该函数。施法并不能消除错误——它只是改变了错误。“Float”消息是我刚刚报告的一个误导性错误
greatestcommondenomator
是一个函数,它接受两个
Int
并返回一个
Int
。我可以看到它是什么,因为这是一个标准实现。我仍然不太确定那个操作员的确切行为。一个是Int,另一个是返回Int的函数调用。这足以让我避免使用运算符。有趣的是,演员阵容没有改变它,我将跟随这个问题,看看还有什么其他答案。