-1

I would like to override the '=' operator for a String like the follow try :

let a: String =  "a"..."z"
print(a) // abcdefghijklmnopqrstuvwxyz

I had found ExpressibleBy protocol and Initialize a String from a range of Characters in Swift

But, I does not found any idea how to merge these solution.

yycking
  • 1,017
  • 1
  • 9
  • 14

1 Answers1

1

Rather than using ExpressibleByXXXLiteral, you can just declare your own ... operator that returns a String.

This code from your second link makes ClosedRange<UnicodeScalar> conform to Sequence, which allows us to initialise a string from a ClosedRange<UnicodeScalar>:

extension Unicode.Scalar: Strideable {
    public func advanced(by n: Int) -> Unicode.Scalar {
        let value = self.value.advanced(by: n)
        guard let scalar = Unicode.Scalar(value) else {
            fatalError("Invalid Unicode.Scalar value:" + String(value, radix: 16))
        }
        return scalar
    }
    public func distance(to other: Unicode.Scalar) -> Int {
        return Int(other.value - value)
    }
}

extension String {
    init<S: Sequence>(_ sequence: S) where S.Element == Unicode.Scalar {
        self.init(UnicodeScalarView(sequence))
    }
}

extension Sequence where Element == Unicode.Scalar {
     var string: String { return String(self) }
}

Using that, our string-producing ... operator is simple to define:

func ...(lhs: UnicodeScalar, rhs: UnicodeScalar) -> String {
    // note that this is not recursive
    // this calls the "..." that produces a closed range
    (lhs...rhs).string
}

Usage:

let alphabet = "a"..."z"
print(alphabet)
Sweeper
  • 213,210
  • 22
  • 193
  • 313