无法将NSNumber类型的值转换为预期的参数类型NSNumber

时间:2018-07-19 15:56:51

标签: swift generic-programming

尝试使用从基类继承的泛型函数的参数时,标题出现错误

基类:

BaseBottomBar: UIView {
    ...
    func formatDetailText<T>(value: T...) {
        assertionFailure("You shouldn't be using this base 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
    }
}

Cannot convert value of type NSNumber to expected argument type NSNumber

我想我的基本方法原型在某种程度上是错误的,但是我不知道怎么做。

一开始我没有使用通用方法,因此原型如下:

func formatDetailText(value: Double...) {
    ...
    let priceAsCurrencyString = NumberFormatter.currencyFormatter.string(from: NSNumber(value: value[1]))
    ...
}

这很好用

任何帮助将不胜感激

2 个答案:

答案 0 :(得分:3)

您似乎认为

override func formatDetailText<NSNumber>(value: NSNumber...) {

在重写的方法中将通用<T>解析为NSNumber。没有。它只是为泛型引入了不同的名称。这里的NSNumber不是NSNumber类,它只是另一个通用的占位符名称,与T完全一样(实际上,它的是T的另一个名称)。

因此,很自然地,当您尝试使用NumberFormatter的string(from:)中期望使用NSNumber的占位符时,编译器转身说:“ Dude [编译器来自加利福尼亚,这就是它的说法],我没有理由认为您的占位符“ NSNumber”实际上就是NSNumber。”

您需要给它一个理由。你可能的意思是

override func formatDetailText<T>(value: T...) where T : NSNumber {

答案 1 :(得分:2)

问题是您的代码没有说明参数必须为NSNumber。就是说,它采用了要调用NSNumber的通用类型,就像您在上面使用T一样。

该错误消息是因为无法向编译器保证称为NSNumber的泛型类型是真实的NSNumber实例。您可以向它传递一个字符串,一无所知。

您的替代应该看起来像这样

override func formatDetailText<T: NSNumber>(value: T...)