2016-03-31 29 views
1

无法理解如何对待各类仿制药,以及如何与图书馆与未定义的类型使用的参数:“无法将类型‘T’......的价值”,在仿制药

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") 
    } 
} 
+2

您可能想使用'Any'而不是通用方法。无论如何,通过这样做,如果让doubleValue = value为?双{...使用}'。请参阅https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/TypeCasting.html – Kevin

+0

它适用于'return(fm.stringFromNumber(NSNumber(double:doubleValue))!)'。我不知道,但为什么我应该在最后解开字符串值? –

+0

因为'stringFromNumber(_ :)'不能保证返回一个非零值,但是你的方法是。 – avismara

回答

0

为什么在这种情况下你必须使用泛型吗?只有在必须保存类型信息时才使用泛型。

使用泛型只有当:

“你打算以后给你一个类型,我希望你能强制执行 类型,我到处都指定。”

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

“不要担心这个变量没必要强制这里的任何类型让 我做任何我想要。”

就是说,你的用例适合第二个。你不想在这里混淆泛型。您的解决方案应该如下:

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") 
    } 
} 
+0

不是'return(fm.stringFromNumber(doubleValue))!'但是'return(fm.stringFromNumber(doubleValue)!)' –

+0

两者都很好。你甚至可以失去外部的括号。它不是像其他语言一样在Swift中强制执行。 :) – avismara