Swift3 Can';t扩展特定类型的泛型结构

Swift3 Can';t扩展特定类型的泛型结构,swift3,Swift3,想玩玩在Swift3中添加一些糖的游戏。基本上,我希望能够做到以下几点: let randomAdjust = (-10...10).random 为此,我决定需要扩展ClosedRange。但后来发现这可能对我的情况更好,我现在真的打算做Int,使用CountableClosedRange。我最近的多次尝试如下所示: extension CountableClosedRange where Bound == Int { var random:Int { return

想玩玩在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 {

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

在尝试扩展阵列时,通常会遇到此障碍。这是合法的:

extension Array where Element : Comparable {
}
但这是非法的:

extension Array where Element == Int {
}
编译器抱怨:

error: same-type requirement makes generic parameter 'Bound' non-generic
extension CountableClosedRange where Bound == Int {
同一类型要求使泛型参数“Element”非泛型

问题在于这里将
==
与数组的参数化类型元素结合使用,因为数组是一个通用结构

Array的一个解决方法是提升Array继承的层次结构,以达到非泛型结构的效果:

extension Sequence where Iterator.Element == Int {
}
这是合法的,因为序列和迭代器是通用协议

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

extension CountableClosedRange where Bound : Integer {
}
这就是我们两次尝试在一个范围内实现
random
的真正区别。您的尝试遇到了障碍,但没有遇到,原因是您使用的是
=
,而我使用的是
。我可以这样做,因为Double符合一个协议(FloatingPoint)


但是,正如您所知,幸运的是,所有这些诡计都将很快成为过去。

这种常见的路障是在尝试扩展阵列时遇到的。这是合法的:

extension Array where Element : Comparable {
}
但这是非法的:

extension Array where Element == Int {
}
编译器抱怨:

error: same-type requirement makes generic parameter 'Bound' non-generic
extension CountableClosedRange where Bound == Int {
同一类型要求使泛型参数“Element”非泛型

问题在于这里将
==
与数组的参数化类型元素结合使用,因为数组是一个通用结构

Array的一个解决方法是提升Array继承的层次结构,以达到非泛型结构的效果:

extension Sequence where Iterator.Element == Int {
}
这是合法的,因为序列和迭代器是通用协议

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

extension CountableClosedRange where Bound : Integer {
}
这就是我们两次尝试在一个范围内实现
random
的真正区别。您的尝试遇到了障碍,但没有遇到,原因是您使用的是
=
,而我使用的是
。我可以这样做,因为Double符合一个协议(FloatingPoint)


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

在Swift 4中,您所尝试的一切现在都得到了完全支持。万岁

扩展堆栈,其中元素:equalable{
func isTop(uItem:Element)->Bool{
guard let topItem=items.last else{
返回错误
}
返回topItem==项目
}
}

来自Swift文档的示例:

在Swift 4中,您正在尝试的内容现在完全受支持。万岁

扩展堆栈,其中元素:equalable{
func isTop(uItem:Element)->Bool{
guard let topItem=items.last else{
返回错误
}
返回topItem==项目
}
}

Swift文档中的示例:

您的意思是这样吗?那么你想回答什么问题呢?我已经向您展示了如何创建range
random
函数;这让你满意吗?还是让我谈论“我甚至不知道它在告诉我什么”这一部分的真正目的?我想是第二个。在尝试扩展Swift中的协议和更多泛型时,我一直感到非常沮丧。所以,是的,我很好奇为什么我不能约束绑定到Int。因为我的灯泡还没亮。与其他答案相比,我更喜欢你的更通用的解决方案。但令我沮丧的是,我甚至不知道如何写一本更差的/请注意,Swift 3.1将支持这一点。您的意思是这样吗?那么你想回答什么问题呢?我已经向您展示了如何创建range
random
函数;这让你满意吗?还是让我谈论“我甚至不知道它在告诉我什么”这一部分的真正目的?我想是第二个。在尝试扩展Swift中的协议和更多泛型时,我一直感到非常沮丧。所以,是的,我很好奇为什么我不能约束绑定到Int。因为我的灯泡还没亮。与其他答案相比,我更喜欢你的更通用的解决方案。但令我沮丧的是,我甚至不知道如何写一本更差的/请注意,Swift 3.1将支持这一点。在我的书的本节末尾讨论了该示例:并且
扩展数组,其中Element==Int
现在在Swift 3.1中是合法的,Xcode 8.3 beta:)@Hamish终于可以使用了!这个例子在我的书的这一节末尾讨论过:并且
扩展数组,其中Element==Int
现在在Swift 3.1中是合法的,Xcode 8.3 beta:)@Hamish终于可以使用了!谢谢提醒。