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
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
}
}