我经常遇到这样的情况:
public extension CountableRange {
func advanced(by n: Bound.Stride) -> Self {
let lowerBound = self.lowerBound.advanced(by: n)
let upperBound = self.upperBound.advanced(by: n)
return .init(uncheckedBounds: (lowerBound, upperBound))
}
static func + (lhs: Self, rhs: Bound.Stride) -> Self {
lhs.advanced(by: rhs)
}
static func - (lhs: Self, rhs: Bound.Stride) -> Self {
lhs.advanced(by: -rhs)
}
}
//--------------------------------------------------------
public extension CountableClosedRange {
func advanced(by n: Bound.Stride) -> Self {
let lowerBound = self.lowerBound.advanced(by: n)
let upperBound = self.upperBound.advanced(by: n)
return .init(uncheckedBounds: (lowerBound, upperBound))
}
static func + (lhs: Self, rhs: Bound.Stride) -> Self {
lhs.advanced(by: rhs)
}
static func - (lhs: Self, rhs: Bound.Stride) -> Self {
lhs.advanced(by: -rhs)
}
}
完全相同的两段代码。有什么办法可以解决吗?
如果CountableRange
和CountableClosedRange
符合某个通用协议BasicRange
,我可以为该BasicRange
协议编写一个扩展名。但通常并非如此。
答案 0 :(得分:4)
您可以使用协议默认实现将功能添加到几种内置类型。
您只需要声明一个协议,并使用所需功能的默认实现对其进行扩展,然后使想要具有此功能的内置类型符合该协议,它们将免费获得默认实现。 / p>
public protocol BasicRange: RangeExpression where Bound: Strideable {
var lowerBound: Bound { get }
var upperBound: Bound { get }
init(uncheckedBounds bounds: (lower: Bound, upper: Bound))
func advanced(by n: Bound.Stride) -> Self
static func + (lhs: Self, rhs: Bound.Stride) -> Self
static func - (lhs: Self, rhs: Bound.Stride) -> Self
}
public extension BasicRange {
func advanced(by n: Bound.Stride) -> Self {
let lowerBound = self.lowerBound.advanced(by: n)
let upperBound = self.upperBound.advanced(by: n)
return .init(uncheckedBounds: (lowerBound, upperBound))
}
static func + (lhs: Self, rhs: Bound.Stride) -> Self {
lhs.advanced(by: rhs)
}
static func - (lhs: Self, rhs: Bound.Stride) -> Self {
lhs.advanced(by: -rhs)
}
}
extension CountableRange: BasicRange {}
extension CountableClosedRange: BasicRange {}
CountableRange(uncheckedBounds: (1,5)).advanced(by: 1)
CountableClosedRange(uncheckedBounds: (1,5)).advanced(by: 1)