void类型的变量

时间:2014-08-25 12:40:54

标签: types swift void

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

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

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

func test() {}

这些陈述都是合法的。 println()打印“()”。

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

3 个答案:

答案 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")
}