Swift中运算符重载和推断类型的问题 直接常量

Swift中运算符重载和推断类型的问题 直接常量,swift,operator-overloading,operators,type-inference,literals,Swift,Operator Overloading,Operators,Type Inference,Literals,Swift有几个文本,可以用来初始化不同的类型,而无需显式调用它们的初始值设定项。比如说, let x = 5 // x is now an Int 自动推断x为Int类型。但是如果我们将变量的类型指定为其他类型 let x: UInt = 5 // x is now a UInt 编译器自动理解5现在是一个无符号整数,因此必须调用相应的UInt初始值设定项,而不是Int初始值设定项 ExpressibleByIntegerLiteral协议 这适用于实

Swift有几个文本,可以用来初始化不同的类型,而无需显式调用它们的初始值设定项。比如说,

let x = 5             // x is now an Int
自动推断
x
Int
类型。但是如果我们将变量的类型指定为其他类型

let x: UInt = 5       // x is now a UInt
编译器自动理解
5
现在是一个无符号整数,因此必须调用相应的
UInt
初始值设定项,而不是
Int
初始值设定项


ExpressibleByIntegerLiteral
协议 这适用于实现协议的所有类型
ExpressibleByIntegerLiteral
。现在,我将此协议一致性添加到我自己的类型:

/// 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
    }

}
但是,

let x = 5               // x is now an `Int`
仍然推断x是
Int
。到目前为止,一切顺利


重载
运算符 现在,我还希望能够使用闭合范围操作符
创建一个
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's lower bound to the 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 a TextRange because lowerBound > upperBound.")

        return TextRange(lowerBound...upperBound)
    }

}
扩展文本范围{
///给定两个文本范围,此运算符将创建一个包含
///操作数范围内的整数以及操作数范围之间的所有整数。
///
///-参数:
///-lowerRange:下限小于“upperRange”下限的文本范围。
///-上限:下限大于“lowerRange”下限的文本范围。
///-返回:从第一个操作数的下界到第二个操作数的上界的“TextRange”。
静态函数…(下限:TextRange,上限:TextRange)->TextRange{
设lowerBound=lowerRange.lowerBound
设上限=最大值(lowerRange.upperBound,upperRange.upperBound)

assert(lowerBound我的猜测:您定义了一个非泛型的
..
运算符,它优先于现有的泛型版本。-您可能是指
让y=5…10
好吧,我发现
(1为Int)…(5为Int)
可以工作,但它很难看:(@MartinR:听起来很合理。因此编译器首先尝试解析
..
运算符表达式。它搜索操作数为
ExpressibleByIntegerLiteral
的运算符的所有实现。如果仍然存在歧义(即多个实现匹配此模式)它选择非泛型而不是泛型实现,在这里它应该(在我看来)选择“整型文字的默认类型”
Int
。修复了打字错误,感谢您的提示!@Sweeper:是的,只有在推断整型文字的类型(即未明确指定)时才会出现问题。
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's lower bound to the 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 a TextRange because lowerBound > upperBound.")

        return TextRange(lowerBound...upperBound)
    }

}