Swift 通用非预测

Swift 通用非预测,swift,generics,Swift,Generics,我正在尝试创建一个返回NSPredicate的函数 目前我有: func predicate(value: String, op: String, predicate: String) -> [NSPredicate] { return [NSPredicate(format: "\(value) \(op) %@", predicate)] } func predicate(value: String, op: String, predicate: Int) -> [NS

我正在尝试创建一个返回
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)]
}
但这给了我一个错误:

…只能用作常规约束

然后我想我可以用
where
子句创建函数:

func ... -> [NSPredicate] where T: SignedInteger { ... }
但是我不知道如何让它接受
Date
String
NSManagedObject

问题:

如何创建一个能够区分
Int
和“其他”的通用函数?

对于不同的参数类型,可以使用以前的解决方案来解决这个问题:重载

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)]
}
func谓词(值:String,op:String,谓词:T)->[NSPredicate]{
返回[NSPredicate(格式:“\(值)\(运算)%@”,谓词]
}
func谓词(值:String,op:String,谓词:Int)->[NSPredicate]{
返回[NSPredicate(格式:“\(值)\(操作)%d”,谓词)]
}
希望这有帮助。

祝你好运。

老实说,我看不出这样一个函数有什么用处。
谓词(value:“key”,op:“=”,谓词:123)
NSPredicate(format:“key=%d”,123)
的优点是什么?@MartinR示例已经简化。最初,它是我的
NSManagedObject
协议,带有嵌套的
enum
,因此我可以更轻松地创建谓词。请注意,整数参数的正确格式取决于整数类型的大小。在64位平台上,
NSPredicate(格式:“key=%d”,Int.max)
不会给出预期的结果,您应该对
Int
(==Int64)参数使用
%ld
。@MartinR请原谅我有点懒惰(我似乎还找不到答案),这是否意味着为了安全起见,我应该使用
%ld
,而不是
%d
?比较。实际上,最简单的方法是将所有数字转换为
NSNumber
谢谢,我希望我可以在不过载的情况下完成。我也一直在考虑你的答案,但担心当使用
Int
时,它会使用第一个函数。我现在意识到这不会发生,因为一旦使用了
Int
,它将自动使用第二个函数。很高兴知道它有帮助。这是最佳的方法,因为代码被尽可能多地共享,但不是更多。
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)]
}