Swift Generic Protocol Function Parameters

后端 未结 1 555
星月不相逢
星月不相逢 2021-01-25 10:36

This seems like it should work to me. All I am trying to do is make the Rule protocol able to performRule on whatever struct adopts that Rule protocol

相关标签:
1条回答
  • 2021-01-25 11:05

    Saying <NSNumber> defines a new generic placeholder type in your performRule(value:) method, which, as you've named it NSNumber, will shadow Foundation's NSNumber class – meaning that the value: parameter is of type your generic placeholder, not Foundation's NSNumber.

    If you want it so that types conforming to Rule can choose their own type for the parameter of the performRule(value:) method – then you want an associated type, not a generic placeholder.

    protocol NumberCalculation {
        var number : NSNumber { get set }
    }
    
    protocol Rule {
    
        // define associated type that conforming types must satisfy
        // by providing a type to replace it with
        associatedtype Value
        var invalidMessage : String { get set }
        func performRule(value: Value) -> Bool
    }
    
    struct GreaterThanRule : Rule, NumberCalculation {
    
        var invalidMessage: String
        var number : NSNumber
    
        init(valueMustBeGreaterThan value: NSNumber, withInvalidMessage message : String = "") {
            number = value
            invalidMessage = message
        }
    
        // satisfy associated type implicitly by annotating the type of the parameter
        // as NSNumber – the compiler will infer that Value == NSNumber.
        func performRule(value: NSNumber) -> Bool {
            number.decimalValue // works
            value.decimalValue // also works!
            return true
        }
    }
    
    0 讨论(0)
提交回复
热议问题