可以在Swift`struct中设置“计算常量”吗?

时间:2017-05-24 22:45:26

标签: swift

为了方便命名常量,我想在Swift中执行以下操作(我的实际情况不那么简单),所以我可以在后面的代码中引用IntegerConstants.SIX。但是,SIX无法获得值,因为ONETWOstruct初始化之前没有值..“Catch-22”的位数

struct IntegerConstants {
   let ONE = 1.0
   let TWO = 2.0
   let SIX = (ONE + TWO) * TWO
}

有没有办法做到这一点,或者是一个创建“GROUP.VALUE”形式的命名常量的等价物,我还没有发现?

3 个答案:

答案 0 :(得分:3)

如果你使用它来分组常量,就像使用IntegerConstants.six一样,你真正想要做的就是让它们成为静态的。这也解决了您的错误,因为您不需要访问self

struct IntegerConstants {
    static let one = 1
    static let two = 2
    static let six = (one + two) * two
}

答案 1 :(得分:2)

就我而言,你有两个(好的)选择。

  1. 使其成为计算属性。对于这种类型的事情来说这是很常见的,唯一的缺点是每次访问属性时都会进行计算,但只要它是cheep它就不应该是一个大问题。

    struct IntegerConstants {
        let ONE = 1.0
        let TWO = 2.0
        var SIX: Double {
           get { return (ONE + TWO) * TWO }
        }
    }
    
  2. 将结构外部的常量移动为全局。这与您想要的行为完全相同,但它会增加额外的常量。

    fileprivate let ONE_CONST = 1.0
    fileprivate let TWO_CONST = 2.0
    struct IntegerConstants {
        let ONE = ONE_CONST
        let TWO = TWO_CONST
        let SIX = (ONE_CONST + TWO_CONST) * TWO_CONST
    }
    

    fileprivate let ONE_CONST = 1.0
    fileprivate let TWO_CONST = 2.0
    fileprivate let SIX_CONST = (ONE_CONST + TWO_CONST) * TWO_CONST
    
    struct IntegerConstants {
        let ONE = ONE_CONST
        let TWO = TWO_CONST
        let SIX = SIX_CONST
    }
    

答案 2 :(得分:1)

您确定可以,但您需要在初始化程序中执行此操作:

struct IntegerConstants {
   let ONE = 1.0
   let TWO = 2.0
   let SIX: Double

   init() {
        SIX = (ONE + TWO) * TWO
    }
}

但是这段代码存在一些非常大的问题。

  1. IntegerConstants结构实际上包含Double s
  2. 这样的常量应该是静态的。它们没有理由绑定到实例。
  3. 鉴于此结构现在应该只包含静态成员,因此使它的实例没有多大意义,所以它应该切换到无大小写的枚举,这样就不会有任何实例。
  4. Swift遵循对UpperCamelCase使用静态成员和类型的约定。您应该遵循INSTEAD_OF_USING_YELLING_CASE
  5. IntegerConstants结构及其成员首先不应该存在。直接使用文字! IntegerConstants.SIX无法解决幻数问题。这只是说6的一种可怕方式。