首页 > 解决方案 > 具有数字和可比较协议的 Swift 泛型类

问题描述

我想编写一个快速的泛型类,它将数字作为也符合可比协议的类型。基本上我想要的是一个泛型rangeValidator,它应该采用任何类型的数字(int、double、float)并返回它是否在给定范围内?

class NumberRangeValidator<T: Numeric,Comparable> {

    var minValue: T
    var maxValue: T

    init(minValue: T, maxValue: T) {
        self.minValue = minValue
        self.maxValue = maxValue
    }

    func validate(_ value: T) -> Bool {
       if case minValue...maxValue = value {
          return true
        }
        return false
    }
}

标签: iosswiftgenerics

解决方案


由于您class是“RangeValidator”,我建议让您的类初始化程序采用ClosedRange<T>. 声明T: Comparable允许您使用range.contains(value)来进行验证:

注意:无需将您的课程限制为Numeric,但如果您愿意,可以将其声明为class NumberRangeValidator<T: Comparable & Numeric>评论中提到的@JoakinDanielson。

class NumberRangeValidator<T: Comparable & Numeric> {

    let range: ClosedRange<T>

    init(range: ClosedRange<T>) {
        self.range = range
    }

    // allow range to be specified with minValue, maxValue
    init(minValue: T, maxValue: T) {
        guard minValue <= maxValue else { fatalError("Can't form Range with maxValue < minValue") }
        self.range = minValue...maxValue
    }

    func validate(_ value: T) -> Bool {
        return range.contains(value)
    }
}

例子:

let validator = NumberRangeValidator(range: 10.0 ... 30.0)

print(validator.validate(9))   // false
print(validator.validate(10))  // true
print(validator.validate(20))  // true
print(validator.validate(30))  // true
print(validator.validate(31))  // false

let floatValidator = NumberRangeValidator(minValue: Float(0), maxValue: 5)
print(floatValidator.validate(0))   // true
print(floatValidator.validate(10))  // false

注意:没有理由这需要是class. Astruct也会做同样的工作。


推荐阅读