Я предполагаю, что этот фрагмент находится в 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()
Редактировать
В комментариях хан спрашивает:
Я не могу понять, почему мы должны снова создать функцию, мы можем использовать «нормализованную функцию»
Смысл в том, почему мы не можем сделать что-то вроде этого:
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()