无法为特定类型扩展通用结构 [英] Can't extend generic struct for specific type
问题描述
想在 Swift3 中添加一些糖.基本上,我希望能够执行以下操作:
Wanted to toy with adding some sugar in Swift3. Basically, I wanted to be able to do something like:
let randomAdjust = (-10...10).random
为此,我决定需要扩展ClosedRange
.但后来发现它对我的情况可能会更好,我现在真的只是打算做 Int,使用 CountableClosedRange
.我最近的多次尝试看起来像:
To do that, I decided I would need to extend ClosedRange
. But then found it would probably be even better for my case, I really just plan on doing Int's for now, to use CountableClosedRange
. My latest of multiple attempts looked like:
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 {
我什至不知道它在那里告诉我什么.
I don't even know what it's telling me there.
推荐答案
通常遇到这种障碍的方式是尝试扩展 Array.这是合法的:
The way this roadblock is commonly encountered is when attempting to extend Array. This is legal:
extension Array where Element : Comparable {
}
但这是非法的:
extension Array where Element == Int {
}
编译器抱怨:
相同类型的要求使得泛型参数 'Element' 非泛型
Same-type requirement makes generic parameter 'Element' non-generic
问题是这里使用了==
和Array的参数化类型Element,因为Array是一个泛型的struct.
The problem is the use of ==
here in combination with Array's parameterized type Element, because Array is a generic struct.
Array 的一种解决方法是提升 Array 继承的层次结构,以达到非通用结构的内容:
One workaround with Array is to rise up the hierarchy of Array's inheritance to reach something that is not a generic struct:
extension Sequence where Iterator.Element == Int {
}
这是合法的,因为 Sequence 和 Iterator 是通用的协议.
That's legal because Sequence and Iterator are generic protocols.
不过,另一种解决方案是从目标类型(即 Int)向上提升层次结构.如果我们能找到一个 Int 符合的协议,那么我们可以使用 :
操作符代替 ==
.嗯,有一个:
Another solution, though, is to rise up the hierarchy from the target type, namely Int. If we can find a protocol to which Int conforms, then we can use the :
operator instead of ==
. Well, there is one:
extension CountableClosedRange where Bound : Integer {
}
这是我们两次尝试在一个范围内实现 random
的真正区别.您的尝试遇到了障碍而 我的 不是因为您使用的是 ==
而我使用的是 :
.我可以这样做,因为有一个 Double 符合的协议 (FloatingPoint).
That's the real difference between our two attempts to implement random
on a range. The reason your attempt hits a roadblock and mine doesn't is that you are using ==
whereas I am using :
. I can do that because there's a protocol (FloatingPoint) to which Double conforms.
但是,正如你被告知的那样,幸运的是,所有这些诡计很快就会成为过去.
But, as you've been told, with luck all this trickery will soon be a thing of the past.
这篇关于无法为特定类型扩展通用结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!