【问题标题】:"Cannot convert value of type 'T'..." in generics泛型中的“无法转换'T'类型的值......”
【发布时间】:2016-03-31 03:37:19
【问题描述】:

无法理解如何处理泛型类型以及如何将参数与库中的未定义类型一起使用:

func cellWith<T>(value: T) -> String {         // I expect Int, Double or String 
                                               // type value as argument  

    let fm = NSNumberFormatter()               // Double type argument will be
    fm.numberStyle = .CurrencyStyle            // processed like "currency"

    if value.self is Double {               // In case value have type "Double", 
                                            // like 20_000.00
        return(fm.stringFromNumber(value))  // I expect return $20,000.00
                                   ^~~~~
// ERROR: Cannot convert value of type 'T' to expected argument type 'NSNumber'

    } else {
        return("bla-bla-bla")
    }
}

【问题讨论】:

  • 您可能希望使用Any 而不是泛型方法。无论如何,您可以通过 if let doubleValue = value as? Double { ...use } 快​​速投入。见developer.apple.com/library/ios/documentation/Swift/Conceptual/…
  • 它适用于return(fm.stringFromNumber(NSNumber(double:doubleValue))!)。我不知道,但是为什么我要在最后解开 String 值呢?
  • 因为stringFromNumber(_:)不能保证返回非零值,但你的方法是。

标签: swift generics types casting


【解决方案1】:

为什么在这种情况下必须使用泛型?仅当您必须保存类型信息时才使用泛型。

仅在以下情况下使用泛型:

“你稍后会给你一个类型,我希望你强制执行 在我指定的任何地方输入。”

只有当你想告诉编译器时才使用Any:

"不用担心这个变量这里不需要强制任何类型 let 我想做什么就做什么。”

话虽如此,您的用例适合第二个。你不想在这里弄乱泛型。你的解决方案应该是:

func cellWith(value: Any) -> String {
    let fm = NSNumberFormatter()
    fm.numberStyle = .CurrencyStyle
    if let doubleValue = value as? Double {
        return(fm.stringFromNumber(doubleValue))!
    } else {
        return("bla-bla-bla")
    }
}

【讨论】:

  • 不是return(fm.stringFromNumber(doubleValue))!,而是return(fm.stringFromNumber(doubleValue)!)
  • 两者都很好。您甚至可以丢失外括号。与其他语言不同,它在 Swift 中没有强制执行。 :)
猜你喜欢
  • 2018-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多