Переменная p передается по ссылке перед ее инициализацией

У меня есть класс Human с функцией, которая принимает любое количество людей и определяет, является ли кто-то старше любого из этих людей, а затем возвращает массив с людьми, которых он старше.

func isOlderThan(people: Human...) -> [Human] {
    var p: [Human]

    for person in people {
        if age > person.age {
            p.append(person)
        }
    }
    return p
}

Однако при

p.append(person)

Я получаю сообщение об ошибке

Variable p passed by reference before being initialized

Кто-нибудь уверен, почему это? Спасибо!

Ответ 1

Ваше объявление p - это просто объявление. Вы не инициализировали его. Вам нужно изменить его на

var p = [Human]()

Или, как указывает @MartinR,

var p: [Human] = []

Существуют и другие эквивалентные конструкции, но важно то, что вы должны назначить что-то объявленной переменной (в обоих случаях здесь пустой массив, который будет принимать члены Human).

Обновление Для полноты вы также можете использовать:

var p: Array<Human> = []

или

var p = Array<Human>()

Ответ 2

Вам лучше просто использовать метод filter:

func isOlderThan(people: Human...) -> [Human] {
  return people.filter { self.age > $0.age }
}

Он работает следующим образом:

 20> class Human {
 21.     let age : Int
 22.     init (age: Int) { self.age = age }
 23.     func isOlderThan (people: Human...) -> [Human] {
 24.         return people.filter { self.age > $0.age }
 25.     }
 26. }

 28> let me = Human(age:27)
me: Human = {
  age = 27
}

 29> me.isOlderThan (Human(age:25), Human(age:30))
$R10: [Human] = 1 value {
  [0] = {
    age = 25
  }
}

Кстати, скоро вам будет полезно определить дополнительный метод, указанный как:

func isOlderThan(people: [Human]) -> [Human] { ... }

поскольку, как только у вас есть массив, и поскольку в Swift нет метода apply, ваш исходный метод не будет работать.

Ответ 3

append является mutating методом struct Array.

Вы можете рассматривать метод struct как функцию со скрытым параметром self. По умолчанию параметры для функций являются константами, и поэтому вы не можете сделать ничего, что вы не можете сделать с константой. Метод mutating struct должен делать то, что нельзя сделать с константой, поэтому он должен принимать параметр self как inout, то есть как если бы он передавался по ссылке. Таким образом, вы можете вызвать метод mutating только на том, что вы можете передать по ссылке. И вы не можете передать неинициализированную переменную по ссылке.