DSh*_*aar 1 arrays cgfloat ios swift
所以我正在写一个低通加速度计功能来缓和加速度计的抖动.我有一个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
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,lastVector在我的程序顶部定义如下:
var lastVector:[CGFloat] = [0.0, 0.0, 0.0]
Run Code Online (Sandbox Code Playgroud)
形式vector [a] = ...中的三行给出了错误.有关为什么我收到此错误的任何想法?
如果使用inout修饰符传递数组,那么代码似乎会编译:
func lowPass(inout vector:[CGFloat]) -> [CGFloat] {
...
}
Run Code Online (Sandbox Code Playgroud)
我不确定这是不是一个错误.本能地,如果我将数组传递给函数,我希望能够修改它.如果我使用inout修饰符,我希望能够使原始变量指向一个新数组 - 类似于&修饰符在C和C++中的作用.
也许后面的原因是在Swift中有可变和不可变的数组(和字典).没有inout它被认为是不可变的,因此它无法被修改的原因.
附录1 - 这不是一个错误
@newacct说这是预期的行为.经过一番研究,我同意他的观点.但即使不是我最初认为错误的错误(读到最后得出结论).
如果我有这样的课程:
class WithProp {
var x : Int = 1
func SetX(newVal : Int) {
self.x = newVal
}
}
Run Code Online (Sandbox Code Playgroud)
我可以将该类的实例传递给函数,该函数可以修改其内部状态
var a = WithProp()
func Do1(p : WithProp) {
p.x = 5 // This works
p.SetX(10) // This works too
}
Run Code Online (Sandbox Code Playgroud)
无需传递实例inout.我可以使用它inout来使a变量指向另一个实例:
func Do2(inout p : WithProp) {
p = WithProp()
}
Do2(&a)
Run Code Online (Sandbox Code Playgroud)
使用该代码,从内部Do2我使p参数(即a变量)指向新创建的实例WithProp.
使用数组也不能这样做(我也假设一个字典).要更改其内部状态(修改,添加或删除元素),inout必须使用修饰符.这是违反直觉的.
但是从这本快速的书中读到这段摘录后,一切都得到澄清:
Swift的String,Array和Dictionary类型实现为结构.这意味着字符串,数组和字典在分配给新常量或变量时或者传递给函数或方法时会被复制.
因此,当传递给func时,它不是原始数组,而是它的副本 - 因此对它进行的任何更改(即使可能)都不会在原始数组上完成.
所以,最后,我上面的原始答案是正确的,经验丰富的行为不是错误
非常感谢@newacct :)
从Xcode 6 beta 3开始,修改an的内容Array是一种变异操作.你不能修改常量(即let)数组; 你只能修改一个非常数(即var)数组.
默认情况下,函数的参数是常量.因此,您无法修改内容,vector因为它是常量.与其他参数一样,有两种方法可以更改参数:
var,在这种情况下您可以分配它,但它仍然按值传递,因此对参数的任何更改都不会影响调用范围.inout,在这种情况下参数通过引用传递,并且对参数的任何更改就像您对调用范围中的变量进行了更改一样.您可以在Swift标准库中看到所有采用Array并对其进行变异的函数,例如sort(),将Array作为inout.
PS这就像数组如何在PHP中工作一样