Cla*_*oft 5 generics parsing ambiguity swift ambiguous-grammar
考虑以下 Swift 表达式
println(Generic<Foo, Bar>(1))
Run Code Online (Sandbox Code Playgroud)
Normally, one would read this as a generic call to the constructor Generic<Foo, Bar>
with the arguments (1)
.
println( Generic<Foo,Bar>(1) )
Run Code Online (Sandbox Code Playgroud)
However, when re-arranging the tokens a bit, it could also represent two separate comparisons, for example if Generic
and Foo
were some poorly named numeric variables:
println(Generic < Foo, Bar > (1))
// or, with proper parenthesis
println((Generic < Foo), (Bar > 1))
Run Code Online (Sandbox Code Playgroud)
What we can observe here is that an expression with a generic constructor like this is highly ambiguous, and not easy to disambiguate even for humans. The problem here is that Swift doesn't have a new
keyword for constructors, which makes them ambiguous with method calls and operators in some cases. Thus, I am interested in how the Swift compiler (parser) manages to disambiguate the above expressions. Is the way it is parsed dependant on the context (types, variables, functions) or can it be resolved by the parser?
答案很简单:编译器根本不允许您声明这些变量:
struct Generic<T, U> {
init(_ i: Int) {}
}
struct Foo {}
struct Bar {}
print(Generic<Foo, Bar>(1))
// error
let Foo = 0 // invalid redeclaration of Foo
let Bar = 3 // invalid redeclaration of Bar
let Generic = 5 // invalid redeclaration of Generic
print(Generic<Foo, Bar>(1))
Run Code Online (Sandbox Code Playgroud)
将另一个源文件中的变量或类型声明设置为当前声明将“覆盖”另一个。