使用属性作为同一类中方法的默认参数值

Tre*_*vör 14 swift

在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
    }
}
Run Code Online (Sandbox Code Playgroud)

问题是我不能将我的niceAnimal属性用作默认函数值,因为它触发了我一个编译时错误:

'animal.Type'没有名为'niceAnimal'的成员

难道我做错了什么 ?或者在Swift中是不可能的?如果那是不可能的,你知道为什么吗?

alg*_*gal 10

我不认为你做错了什么.

语言规范仅表示默认参数应在非默认参数之前(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 {
         // print
       }
     }
 }
Run Code Online (Sandbox Code Playgroud)

  • 我不确定.我认为默认参数值是一个很好的方便,但它们也可能导致关于何时评估默认表达式的令人惊讶和复杂的极端情况.我知道它在Python中变得混乱.所以我可以看到保持它明确和有限的美德.我认为解决方法并不是那么糟糕. (2认同)
  • 是.考虑:如果默认值表达式是在实例的上下文中计算的(即,具有引用self的能力),那么它的行为几乎就像在您尝试的实例方法之前调用的完全独立的实例方法呼叫.可以访问私人会员吗?超级成员?这不是一个不可能的设计,但它可能隐藏了意想不到的惊喜. (2认同)
  • 注意,这里不需要使用`if let`(甚至不在Swift 3中编译),因为`niceAnimal`是非可选的,因此`??`将产生一个非可选的.只要说'让animalIsNice = animalIsNice ?? self.niceAnimal`. (2认同)