无法扩展特定类型

时间:2017-01-15 02:31:21

标签: swift3

想在Swift3中添加一些糖来玩具。基本上,我希望能够做到这样的事情:

let randomAdjust = (-10...10).random

为此,我决定扩展ClosedRange。但后来发现它可能对我的情况更好,我真的只是计划现在做Int,使用CountableClosedRange。我最近的多次尝试看起来像:

extension CountableClosedRange where Bound == Int {
    var random:Int {
        return Int(arc4random_uniform(UInt32(self.count) + 1)) + self.lowerBound
    }
}

但游乐场抱怨道:

error: same-type requirement makes generic parameter 'Bound' non-generic
extension CountableClosedRange where Bound == Int {

我甚至不知道它在那里告诉我什么。

2 个答案:

答案 0 :(得分:8)

通常遇到此障碍的方式是尝试扩展Array时。这是合法的:

extension Array where Element : Comparable {
}

但这是非法的:

extension Array where Element == Int {
}

编译器抱怨:

  

相同类型的要求使通用参数'Element'非通用

问题是这里使用==和Array的参数化类型Element,因为Array是一个通用的 struct

使用Array的一个解决方法是提升Array继承的层次结构,以达到不是通用结构的东西:

extension Sequence where Iterator.Element == Int {
}

这是合法的,因为Sequence和Iterator是通用的协议

另一种解决方案是从目标类型(即Int)提升层次结构。如果我们可以找到Int符合的协议,那么我们可以使用:运算符而不是==。嗯,有一个:

extension CountableClosedRange where Bound : Integer {
}

这是我们在范围内实施random的两次尝试之间的真正区别。您尝试遇到包版广告的原因是mine没有使用==,而我正在使用:。我可以这样做,因为有一个Double符合的协议(FloatingPoint)。

但是,正如你所知,幸运的是,所有这些诡计很快就会成为过去。

答案 1 :(得分:0)

在Swift 4中,现在完全支持您的尝试。哇!

Swift文档中的示例:https://docs.swift.org/swift-book/LanguageGuide/Generics.html#ID553