Использование свойства в качестве значения по умолчанию для метода в том же классе

В классе Swift я хочу использовать свойство как значение параметра по умолчанию для метода того же класса.

Вот мой код:

class animal {
    var niceAnimal:Bool
    var numberOfLegs:Int

    init(numberOfLegs:Int,animalIsNice:Bool) {
        self.numberOfLegs = numberOfLegs
        self.niceAnimal = animalIsNice
    }

    func description(animalIsNice:Bool = niceAnimal,numberOfLegs:Int) {
        // I'll write my code here
    }
}

Проблема заключается в том, что я не могу использовать свойство niceAnimal в качестве значения функции по умолчанию, потому что он вызывает ошибку времени компиляции:

'animal.Type' не имеет члена с именем 'niceAnimal'

Я делаю что-то неправильно? Или это невозможно в Swift? Если это невозможно, вы знаете, почему?

Ответ 1

Я не думаю, что вы делаете что-то неправильно.

В спецификации языка указано, что перед параметрами, отличными от параметров по умолчанию (p169), должен использоваться параметр по умолчанию, а значение по умолчанию определяется выражением (p637).

Он не говорит, что это выражение разрешено ссылаться. Похоже, что не разрешается ссылаться на экземпляр, на который вы вызываете метод, т.е. Self, который, похоже, должен ссылаться на self.niceAnimal.

В качестве обходного пути вы можете определить параметр по умолчанию как необязательный со значением по умолчанию nil, а затем установить фактическое значение с помощью "if let", который ссылается на переменную-член в случае по умолчанию, например:

 class animal {
     var niceAnimal:Bool
     var numberOfLegs:Int

     init(numberOfLegs:Int,animalIsNice:Bool) {
         self.numberOfLegs = numberOfLegs
         self.niceAnimal = animalIsNice
     }

     func description(numberOfLegs:Int,animalIsNice:Bool? = nil) {
       if let animalIsNice = animalIsNice ?? self.niceAnimal {
         // println

       }
     }
 }

Ответ 2

Думаю, на данный момент вы можете использовать только литералы и свойства типа в качестве аргументов по умолчанию.

Лучшим вариантом было бы перегрузить метод, и вы можете реализовать более короткую версию, вызвав ее полную. Я использовал только конструкцию, чтобы опустить инициализатор.

struct Animal {

    var niceAnimal: Bool
    var numberOfLegs: Int

    func description(#numberOfLegs: Int) {
        description(niceAnimal, numberOfLegs: numberOfLegs)
    }

    func description(animalIsNice: Bool, numberOfLegs: Int) {
        // do something
    }

}