void类型的变量

Ato*_*mix 14 types void swift

所以我知道这Void用于表示函数不接受或返回值.在Swift中,Void实际上是空元组的类型别名().

有趣的是(在Beta 6中),您甚至可以声明类型的变量Void:

var x: Void
println(x)
x = test()

func test() {}
Run Code Online (Sandbox Code Playgroud)

这些陈述都是合法的.该println()打印"()".

到目前为止,我无法弄清楚这可以用于什么.为什么你需要一个不能保存任何值的变量?有没有人知道这方面的实际用途,还是这只是Swift的一个怪癖?

Con*_*has 6

注意:这是对Apple Dev论坛中交叉发布问题的回复的交叉点.

这是因为斯威夫特似乎有点学术上的好处(这是斯威夫特的加分之一!:-)).

数学函数是某些输入(参数)和某些输出(返回值)之间的关系.而不是定义一个不适用的整个类(例如"子程序"或"过程")(没有输出,具体而言),Swift只是将"过程"定义为与某些输入集合(可能为空)的关系,一组空的输出.

但它有一些好处,虽然不常见(至少在功能编程成为语言和社区中更具主导性的风格之前).一个小例子:

infix operator ~~ { precedence 10 associativity right }
func ~~(l: A -> B, r: A) -> B {
     return l(r)
}

let productsSoldIn2014 = productOfSales ~~ salesInYears ~~ [2014]
let salespersonsInvolvedIn2014Sales = salespersonsOfSales ~~ salesInYears ~~ [2014]

fireSalespersons ~~ salespersonsOfSales ~~ salesInYears ~~ [2014]   // Awful companies only.

func salesInYears(_ y: [Int]) -> [Sale] { … }
func productsOfSales(_ s: [Sale]) -> [Product] { … }
func salespersonsOfSales(_ s: [Sale]) -> [SalesPerson] { … }
func fireSalespersons(_ s: [SalesPerson]) -> () { … }               // The appended arrow and null tuple can be left out.
Run Code Online (Sandbox Code Playgroud)

我已经定义了一个"链接"操作符~~(想象一个弯曲链),它从右到左,通过链推送一个值.通过一些适当命名的函数,我们可以声明性地定义我们需要的值.(使用惰性集合而不是数组,我们接近Haskell范例.除非我弄错了,否则~~这里是一个标识monad.或者它只是一个组合运算符.)

第三个声明(在两个允许之后)触发了在2014年出售任何东西的销售人员.注意虽然~~想要返回"fireSalespersons"的值(以继续左边的链,这里不存在),在Swift中是有效的 - 它只是零元组,我们丢弃它.没有返回值的函数不应该与运算符一起工作(没有重载它).

顺便说一句,这也是有效的:

increaseCEOBonus(35000) ~~ fireSalespersons ~~ salespersonsOfSales ~~ salesInYears ~~ [2014]      // Really awful companies only.
//         () -> ()  ~~  [Salesperson] -> ()  ~~  [Sales] -> [Salesperson] …

func increaseCEOBonus(amount: Int)() { … }
Run Code Online (Sandbox Code Playgroud)

在这个例子中,最左边的链是无值的 - 它仍然右边后面,但是没有任何值传递到左边.我不推荐这种用法,最好简单地在一个单独的行上枚举它们.

要回到你的问题,因为"没有"可以消耗(通过参数),明确禁止将"无"分配给变量 - 参数是变量是愚蠢的.

PS:在任何人问之前:是的,我确实想借口做一个人为的例子; 它只是为了测试我编写复杂类型的能力.


Dal*_*ale 5

我遇到了一个实际示例,该示例在处理泛型时很有用。我有一个通用类,可以围绕异步任务创建包装器。该类的方法之一允许发布结果。

将其分解为一个简化的示例:

class Foo<T>  {

    var x : T?

    func finishWith(result:T) {
        x = result
        // do more stuff here as a side effect of posting the result
    }
}
Run Code Online (Sandbox Code Playgroud)

问题是您是否需要无效结果,即

var foo = Foo<Void>()
Run Code Online (Sandbox Code Playgroud)

您如何称呼该finishWith:result方法?

您可以创建一个值为void的变量,也可以使用'()'作为文字的void值:

foo.finishWith(result: ())
Run Code Online (Sandbox Code Playgroud)