2017-01-11 43 views
1

我試圖創建一個函數,它返回NSPredicate通用NSPredicate

目前我有:

func predicate(value: String, op: String, predicate: String) -> [NSPredicate] { 
    return [NSPredicate(format: "\(value) \(op) %@", predicate)] 
} 

func predicate(value: String, op: String, predicate: Int) -> [NSPredicate] { 
    return [NSPredicate(format: "\(value) \(op) %d", predicate)] 
} 

func predicate(value: String, op: String, predicate: NSManagedObject) -> [NSPredicate] { 
    return [NSPredicate(format: "\(value) \(op) %@", predicate)] 
} 

func predicate(value: String, op: String, predicate: Date) -> [NSPredicate] { 
    return [NSPredicate(format: "\(value) \(op) %@", predicate)] 
} 

這似乎有點過分。所以,我一直在試圖把它們合併起來,並創建一個通用的功能:

func predicate<T: CVarArg>(value: String, op: String, predicate: T) -> [NSPredicate] { 
    return [NSPredicate(format: "\(value) \(op) %@", predicate)] 
} 

這個工程除了當TInt。爲此,我需要使用%d。我試圖添加一行:

let symbol = T is SignedInteger ? "%d" : "%@" 

但是,這是給我的錯誤:

...can only be used as a generic constraint...

然後,我以爲我可以創建一個where子句功能:

func ... -> [NSPredicate] where T: SignedInteger { ... } 

但那麼我不知道如何讓它接受DateStringNSManagedObject

問:
如何創建一個通用的功能,可以在Int與「他人」之間區別?

+0

說實話,我沒有看到這種功能的用處。 'NSPredicate'(format:「key =%d」,123)''謂詞(value:「key」,op:「=」,predicate:123)的優點是什麼? –

+0

@MartinR示例已被簡化。最初它是一個嵌套'enum'的'NSManagedObject'的協議,所以我可以更容易地創建一個謂詞。 –

+2

請注意,整數參數的正確格式取決於整數類型的*大小*。在64位平臺上,NSPredicate(format:「key =%d」,Int.max)不會給出預期的結果,您應該對'Int'(== Int64)參數使用'%ld'。 –

回答

3

您可以使用以前的解決方案針對不同的參數類型實現不同的實現來解決問題:重載

func predicate<T: CVarArg>(value: String, op: String, predicate: T) -> [NSPredicate] { 
    return [NSPredicate(format: "\(value) \(op) %@", predicate)] 
} 

func predicate(value: String, op: String, predicate: Int) -> [NSPredicate] { 
    return [NSPredicate(format: "\(value) \(op) %d", predicate)] 
} 

希望這會有所幫助。
祝你好運。

+0

謝謝,我希望我可以做到沒有超載。我一直在考慮你的答案,但是在使用'Int'時會擔心,它會使用第一個函數。我意識到現在不會發生這種情況,因爲一旦使用了「Int」,它就會自動使用第二個函數。 –

+0

很高興知道它有幫助。這是最佳的方法,因爲代碼儘可能多地共享,但不會更多。 –