Trouble with operator overloading and inferred types in Swift -
literals
swift has couple of literals can used initialize different types without explicitly calling initializer. example,
let x = 5 // x int
automatically infers x
of type int
. if specify type of variable else
let x: uint = 5 // x uint
the compiler automatically understands 5
unsigned integer , respective uint
initializer has called instead of int
initializer.
the expressiblebyintegerliteral
protocol
this possible types implement protocol expressiblebyintegerliteral
. add protocol conformance own type:
/// represents range of characters in `string`. // /// purpose of type provide wrapper around `countableclosedrange` /// can initialized both range , **integer literal**. struct textrange: expressiblebyintegerliteral { let range: countableclosedrange<int> var lowerbound: int { return range.lowerbound } var upperbound: int { return range.upperbound } init(_ range: countableclosedrange<int>) { self.range = range } // initializer adds protocol conformance: init(integerliteral value: int) { self.range = value...value } }
with definition can write:
let x: textrange = 5 // x `textrange`
however,
let x = 5 // x `int`
still infers x int
. far, good.
overloading ...
operator
now want able create textrange
closed range operator ...
this:
let y: textrange = 5...10
so overload ...
operator in extension textrange
s:
extension textrange { /// given 2 text ranges, operator creates new text range incorporates /// integers within operand ranges integers between operand ranges. /// /// - parameters: /// - lowerrange: text range lower bound smaller lower bound of `upperrange`. /// - upperrange: text range lower bound greater lower bound of `lowerrange`. /// - returns: `textrange` first operand's lower bound second operand's upper bound. static func ...(lowerrange: textrange, upperrange: textrange) -> textrange { let lowerbound = lowerrange.lowerbound let upperbound = max(lowerrange.upperbound, upperrange.upperbound) assert(lowerbound <= upperbound, "cannot create textrange because lowerbound > upperbound.") return textrange(lowerbound...upperbound) } }
and trouble. (what surprise: trouble begins operator overloading! 😏)
trouble
for variable of textrange
type operator works expected when omit type annotation variable still instantiated textrange
:
let y = 5...10 // y `textrange`
that shouldn't be because:
if no type specified variable,
the default inferred type of integer literal swift standard library type int.
(see integer literals in the swift programming language)
thus, expect
5
,10
inferredint
, nottextrange
.the overload of
...
operator implemented 2 operands oftextrange
type. thus,x...y
should still use original swift implementation of...
ifx
,y
bothint
s.
so why compiler "decide" should use overloaded operator default ranges between 2 integer literals , interpret x
, y
in pattern x...y
textrange
s?
is there way tell compiler operator should used default in case type of 2 operands not specified?
Comments
Post a Comment