Swift语法显式成员表达式

时间:2016-02-14 00:09:59

标签: swift generics grammar

在Swift书的grammar section中有两个语法声明:

explicit-member-expression  ->  postfix-expression  .  decimal-digits
explicit-member-expression  ->  postfix-expression  .  identifier  generic-argument-clause[opt]

第一个用于访问元组:

var tuple = (1, 2, 3)
tuple.1 = tuple.2

第二个用于访问其他成员,如属性和函数:

struct S {
    var property = 0
    func function<T>(parameter: T) {}
}

S().property
S().function(3)

但是我找不到可选generic-argument-clause的使用方法。在这些成员之后禁止:

S().property<Int>   // error: '>' is not a postfix unary operator
S().function<Int>(3) // error: cannot explicitly specialize a generic function

那么在哪种情况下我们可以使用generic-argument-clause s?

1 个答案:

答案 0 :(得分:2)

模块的成员表达式的通用参数子句

generic-argument-clause可能只有模块SomeModule.SomeGeneric<SomeType>())的用例。来自Language Reference - Expressions

  

明确的成员表达

     

显式成员表达式允许访问已命名的成员   类型,元组,或模块。它由一段时间(。)组成   item及其成员的标识符。

举个例子:

/* Module 'MyLib.a' ... */
class MyClass<T> {
    var foo: T?
}

/* ... elsewhere: explicit member expression to module */
MyLib.MyClass<Int>()

奇怪的是,implicit member expressions不包含generic-argument-clause[opt]的语法,我们可以将其解释为隐式游标,后者对于显式成员表达式,至少不涉及枚举;可能会略微提升这个仅涉及模块的理论。

  

隐性成员表达的语法

implicit-member-expression → .­identifier­

除模块之外的其他用例?

我不能肯定上述内容仅适用于模块,但我无法在成员表达式的上下文中找到泛型参数子句的任何其他用法。

下面是一些有关讨论背景的相关参考摘录;除了模块之外,它可能对其他人的调查具有一定的价值。

首先,什么是泛型参数子句?来自Language Reference - Generic Parameters and Arguments - Generic Argument Clause

  

泛型参数子句指定泛型类型的类型参数。

     

...

     

泛型参数列表是以逗号分隔的类型参数列表。   类型参数是替换a的实际具体类型的名称   a的泛型参数子句中对应的类型参数   通用类型。结果是该泛型的专用版本   类型。

     

...

     

通用Dictionary类型的专用版本,   通过替换泛型来形成Dictionary<String, Int>   带有具体类型的参数Key: HashableValue   参数StringInt

现在,同一部分包含以下语句:

  

通用参数条款中所述,您不使用泛型   argument子句,用于指定泛型函数的类型参数   或初始化。

我们跳转到通用参数条款部分并阅读:

  

... 与通用类型相比,您没有指定通用类型   使用泛型函数或初始值设定项时的参数子句。该   而是从参数的类型推断出类型参数   传递给函数或初始化器。

因此,对于这个问题的主题,我们应该关注成员表达式和(.泛型类型的右侧;不是通用功能。但是在什么情况下---除了模块---我们可以将这两个和泛型参数子句结合起来吗?可能会想到的第一个是具有关联泛型类型的enum

enum Bar<T> {
    case One(T)
    case Two
}

var foo = Bar.One(1)
print(foo.dynamicType) // Bar<Int>

但这是类型推断,而不是泛型参数子句。

从上面的内容来看,我只能将模块视为成员表达式上下文中语法generic-argument-clause的用例。