Swift通用协议功能参数 [英] Swift Generic Protocol Function Parameters

查看:90
本文介绍了Swift通用协议功能参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这似乎应该对我有用。我所要做的就是在任何结构采用Rule协议的情况下使 Rule 协议能够 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
}
}
在您的 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆