Swift中运算符重载和推断类型的问题 直接常量
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协议 这适用于实
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)
}
}