所以我知道这Void
用于表示函数不接受或返回值.在Swift中,Void
实际上是空元组的类型别名()
.
有趣的是(在Beta 6中),您甚至可以声明类型的变量Void
:
var x: Void
println(x)
x = test()
func test() {}
Run Code Online (Sandbox Code Playgroud)
这些陈述都是合法的.该println()
打印"()".
到目前为止,我无法弄清楚这可以用于什么.为什么你需要一个不能保存任何值的变量?有没有人知道这方面的实际用途,还是这只是Swift的一个怪癖?
注意:这是我对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:在任何人问之前:是的,我确实想借口做一个人为的例子; 它只是为了测试我编写复杂类型的能力.
我遇到了一个实际示例,该示例在处理泛型时很有用。我有一个通用类,可以围绕异步任务创建包装器。该类的方法之一允许发布结果。
将其分解为一个简化的示例:
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)