所以我知道Void
用于表示函数不接受或返回值。
在Swift中,Void
实际上是空元组()
的类型别名。
有趣的是(在Beta 6中),您甚至可以声明Void
类型的变量:
var x: Void
println(x)
x = test()
func test() {}
这些陈述都是合法的。 println()
打印“()”。
到目前为止,我无法弄清楚这可以用于什么。为什么你需要一个不能保存任何值的变量?有没有人知道这方面的实际用途,还是这只是Swift的一个怪癖?
答案 0 :(得分:6)
注意:这是Apple发布论坛中交叉发布问题的my reply的交叉点。
这是因为斯威夫特似乎有点学术上有利(它是斯威夫特的加分之一!:-))。
数学函数是某些输入(参数)和某些输出(返回值)之间的关系。 Swift只是定义一个"而不是定义一个完整的类(例如"子程序"或者#34;程序"),这些不适用(没有输出)。过程"作为与一组输入(可能为空)和一组空输出的关系。
虽然它有一些好处,虽然不常见(至少在功能编程成为语言和社区中更具主导性的风格之前)。一个小例子:
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.
我已定义了一个"链接"算子~~
(想象一个弯曲链),从右到左,通过链推动一个值。通过一些适当命名的函数,我们可以声明性地定义我们需要的值。 (使用惰性集合而不是数组,我们接近Haskell范例。除非我错了,~~
在这里是一个标识monad。或者它只是一个合成运算符。)
第三个声明(在两个允许之后)解雇了2014年出售任何东西的销售人员。注意~~
想要返回" fireSalespersons"的价值(到继续左边的链,这里不存在),在Swift中它是有效的 - 它只是空元组,我们丢弃它。没有返回值的函数不应该与运算符一起工作(没有超载)。
顺便说一句,这也是有效的:
increaseCEOBonus(35000) ~~ fireSalespersons ~~ salespersonsOfSales ~~ salesInYears ~~ [2014] // Really awful companies only.
// () -> () ~~ [Salesperson] -> () ~~ [Sales] -> [Salesperson] …
func increaseCEOBonus(amount: Int)() { … }
在这个例子中,最左边的链是无值的,它在之后仍然,但是没有传递给左边的任何值。我不推荐这种用法,最好只是在一个单独的行上枚举它们。
回到你的问题,因为"没有"可以被消费(通过参数),明确禁止"没有"是愚蠢的。被分配给变量参数的是变量。
P.S。:在任何人问之前:是的,我确实想借口做一个人为的例子;它只是为了测试我编写复杂类型的能力。答案 1 :(得分:4)
我遇到了一个实际的例子,它在处理泛型时非常有用。我有一个泛型类,它创建一个围绕异步任务的包装器。该类的一种方法允许发布结果。
将其分解为一个简化的例子:
class Foo<T> {
var x : T?
func finishWith(result:T) {
x = result
// do more stuff here as a side effect of posting the result
}
}
问题是你是否需要Void结果,即
var foo = Foo<Void>()
如何调用finishWith:result
方法?
您可以创建值为void的变量,也可以使用&#39;()&#39;作为字面无效值:
foo.finishWith(result: ())
答案 2 :(得分:2)
可能稍微有用的是Void?
类型,可用于存储,例如一个try?
语句,它不会返回值,但您仍想检查以下内容是否成功:
let someString = "foo"
let saved: Void? = try? someString.write(toFile: "somePath", atomically: false, encoding: .utf8)
if (saved == nil) {
print("didn't save")
}