Swift通用协议功能参数 [英] Swift Generic Protocol Function Parameters
问题描述
performRule
,然后返回一个布尔值。但是,通过我的代码目前的方式,我无法访问 performRule(:value)
值参数上的任何属性。我觉得我错过了一个重要的概念,或者是一些马车。您应该可以将下面的代码复制到游乐场,以便自己查看问题。 import Foundation
协议NumberCalculation {
var number:NSNumber {get set}
}
协议规则{
var invalidMessage:String {get set}
func performRule< T>(值:T) - > Bool
}
struct GreaterThanRule:Rule,NumberCalculation {
var invalidMessage:String
var number:NSNumber
init(valueMustBeGreaterThan value: NSNumber,withInvalidMessage message:String =){
number = value
invalidMessage = message
}
func performRule< NSNumber>(value:NSNumber) - > ; Bool {
number.decimalValue //工作
value.decimalValue //不工作
返回true
}
}
$ c $
performRule(value:)
方法中添加了一个新的通用占位符类型,如您所命名的 NSNumber
,将shadow Foundation的 NSNumber
类 - 这意味着值:
参数的类型是您的泛型占位符,而不是基金会的 NSNumber
。 如果你想让它符合 Rule
可以为 performRule(value:)
方法的参数选择它们自己的类型 - 那么你需要一个 associated type ,而不是一个通用的占位符。
protocol NumberCalculation {
var number:NSNumber {get set}
}
协议规则{
//定义相关类型,相符类型必须满足
//通过提供一个类型来替换它
associatedtype Value
var invalidMessage:String {get set}
func performRule(value:Value) - > Bool
}
struct GreaterThanRule:Rule,NumberCalculation {
var invalidMessage:String
var number:NSNumber
init (valueMustBeGreaterThan value:NSNumber,withInvalidMessage message:String =){
number = value
invalidMessage = message
}
//通过注释隐式地满足关联类型参数
//的类型为NSNumber - 编译器会推断出值== NSNumber。
func performRule(value:NSNumber) - > Bool {
number.decimalValue //工作
value.decimalValue //也可以工作!
return true
}
}
This seems like it should work to me. All I am trying to do is make the Rule
protocol able to performRule
on whatever struct adopts that Rule protocol and then return a boolean. However, with the way my code is currently I cannot access any properties on the performRule(:value)
value parameter. I feel like I am missing an important concept or something is buggy. You should be able to copy the code below into a playground to see the issue for yourself.
import Foundation
protocol NumberCalculation {
var number : NSNumber { get set }
}
protocol Rule {
var invalidMessage : String { get set }
func performRule<T>(value: T) -> Bool
}
struct GreaterThanRule : Rule, NumberCalculation {
var invalidMessage: String
var number : NSNumber
init(valueMustBeGreaterThan value: NSNumber, withInvalidMessage message : String = "") {
number = value
invalidMessage = message
}
func performRule<NSNumber>(value: NSNumber) -> Bool {
number.decimalValue // works
value.decimalValue // doesn't work
return true
}
}
Saying <NSNumber>
defines a new generic placeholder type in your performRule(value:)
method, which, as you've named it NSNumber
, will shadow Foundation's NSNumber
class – meaning that the value:
parameter is of type your generic placeholder, not Foundation's NSNumber
.
If you want it so that types conforming to Rule
can choose their own type for the parameter of the performRule(value:)
method – then you want an associated type, not a generic placeholder.
protocol NumberCalculation {
var number : NSNumber { get set }
}
protocol Rule {
// define associated type that conforming types must satisfy
// by providing a type to replace it with
associatedtype Value
var invalidMessage : String { get set }
func performRule(value: Value) -> Bool
}
struct GreaterThanRule : Rule, NumberCalculation {
var invalidMessage: String
var number : NSNumber
init(valueMustBeGreaterThan value: NSNumber, withInvalidMessage message : String = "") {
number = value
invalidMessage = message
}
// satisfy associated type implicitly by annotating the type of the parameter
// as NSNumber – the compiler will infer that Value == NSNumber.
func performRule(value: NSNumber) -> Bool {
number.decimalValue // works
value.decimalValue // also works!
return true
}
}
这篇关于Swift通用协议功能参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!