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 textranges:

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 inferred int, not textrange.

  • the overload of ... operator implemented 2 operands of textrange type. thus, x...y should still use original swift implementation of ... if x , y both ints.

so why compiler "decide" should use overloaded operator default ranges between 2 integer literals , interpret x , y in pattern x...y textranges?

is there way tell compiler operator should used default in case type of 2 operands not specified?


Comments

Popular posts from this blog

python Tkinter Capturing keyboard events save as one single string -

android - InAppBilling registering BroadcastReceiver in AndroidManifest -

javascript - Z-index in d3.js -