swift - Swift 如何消除表达式上下文中类型参数的歧义?

标签 swift generics compiler-construction grammar ambiguous-grammar

看看下面两个表达式:

baz(Foo<Bar, Bar>(0))
baz(Foo < Bar, Bar > (0))

不知道是什么,baz , FooBar是(baz 可以是类型或方法,FooBar 可以是类型或变量),无法消除< 是否存在歧义。表示类型参数列表或小于运算符。

// two different outcomes, difference shown with parentheses
baz((Foo<Bar,Bar>(0)))      // generics
baz((Foo < Bar), (Bar > 0)) // less-than

任何理智的编程语言都不应该依赖于什么baz , FooBar是在解析这样的表达式时。然而,无论我在何处放置空格,Swift 都设法消除了以下表达式的歧义:

println(Dictionary<String, String>(0))
println(Dictionary < String, String > (0))

编译器如何管理这个?而且,更重要的是,Swift 语言规范中是否有任何位置。其中描述了规则。翻看Language Reference Swift书的一部分,我只找到了这一段:

In certain constructs, operators with a leading < or > may be split into two or more tokens. The remainder is treated the same way and may be split again. As a result, there is no need to use whitespace to disambiguate between the closing > characters in constructs like Dictionary<String, Array<Int>>. In this example, the closing > characters are not treated as a single token that may then be misinterpreted as a bit shift >> operator.

什么是certain constructs在这种情况下指的是?实际语法只包含一个提到类型参数的产生式规则:

explicit-member-expression → postfix-expression­ . ­identifier­generic-argument-clause­opt

任何解释或资源将不胜感激。

最佳答案

感谢@Martin R,我找到了编译器源代码的相关部分,其中包含解释它如何解决歧义的注释。

swift/ParseExpr.cpp, line 1533 :

///   The generic-args case is ambiguous with an expression involving '<'
///   and '>' operators. The operator expression is favored unless a generic
///   argument list can be successfully parsed, and the closing bracket is
///   followed by one of these tokens:
///     lparen_following rparen lsquare_following rsquare lbrace rbrace
///     period_following comma semicolon

基本上,编译器会尝试解析类型列表,然后检查右尖括号后的标记。如果那个 token 是

  • 右括号、方括号或大括号,
  • 在其自身和右尖括号之间没有空格的左括号、括号或句点(>(>[,但不是 > (, > [),
  • 左大括号或
  • 逗号或分号

它将表达式解析为通用调用,否则将其解析为一个或多个关系表达式。

如书中所述Annotated C# ,问题在 C# 中以类似的方式解决。

关于swift - Swift 如何消除表达式上下文中类型参数的歧义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36387657/

相关文章:

ios - 使用 SKReferenceNode 引用的 SpriteKit 场景未加载自定义类

swift - 转换为 typeof(self)

c# - 来自参数的通用 T 而不是手动指定

java - .java 和 .scala 类之间是否存在循环依赖?

ios - 将 CollectionView 照片传递到电子邮件附件 iOS swift

swift - 将字符串拆分为每个数组中具有最大变量的数组

java - 在 Java 运行时使用泛型 - (T)object - 进行强制转换会发生什么情况?

c# - 编译器错误取决于方法签名中的参数位置。使用未分配的局部变量

c# - 多余的通用参数?

c# - 通用列表性能优化