因此,我正在编写一个低通加速度计函数来缓和加速度计的抖动。我有一个CGFloat数组来表示数据,我想用这个函数来衰减它:

// Damps the gittery motion with a lowpass filter.
func lowPass(vector:[CGFloat]) -> [CGFloat]
{
    let blend:CGFloat = 0.2

    // Smoothens out the data input.
    vector[0] = vector[0] * blend + lastVector[0] * (1 - blend)
    vector[1] = vector[1] * blend + lastVector[1] * (1 - blend)
    vector[2] = vector[2] * blend + lastVector[2] * (1 - blend)

    // Sets the last vector to be the current one.
    lastVector = vector

    // Returns the lowpass vector.
    return vector
}

在这种情况下,lastVector在程序顶部定义如下:
var lastVector:[CGFloat] = [0.0, 0.0, 0.0]

vector [a] = ...形式的三行给了我错误。关于为什么我会收到此错误的任何想法?

最佳答案

如果使用inout修饰符传递数组,则该代码似乎可以编译:

func lowPass(inout vector:[CGFloat]) -> [CGFloat] {
    ...
}

我不确定这是否是错误。本能地,如果我将数组传递给函数,则希望能够对其进行修改。如果我使用inout修饰符传递,我希望能够使原始变量指向新数组-类似于&修饰符在C和C++中的作用。

也许背后的原因是,在Swift中,存在可变且不可变的数组(和字典)。没有inout,它被认为是不可变的,因此不能修改它的原因。

附录1-不是bug

@newacct说这是预期的行为。经过一番研究,我同意他的看法。但是,即使不是错误,我最初也认为它是错误的(请仔细阅读最后的结论)。

如果我有这样的 class :
class WithProp {
    var x : Int = 1

    func SetX(newVal : Int) {
        self.x = newVal
    }
}

我可以将该类的实例传递给函数,并且该函数可以修改其内部状态
var a = WithProp()

func Do1(p : WithProp) {
    p.x = 5 // This works
    p.SetX(10) // This works too
}

无需将实例作为inout传递。
我可以改用inout来使a变量指向另一个实例:
func Do2(inout p : WithProp) {
    p = WithProp()
}

Do2(&a)

使用该代码,我从Do2中使p参数(即a变量)指向新创建的WithProp实例。

数组不能做同样的事情(我也假定字典)。要更改其内部状态(修改,添加或删除元素),必须使用inout修饰符。那是违反直觉的。

但是从速成书中阅读this excerpt之后,一切都变得清晰了:

Swift的String,Array和Dictionary类型实现为结构。这意味着将字符串,数组和字典分配给新的常量或变量,或者将它们传递给函数或方法时,将对其进行复制。

因此,当传递给函数时,它不是原始数组,而是它的一个副本-因此,对它所做的任何更改(即使可能)也不会在原始数组上进行。

因此,最后,我上面的原始答案是正确,经验丰富的行为是而不是bug

非常感谢@newacct :)

关于ios - 接受数组错误的Swift函数:“@ lvalue $ T24”与“CGFloat”不同,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24707245/

10-12 00:08
查看更多