Issues with operator overloading and suggested types in Swift

literals

Swift has a couple of literals that can be used to initialize different types without explicitly invoking their initializer. For instance,

let x = 5             // x is now an Int

automatically outputs xto type Int. But if we specify the type of the variable as something else

let x: UInt = 5       // x is now a UInt

the compiler automatically understands what is 5now an unsigned integer, so instead of the initializer, you Intshould call the corresponding initializer UInt.


Protocol ExpressibleByIntegerLiteral

This is possible for all types that implement the protocol ExpressibleByIntegerLiteral. Now I add the correspondence of this protocol to my own type:

/// Represents a range of characters in a `String`.
//
/// The only purpose of this type is to provide a wrapper around `CountableClosedRange`
/// that can be initialized both with a range and an **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
    }

    // This initializer adds the protocol conformance:
    init(integerLiteral value: Int) {
        self.range = value...value
    }

}

With this definition, I can write:

let x: TextRange = 5    // x is now a `TextRange`

However

let x = 5               // x is now an `Int`

still indicates x as Int. So far so good.


...

TextRange ... :

let y: TextRange = 5...10

... TextRange s:

extension TextRange {

    /// Given two text ranges, this operator creates a new text range that incorporates
    /// the integers within the operand ranges as well as all integers between the operand ranges.
    ///
    /// - Parameters:
    ///   - lowerRange: A text range whose lower bound is smaller than the lower bound of `upperRange`.
    ///   - upperRange: A text range whose lower bound is greater than the lower bound of `lowerRange`.
    /// - Returns: A `TextRange` from the first operand lower bound to the second operand 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 a TextRange because lowerBound > upperBound.")

        return TextRange(lowerBound...upperBound)
    }

}

. ( : !)


TextRange , , TextRange:

let y = 5...10           // y is now a `TextRange`

, :

  • ,

    - Swift.

    (. Swift Programming)

    , , 5 10 Int, TextRange.

  • ... TextRange. , x...y Swift ..., x y Int s.

, "", x y x...y TextRange s?

, , ?

+4

Source: https://habr.com/ru/post/1683734/


All Articles