Swift 忽略块签名中定义的参数类型
Swift ignoring parameter types defined in block signature
我有下面的代码,编译器很满意:
func CheckPaintExists(colorCode : String, applicationCode : String) {
let checkRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Paint")
checkRequest.predicate = NSPredicate(block: { (item, bindings) -> Bool in
return (item as! Paint).ColorCode == colorCode
&& (item as! Paint).ApplicationCode == applicationCode
})
checkRequest.includesSubentities = false;
//managedContext.count(for: ...)do further stuff
}
但是一旦我在块签名中定义了 item
类型,我在 return 行上得到一个错误:
func CheckPaintExists2(colorCode : String, applicationCode : String) {
let checkRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Paint")
checkRequest.predicate = NSPredicate(block: { (item : Paint?, bindings : NSDictionary?) -> Bool in
return item.ColorCode == colorCode //*Value of type 'Any?' has no member 'ColorCode'
&& item.ApplicationCode == applicationCode
})
checkRequest.includesSubentities = false;
//managedContext.count(for: ...)do further stuff
}
它说 Value of type 'Any?' has no member 'ColorCode'
。我该如何解决这个问题?为什么它仍然使用块提供的默认 Any 类型?
如果你查看 NSPredicate.init(block:)
的 signature 那么你会看到该块有两个参数并且 return 是一个布尔值:(Any?, [String : Any]?) -> Bool)
而第一个参数确实是一个 Any
.
在您的第一个示例中,您使用 as!
进行强制转换,这就是它起作用的原因(如果类型实际上不是 Paint
装在 Any
中,它会在这里崩溃。你的第二个例子给你一个错误,因为你的类型注释是错误的;编译器期望第一个参数是 Any
而不是 Paint?
;它确实应该给你上面一行的错误,但看起来它首先在 return.
线上捕获它
如果你想安全地打开它应该是:
func CheckPaintExists(colorCode : String, applicationCode : String) {
let checkRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Paint")
checkRequest.predicate = NSPredicate(block: { (item, bindings) -> Bool in
guard let paint = item as? Paint else {
return false
}
return paint.ColorCode == colorCode
&& paint.ApplicationCode == applicationCode
})
checkRequest.includesSubentities = false;
//managedContext.count(for: ...)do further stuff
}
我有下面的代码,编译器很满意:
func CheckPaintExists(colorCode : String, applicationCode : String) {
let checkRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Paint")
checkRequest.predicate = NSPredicate(block: { (item, bindings) -> Bool in
return (item as! Paint).ColorCode == colorCode
&& (item as! Paint).ApplicationCode == applicationCode
})
checkRequest.includesSubentities = false;
//managedContext.count(for: ...)do further stuff
}
但是一旦我在块签名中定义了 item
类型,我在 return 行上得到一个错误:
func CheckPaintExists2(colorCode : String, applicationCode : String) {
let checkRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Paint")
checkRequest.predicate = NSPredicate(block: { (item : Paint?, bindings : NSDictionary?) -> Bool in
return item.ColorCode == colorCode //*Value of type 'Any?' has no member 'ColorCode'
&& item.ApplicationCode == applicationCode
})
checkRequest.includesSubentities = false;
//managedContext.count(for: ...)do further stuff
}
它说 Value of type 'Any?' has no member 'ColorCode'
。我该如何解决这个问题?为什么它仍然使用块提供的默认 Any 类型?
如果你查看 NSPredicate.init(block:)
的 signature 那么你会看到该块有两个参数并且 return 是一个布尔值:(Any?, [String : Any]?) -> Bool)
而第一个参数确实是一个 Any
.
在您的第一个示例中,您使用 as!
进行强制转换,这就是它起作用的原因(如果类型实际上不是 Paint
装在 Any
中,它会在这里崩溃。你的第二个例子给你一个错误,因为你的类型注释是错误的;编译器期望第一个参数是 Any
而不是 Paint?
;它确实应该给你上面一行的错误,但看起来它首先在 return.
如果你想安全地打开它应该是:
func CheckPaintExists(colorCode : String, applicationCode : String) {
let checkRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Paint")
checkRequest.predicate = NSPredicate(block: { (item, bindings) -> Bool in
guard let paint = item as? Paint else {
return false
}
return paint.ColorCode == colorCode
&& paint.ApplicationCode == applicationCode
})
checkRequest.includesSubentities = false;
//managedContext.count(for: ...)do further stuff
}