考虑以下代码(我发布这个主要是为了深入了解Swift编译器必须克服的障碍 - 失败本身不太可能影响太多的开发人员):
extension Int {
static var i: Int { return 5 }
}
func f(#xs: Int...) { // notice the #
println(xs)
}
f(xs: .i, .i, .i) // --> [5, 5, 5]
f() // --> []
f(xs: 5) // --> [5]
f(xs: .i) // --> [5]
func g(xs: Int...) { // no #
println(xs)
}
g(.i, .i, .i) // --> [5, 5, 5]
g() // --> []
g(5) // --> [5]
g(.i) // --> error: '(Int...).Type' does not have a member named 'i'
所以问题是你是否会认为这是一个错误?为此,请考虑问题可能与:
有关let (xs: Int...) = (.max, .min)
xs // --> [9223372036854775807, -9223372036854775808]
而对于单个元素,编译器不会将parens解释为定义元组(它本身就是语言的一个特征,而不是bug):
let (xs: Int...) = (.max) // error: could not find member 'max'
所以,使用显式类型我们也可以删除parens:
let (xs: Int...) = Int.max
xs // --> [9223372036854775807]
解决方法 (受Airspeed Velocity的启发 - 见下面他/她的好答案)
func h(xs: [Int]) {
println(xs)
}
func h(x: Int, xs: Int...) {
h([x] + xs)
}
func h() {
h([])
}
h(.i, .i, .i) // --> [5, 5, 5]
h(.i, .i) // --> [5, 5]
h(.i) // --> [5]
h() // --> []
示例用例
import Foundation
public extension NSRegularExpressionOptions { // these are nil literal convertible!
static var i: NSRegularExpressionOptions { return .CaseInsensitive }
static var x: NSRegularExpressionOptions { return .AllowCommentsAndWhitespace }
// static var IgnoreMetacharacters: NSRegularExpressionOptions { get }
static var s: NSRegularExpressionOptions { return .DotMatchesLineSeparators }
static var m: NSRegularExpressionOptions { return .AnchorsMatchLines }
// static var UseUnixLineSeparators: NSRegularExpressionOptions { get }
static var u: NSRegularExpressionOptions { return .UseUnicodeWordBoundaries }
}
public extension String {
// TODO: implement named capture groups (?<name>pattern)
func r(options: [NSRegularExpressionOptions]) -> NSRegularExpression {
return NSRegularExpression(pattern: self, options: reduce(options, nil, |), error: nil)!
}
func r(option: NSRegularExpressionOptions, _ options: NSRegularExpressionOptions...) -> NSRegularExpression {
return r(options + [option])
}
func r() -> NSRegularExpression { return r([]) }
var r: NSRegularExpression { return r([]) }
}
"a\\s+$".r(.m | .i) // --> NSRegularExpression
"a\\s+$".r(.m, .i) // --> NSRegularExpression
"\\s+$".r(.m) // --> NSRegularExpression
"\\s+".r() // --> NSRegularExpression
"\\s+".r // --> NSRegularExpression
并不是说你一定需要或想要所有这些选项:)事实上,我无法抗拒添加:
public func / (lhs: String, rhs: NSRegularExpressionOptions) -> NSRegularExpression {
return lhs.r(rhs)
}
public extension NSRegularExpressionOptions {
static var r: NSRegularExpressionOptions { return .allZeros }
}
"\\s+" / .r // --> NSRegularExpression
"\\s+$" / .m // --> NSRegularExpression
"a\\s+$" / (.m | .i) // --> NSRegularExpression
答案 0 :(得分:2)
我也在1.2中看到它。但我不确定它是否也是一个错误,尽管编译错误可能会更好。
隐式成员缩写只有在左侧的类型可以完全无误识别时才会启动。但由于函数可以将元组作为参数(即func f(_: Int, _: Int) { }; let x = (1,2); f(x)
),因此有两种可能性(Int
和Int...
)。
命名参数或传入多个参数,可以清楚地表明您没有尝试传递(Int...)
,因此.i
左侧的类型是明确的Int
隐式成员缩写起作用。
同样,这也有效:func h(_: Int, xs: Int...) { }; h(1, .i)
。和g(.i as Int)
一样。
如果您尝试这样做,则会收到类似的错误消息:func generic<T>(x: T) { }; g(.i)
- 仅仅因为恰好存在一个可能的匹配并不意味着Swift愿意从多种可能性中选择它。
然后,这个论点被这个工作所破坏:func k(i: Int) { }; func k(d: Double) { }; k(.i)
。所以也许这是一个错误 - 但无论如何它都值得商榷。