如果一个变异函数的自身设置等于另一个函数,那是什么意思

时间:2019-07-03 08:39:42

标签: ios swift xcode arkit

我正在查看Apple的Arkit项目示例。自从我一直在学习以来,我一直试图理解代码。我看到一个将其自身设置为等于另一个功能的功能,有人可以解释一下这些功能到底在做什么。请详细介绍一下。在代码中,“ muting func normalize()”将self设置为self.normalized,这是为什么。这段代码在做什么。我们能不能简单地调用“ func normalized()”,好像我们正在重新创建相同的函数。

mutating func normalize() {

   self = self.normalized()
}


func normalized() -> SCNVector3 {

    if self.length() == 0 {
      return self
  }
    return self / self.length()
}



func length() -> CGFloat {

    return sqrt(self.x * self.x + self.y * self.y)

    }

2 个答案:

答案 0 :(得分:1)

Swift中的值类型可以是可变的和不可变的。因此,当您创建struct(或任何其他值类型)并将其分配给变量(var)时,它是可变的,您可以对其调用normalize()。这意味着该结构不会被复制到另一个内存中,而是会在适当位置进行更新(就像引用类型一样)。但是,当您将其分配给常量(let)时-无法对其进行更改,因此,在此结构中更新值的唯一方法是使用normalized()方法创建具有更新值的新值。关于您的问题-normalize()只是重用逻辑来标准化normalized()中的向量。因此,这是完全好的解决方案。仅在可变方法中允许分配给self。基本上是用新的重写struct的值。

答案 1 :(得分:0)

我假设此片段位于struct中,而不是类中。

self.normalized()制作self的副本,并按其长度除以副本的组成部分,然后返回副本。 self不受影响。

self.normalize()得到self的规范化版本,然后用副本替换self。所以它改变了。

在幕后,每个成员函数都将self作为隐式参数传递。也就是说,对于编译器,声明如下所示:

func normalised(self: SCNVector3) -> SCNVector3

mutating放在函数定义的前面将使隐藏参数inout

func normalise(self: inout SCNVector3)

所以,如果有

var a = SCNVector3(3, 4, 0)
let b = SCNVector3(4, 3, 0)
let c = b.normalized() 
a.normalize()

在该代码之后,c将是(0.8, 0.6, 0),而a将是(0.6, 0.8, 0)b将保持不变。

请注意,a必须用var声明,因为它已由normalise()更改了位置

修改

可汗在评论中问:

  

我无法理解的是为什么我们必须再次创建一个可以使用“ func normalized”的功能

要指出的是为什么我们不能做这样的事情:

    var a = SCNVector3(3, 4, 0)
    a = a.normalized()

完全没有normalise()功能吗?

以上内容与a.normalize()具有完全相同的效果,我认为[1]是更好的样式,更“实用”。

我认为a.normalize()存在仅是因为在Swift中同时提供两种形式的函数是很常见的。例如,对于集合,您同时拥有union()formUnion():第一个返回一个集合与另一个集合的并集,第二个返回一个集合与它本身和另一个集合的并集。在某些情况下,该功能的就地版本可能更有效,但我认为不能使用此normalize函数。

您选择使用哪种取决于您的偏好。


[1]实际上,更好的样式是

let a = SCNVector3(3, 4, 0).normalized()