二进制运算符'/'不能应用于两个'T'操作数

时间:2017-11-13 11:58:04

标签: swift generics computed-properties

struct PickerRange<T: Comparable> {
    var start: T
    var end: T
    var step: T

    var length: T {
        // Binary operator '/' cannot be applied to two 'T' operands.
        return max(start, end) - min(start,end) / step 
    }
}

创建计算属性时会生成错误。怎么解决?

1 个答案:

答案 0 :(得分:3)

只需指定一个Numeric协议。

对于浮点精度:

struct PickerRange<T:FloatingPoint> {
    var start: T
    var end: T
    var step: T

    var length: T {
        return max(start, end) -  (min(start,end) / step)
    }
}

SignedIntegerUnsignedInteger或其他Numeric协议也是一种选择。

// Comparable

这些都不需要您另外指定Comparable,因此指定其中一个就足够了。

修改

  

如何为Int和Double制作一个结构?

基本上,您可以,指定SignedNumeric:

struct PickerRange<T:SignedNumeric & Comparable> {
    var start: T
    var end: T
    var step: T
}

// Treated as PickerRange<Double>
let a = PickerRange(start: 1.0, end: 5.0, step: 1)

// Treated as PickerRange<Int>
let b = PickerRange(start: 1, end: 5, step: 1)

但是,您有专门的length属性,其中包含/不支持的SignedNumeric运算符。解决方法包括对您初始化结构的类型进行类型检查/强制转换:

struct PickerRange<T:SignedNumeric & Comparable> {
    var start: T
    var end: T
    var step: T

    var length: T {
        if T.self is Double.Type {
            return (max(start, end) as! Double) - ((min(start, end) as! Double) / (step as! Double)) as! T
        } else if T.self is Int.Type {
            return (max(start, end) as! Int) - ((min(start, end) as! Int) / (step as! Int)) as! T
        } else {
            return 0
        }
    }
}

let a = PickerRange(start: 1.0, end: 5.0, step: 1)
let b = PickerRange(start: 1, end: 10, step: 1)

print(a.length)
print(b.length)