Swift 通用协议函数参数
Swift Generic Protocol Function Parameters
这似乎对我有用。我想要做的就是让 Rule
协议能够 performRule
在采用该规则协议的任何结构上,然后 return 一个布尔值。但是,按照我的代码目前的方式,我无法访问 performRule(:value)
value 参数上的任何属性。我觉得我错过了一个重要的概念或者有问题。您应该能够将下面的代码复制到 playground 中以亲自查看问题。
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
}
}
说 <NSNumber>
在您的 performRule(value:)
方法中定义了一个新的通用占位符类型,正如您将其命名为 NSNumber
,它将影响 Foundation 的 NSNumber
class – 表示 value:
参数是 your 通用占位符类型,而不是 Foundation 的 NSNumber
.
如果您希望符合 Rule
的类型可以为 performRule(value:)
方法的参数选择自己的类型 – 那么您需要一个 associated type,而不是通用占位符.
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
}
}
这似乎对我有用。我想要做的就是让 Rule
协议能够 performRule
在采用该规则协议的任何结构上,然后 return 一个布尔值。但是,按照我的代码目前的方式,我无法访问 performRule(:value)
value 参数上的任何属性。我觉得我错过了一个重要的概念或者有问题。您应该能够将下面的代码复制到 playground 中以亲自查看问题。
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
}
}
说 <NSNumber>
在您的 performRule(value:)
方法中定义了一个新的通用占位符类型,正如您将其命名为 NSNumber
,它将影响 Foundation 的 NSNumber
class – 表示 value:
参数是 your 通用占位符类型,而不是 Foundation 的 NSNumber
.
如果您希望符合 Rule
的类型可以为 performRule(value:)
方法的参数选择自己的类型 – 那么您需要一个 associated type,而不是通用占位符.
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
}
}