【问题标题】:Initialise property wrapper with dynamic values in Swift 5在 Swift 5 中使用动态值初始化属性包装器
【发布时间】:2020-02-26 11:07:35
【问题描述】:

场景:

  1. 我想要不同类型的具有最小值的债券, 弹性利息当前债券价值(根据一些逻辑计算)和债券增长预测。

  2. 无论何时债券价值 超过最小值,则增长预测变为 升值和贬值,反之亦然。

  3. 我可以有多个 与他们自己的价值观联系在一起。

我正在尝试使用相同的属性包装器,这样我就不会为每个键复制相同的行为:

 @propertyWrapper
struct BondValue {
    private var bondCurrentWorth: Int
    private var minimumValue: Int
    private var flexiInterest: Int

    var projectedValue: BondGrowth = .appreciating // The projected value projects the growth for the bond

    var wrappedValue: Int {

        get {
            return bondCurrentWorth
        }

        set {
            bondCurrentWorth = newValue + (newValue * flexiInterest/100)
            projectedValue = bondCurrentWorth < minimumValue ? .depriciating : .appreciating
        } 
 }

    init(wrappedValue: Int = 0, minimumValue: Int, flexiInterest: Int, value: Int) {
        self.minimumValue = minimumValue
        self.flexiInterest = flexiInterest
        self.bondCurrentWorth = value
    }
}

不要建立任何联系,我愿意:

struct FoodBond {
    var bondName: String
    @BondValue(minimumValue: 200, flexiInterest: 30, value: 200) var value = 30

    init(bondName: String, minimumValue: Int, flexiInterest: Int, value: Int) {
        self.bondName = bondName
    }
}

问题陈述: - 我无法用动态值初始化键值。

可能的解决方法: 在下面的实现中,我将使用与普通结构相同的方法。虽然在文档中也指定了这种使用属性包装器的方式,但我会失去属性包装器的语法风格。

您可以编写使用属性包装器行为的代码, 不利用特殊的属性语法。例如, 这是之前代码清单中 SmallRectangle 的一个版本 将其属性显式包装在 TwelveOrLess 结构中,而不是 将@TwelveOrLess 写为属性

@propertyWrapper
struct BondValue {
    private (set) var bondCurrentWorth: Int
    private (set) var minimumValue: Int
    private (set) var flexiInterest: Int

    var projectedValue: BondGrowth = .appreciating // The projected value projects the growth for the bond

    var wrappedValue: Int { .... }

    init(wrappedValue: Int = 0, minimumValue: Int, flexiInterest: Int, value: Int) { ... }
}

struct FoodBond {
    var bondName: String
    var value = BondValue(minimumValue: 0, flexiInterest: 0, value: 0) // Provide a default value

    init(bondName: String, minimumValue: Int, flexiInterest: Int, value: Int) {
        self.bondName = bondName
        self.value = BondValue(minimumValue: minimumValue, flexiInterest: flexiInterest, value: value)
    }
}

var foodBond = FoodBond(bondName: "Food Bond", minimumValue: 200, flexiInterest: 10, value: 200)
print("Initial bond current worth - \(foodBond.value.bondCurrentWorth)")
print("Bond growth - \(foodBond.value.projectedValue)")

任何建议都会很有帮助。

【问题讨论】:

    标签: ios properties wrapper swift5.1


    【解决方案1】:

    请参阅 Swift 提案文档中关于属性包装器的 Memberwise Initialisers 部分:

    具有属性包装器的实例属性将具有 成员初始化器中的相应参数,其类型将 可以是原始属性类型或包装器类型,具体取决于 包装器类型和初始值(如果提供)。

    解决方案:

    struct FoodBond {
        var bondName: String
    
        @BondValue(minimumValue: 0, flexiInterest: 0, value: 0) var bondValue = 0
    
        init(bondName: String, minimumValue: Int, flexiInterest: Int, value: Int) {
            self.bondName = bondName
            _bondValue = BondValue(minimumValue: minimumValue, flexiInterest: flexiInterest, value: value)
        }
    }
    

    【讨论】:

      【解决方案2】:

      您可以使用不带参数的属性包装器,并为其指定包装值的类型,然后使用您的参数在 init 中创建它:

      struct FoodBond {
          var bondName: String
      
          @BondValue var bondValue : Int
      
          init(bondName: String, minimumValue: Int, flexiInterest: Int, value: Int) {
              self.bondName = bondName
              _bondValue = BondValue(minimumValue: minimumValue, flexiInterest: flexiInterest, value: value)
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-11-25
        • 1970-01-01
        • 2020-06-18
        • 1970-01-01
        • 2020-03-05
        • 2013-03-17
        • 2021-12-22
        • 1970-01-01
        相关资源
        最近更新 更多