Swift 如何防止某些泛型重载,例如整数类型的 Range.subscript?
How does Swift prevent certain generic overloads, like Range.subscript for integer types?
Swift 类型 Range
的文档指出:
Like other collections, a range containing one element has an
endIndex
that is the successor of its startIndex
; and an empty
range has startIndex == endIndex
.
Axiom: for any Range
r
, r[i] == i
.
Therefore, if T
has a maximal value, it can serve as an endIndex
, but can never be contained in a Range<T>
.
It also
follows from the axiom above that (-99..<100)[0] == 0
. To prevent
confusion (because some expect the result to be -99
), in a context
where T
is known to be an integer type, subscripting with T
is a
compile-time error::
// error: could not find an overload for 'subscript'…
println( Range<Int>(start:-99, end:100)[0] )
However,
subscripting that range still works in a generic context::
func brackets<T:ForwardIndexType>(x: Range<T>, i: T) -> T {
return x[i] // Just forward to subscript
}
println(brackets(Range<Int>(start:-99, end:100), 0)) // prints 0
我们如何在我们自己的泛型中实现这种行为 类?仅从 subscript
:
的定义我无法理解它是如何工作的
subscript (position: T) -> T { get }
subscript (_: T._DisabledRangeIndex) -> T { get }
谁能给我解释一下?
以下代码的行为与内置 Range
相同。
struct MyRange<T: ForwardIndexType> {
subscript (position: T) -> T {
return position
}
subscript (_: T._DisabledRangeIndex) -> T {
fatalError()
}
}
MyRange<String.Index>()["foo".startIndex] // no problem
MyRange<Int>()[0] // < [!] error: could not find an overload for 'subscript' that accepts the supplied arguments
好像Int._DisabledRangeIndex
是Int
,Int16._DisabledRangeIndex
是Int16
等等
当 T._DisabledRangeIndex
与 T
相同时,MyRange<T>
最终有 2 个冲突的 subscript
定义导致编译错误。
Swift 类型 Range
的文档指出:
Like other collections, a range containing one element has an
endIndex
that is the successor of itsstartIndex
; and an empty range hasstartIndex == endIndex
.Axiom: for any
Range
r
,r[i] == i
.Therefore, if
T
has a maximal value, it can serve as anendIndex
, but can never be contained in aRange<T>
.It also follows from the axiom above that
(-99..<100)[0] == 0
. To prevent confusion (because some expect the result to be-99
), in a context whereT
is known to be an integer type, subscripting withT
is a compile-time error::// error: could not find an overload for 'subscript'… println( Range<Int>(start:-99, end:100)[0] )
However, subscripting that range still works in a generic context::
func brackets<T:ForwardIndexType>(x: Range<T>, i: T) -> T { return x[i] // Just forward to subscript } println(brackets(Range<Int>(start:-99, end:100), 0)) // prints 0
我们如何在我们自己的泛型中实现这种行为 类?仅从 subscript
:
subscript (position: T) -> T { get }
subscript (_: T._DisabledRangeIndex) -> T { get }
谁能给我解释一下?
以下代码的行为与内置 Range
相同。
struct MyRange<T: ForwardIndexType> {
subscript (position: T) -> T {
return position
}
subscript (_: T._DisabledRangeIndex) -> T {
fatalError()
}
}
MyRange<String.Index>()["foo".startIndex] // no problem
MyRange<Int>()[0] // < [!] error: could not find an overload for 'subscript' that accepts the supplied arguments
好像Int._DisabledRangeIndex
是Int
,Int16._DisabledRangeIndex
是Int16
等等
当 T._DisabledRangeIndex
与 T
相同时,MyRange<T>
最终有 2 个冲突的 subscript
定义导致编译错误。