Reputation: 634
I am getting the error in the title when trying to use the argument of a generic function inherited from a base class
Base class:
BaseBottomBar: UIView {
...
func formatDetailText<T>(value: T...) {
assertionFailure("You shouldn't be using this base class")
}
}
Child class:
NewTicketBottomBar: BaseBottomBar {
override func formatDetailText<NSNumber>(value: NSNumber...) {
let priceAsCurrencyString = NumberFormatter.currencyFormatter.string(from: value[1]) //Error on this line
assert(priceAsCurrencyString != nil, "The price cannot be nil")
let newTicketText = String(format: "%4.0f", value[0]) + " / TOTAL : " + priceAsCurrencyString!
detailLabel.text = newTicketText
}
}
I guess I have my base method prototype wrong in some way but I can't see how.
I wasn't using a generic method in the beginning and the prototype was the following:
func formatDetailText(value: Double...) {
...
let priceAsCurrencyString = NumberFormatter.currencyFormatter.string(from: NSNumber(value: value[1]))
...
}
And this was working fine
Any help would be appreciated
Upvotes: 1
Views: 2365
Reputation: 534950
You seem to think that
override func formatDetailText<NSNumber>(value: NSNumber...) {
resolves the generic <T>
in the overridden method as NSNumber. It doesn't. It merely introduces a different name for the generic; NSNumber here is not the NSNumber class, it's just another generic placeholder name, exactly like T (in fact, it is T by another name).
So naturally, when you try to use this placeholder where an NSNumber is expected in NumberFormatter's string(from:)
, the compiler turns around and says, "Dude [the compiler is from California, this is how it talks], I have no reason to think that your placeholder called "NSNumber" is in fact NSNumber."
You need to give it a reason to think that. What you probably mean is
override func formatDetailText<T>(value: T...) where T : NSNumber {
Upvotes: 3
Reputation: 13266
The problem is that your code isn't saying that the parameter must be an NSNumber
. It's saying that it takes a generic type that you want to call NSNumber
, just like you're using T
above.
The error message is because there is no guarantee to the compiler that the generic type called NSNumber
is a real NSNumber
instance. You could pass a string to it for all it knows.
Your override should look like this
override func formatDetailText<T: NSNumber>(value: T...)
Upvotes: 2