Swift3 在Swift 3中,为什么函数的无效返回值为-gt;(),只是有时推断,但有时必须声明?

Swift3 在Swift 3中,为什么函数的无效返回值为-gt;(),只是有时推断,但有时必须声明?,swift3,syntax,closures,declaration,void,Swift3,Syntax,Closures,Declaration,Void,考虑以下代码: typealias bar = ()->() let foo:bar = { baz -> () in print("foobar") return () } let baz = foo() print("\(baz)") 哪些产出: 福巴 () 现在,如果我们改变这一行: let foo:bar = { baz -> () in typealias bar = ()->() 为此: le

考虑以下代码:

typealias bar = ()->()

let foo:bar = { baz -> () in
    print("foobar")
    return ()
}

let baz = foo()

print("\(baz)")
哪些产出:

福巴

()

现在,如果我们改变这一行:

let foo:bar = { baz -> () in
typealias bar = ()->()
为此:

let foo:bar = { baz in
typealias bar = ()
。。。然后什么也没发生。也就是说,
->()
由编译器进行推断。(注意:如果省略
return()
,编译器也会很高兴)

但是,同时,如果我们改变这一行:

let foo:bar = { baz -> () in
typealias bar = ()->()
为此:

let foo:bar = { baz in
typealias bar = ()
。。。然后,编译程序崩溃了,自杀了。为什么?

这似乎与Swift的文件相冲突,Swift的文件将
()
(又称
Void
)定义为:

未显式指定返回类型的函数的返回类型

根据该语句,由于
typealias bar=()->()
明确指定了返回类型,因此根据定义,它不能返回
()
——但它确实返回了!这是完全不合逻辑和自相矛盾的

有人能告诉我他们是怎么想的吗?这里的理由是什么


如果
->()
总是被推断出来,那么为什么还要推断呢?为什么不直接说
()
始终是一个函数,这样
()
总是返回
()

如果我没有弄错的话,这就是您所说的情况:

typealias bar = ()

let foo: bar = { baz -> () in
    print("foobar")
    return ()
}
赋值的右边是类型为
()->()
的闭包,它是未赋值的
foo
应具有类型bar(
()
),但只有在对闭包进行评估时才会出现这种情况,例如:

let foo: bar = { baz -> () in
    print("foobar")
    return ()
}()

如果我没弄错的话,这就是你所说的情况:

typealias bar = ()

let foo: bar = { baz -> () in
    print("foobar")
    return ()
}
赋值的右边是类型为
()->()
的闭包,它是未赋值的
foo
应具有类型bar(
()
),但只有在对闭包进行评估时才会出现这种情况,例如:

let foo: bar = { baz -> () in
    print("foobar")
    return ()
}()
我喜欢,但这里有另一个角度可能会有帮助

使用
typealias bar=…
声明,您正在定义一个类型。这一定义需要完整和明确。否则,类型系统将无法检查您稍后声明的内容是否为该类型的成员。这个声明提供了类型的完整签名——对于函数/闭包类型,这意味着它的一组参数类型和返回类型,即使两者都是
Void
(aka
()

使用
让foo:bar=…
声明一个值并声明它必须是该类型的成员。由于类型定义的某些部分已经已知(由于typealias),因此在声明类型的成员时无需重复它们:

  • 闭包不需要声明其返回类型,因为它是闭包所遵循的函数类型的一部分。您可以
    返回闭包中预期类型的任何值。(或者,由于函数类型定义了返回类型
    Void
    ,因此可以
    不返回任何内容。)
  • 闭包不需要声明其参数的类型,因为typealias也已经声明了。(或者,由于您唯一的参数类型是
    Void
    ,因此根本不需要声明参数。)
在定义已知类型的闭包时,省略闭包语法的一些部分是Swift的类型推断功能之一。你可以认为它等同于如何,如果你有一个<代码> EnUM Foo{{一个,两个,三} < /Cube >和一个<代码> FUNC条(Foo:FoO),你可以通过“<代码> >一个<代码> >一个调用(<代码> bar(一个)< />代码>)。code>Foo.one是该常数的完全限定名,但仅是
。one
就足够了,因为Swift可以推断
Foo
类型。

我喜欢,但这里有另一个角度可能会有帮助

使用
typealias bar=…
声明,您正在定义一个类型。这一定义需要完整和明确。否则,类型系统将无法检查您稍后声明的内容是否为该类型的成员。这个声明提供了类型的完整签名——对于函数/闭包类型,这意味着它的一组参数类型和返回类型,即使两者都是
Void
(aka
()

使用
让foo:bar=…
声明一个值并声明它必须是该类型的成员。由于类型定义的某些部分已经已知(由于typealias),因此在声明类型的成员时无需重复它们:

  • 闭包不需要声明其返回类型,因为它是闭包所遵循的函数类型的一部分。您可以
    返回闭包中预期类型的任何值。(或者,由于函数类型定义了返回类型
    Void
    ,因此可以
    不返回任何内容。)
  • 闭包不需要声明其参数的类型,因为typealias也已经声明了。(或者,由于您唯一的参数类型是
    Void
    ,因此根本不需要声明参数。)

在定义已知类型的闭包时,省略闭包语法的一些部分是Swift的类型推断功能之一。你可以认为它等同于如何,如果你有一个<代码> EnUM Foo{{一个,两个,三} < /Cube >和一个<代码> FUNC条(Foo:FoO),你可以通过“<代码> >一个<代码> >一个调用(<代码> bar(一个)< />代码>)。code>Foo.one
是该常数的完全限定名,但仅是
。one
就足够了,因为Swift可以推断
Foo
类型。

是的,但根据
()
的定义,
()
()->(
在意义上应该是等价的,因为
()
是未指定返回类型的函数返回的类型。然而,要为函数声明typealias,您必须始终指定一个返回类型,据我所知,因此他们的文档可能是ju