Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift T、 可选<;T>;vs.Void,可选<;无效>; //变量的此声明/定义与预期一样正常 变量i=可选。无 var j:Int? //对于下一行代码,编译器生成一个很好的警告 //推断变量“v1”的类型为“Optional”(也称为“Optional”),这可能是意外的 var v1=可选。无 //但下一句话不会产生任何警告 var v2:无效? //非可选版本产生“相同方式”警告 //变量“v3”推断为具有类型“()”,这可能是意外的 var v3=Void() //但是编译器对下一个代码感觉很好 var v4:Void=Void()_Swift - Fatal编程技术网

Swift T、 可选<;T>;vs.Void,可选<;无效>; //变量的此声明/定义与预期一样正常 变量i=可选。无 var j:Int? //对于下一行代码,编译器生成一个很好的警告 //推断变量“v1”的类型为“Optional”(也称为“Optional”),这可能是意外的 var v1=可选。无 //但下一句话不会产生任何警告 var v2:无效? //非可选版本产生“相同方式”警告 //变量“v3”推断为具有类型“()”,这可能是意外的 var v3=Void() //但是编译器对下一个代码感觉很好 var v4:Void=Void()

Swift T、 可选<;T>;vs.Void,可选<;无效>; //变量的此声明/定义与预期一样正常 变量i=可选。无 var j:Int? //对于下一行代码,编译器生成一个很好的警告 //推断变量“v1”的类型为“Optional”(也称为“Optional”),这可能是意外的 var v1=可选。无 //但下一句话不会产生任何警告 var v2:无效? //非可选版本产生“相同方式”警告 //变量“v3”推断为具有类型“()”,这可能是意外的 var v3=Void() //但是编译器对下一个代码感觉很好 var v4:Void=Void(),swift,Swift,有什么区别?如果类型不是“Void”,为什么Swift编译器总是很高兴?警告中的关键词是“推断”。Swift不喜欢推断Void,因为这通常不是您的意思。但是如果你明确地要求它(:Void),那就没关系了,如果这是你的意思,你将如何消除警告 识别哪些类型是推断的,哪些是显式的,这一点很重要。推断是“从证据和推理而不是从明确的陈述中推断或总结(信息)”。它不是“猜测”或“选择”的同义词。如果类型不明确,编译器将生成错误。类型必须始终定义良好。问题是它是明确定义的,还是通过基于明确信息的推理来定义的

有什么区别?如果类型不是“Void”,为什么Swift编译器总是很高兴?

警告中的关键词是“推断”。Swift不喜欢推断
Void
,因为这通常不是您的意思。但是如果你明确地要求它(
:Void
),那就没关系了,如果这是你的意思,你将如何消除警告

识别哪些类型是推断的,哪些是显式的,这一点很重要。推断是“从证据和推理而不是从明确的陈述中推断或总结(信息)”。它不是“猜测”或“选择”的同义词。如果类型不明确,编译器将生成错误。类型必须始终定义良好。问题是它是明确定义的,还是通过基于明确信息的推理来定义的

此语句具有类型推断:

// this declaration / definition of variable is OK, as expected
var i = Optional<Int>.None
var j:Int?

// for the next line of code compiler produce a nice warning
// Variable 'v1' inferred to have type 'Optional<Void>' (aka 'Optional<()>'), which may be unexpected
var v1 = Optional<Void>.None

// but the next sentence doesn't produce any warning
var v2:Void?

// nonoptional version produce the warning 'the same way'
// Variable 'v3' inferred to have type '()', which may be unexpected
var v3 = Void()

// but the compiler feels fine with the next
var v4: Void = Void()
let x = Foo()
Foo()
的类型是明确已知的,但是
x
的类型是根据整个表达式的类型推断出来的(
Foo
)。它的定义很明确,完全没有歧义,但它是推断出来的

此语句没有类型推断:

// this declaration / definition of variable is OK, as expected
var i = Optional<Int>.None
var j:Int?

// for the next line of code compiler produce a nice warning
// Variable 'v1' inferred to have type 'Optional<Void>' (aka 'Optional<()>'), which may be unexpected
var v1 = Optional<Void>.None

// but the next sentence doesn't produce any warning
var v2:Void?

// nonoptional version produce the warning 'the same way'
// Variable 'v3' inferred to have type '()', which may be unexpected
var v3 = Void()

// but the compiler feels fine with the next
var v4: Void = Void()
let x = Foo()
但是,这里也没有类型推断:

let x: Foo = Foo()
第二行中的
x
Foo?
)类型是显式的,因为它是在上一行中显式定义的

这就是为什么您的一些示例会生成警告(当存在
Void
推断时),而其他示例不会生成警告(当仅显式使用
Void
时)。为什么我们关心推断的
无效
?因为它很容易偶然发生,而且几乎没有任何用处。例如:

var x: Foo? = nil
x = Foo()
var i = Optional<Int>()
这是合法的Swift,但它会生成“推断为具有类型“()””警告。这是一个很容易犯的错误。如果您试图分配某个不返回结果的结果,则至少需要一个警告

那么,我们怎么可能分配不返回结果的结果呢?这是因为每个函数都返回一个结果。如果返回值为
Void
,我们只允许忽略该信息。重要的是要记住,
Void
并不意味着“没有类型”或“什么都没有”。它只是
()
的类型别名,它是一个由零元素组成的元组。它与
Int
一样有效

上述代码的完整形式为:

func foo() {}
let x = foo()
这会返回相同的警告,因为它是相同的东西。我们可以删除
->()
返回()
,但它们是存在的,因此如果需要,我们可以将
()
分配给
x
。但我们不太可能想这么做。我们几乎肯定犯了错误,编译器警告我们这一点。如果出于某种原因我们想要这种行为,那没关系。这是合法的。我们只需明确说明类型,而不是依赖类型推断,警告就会消失:

func foo() -> () { return () }
let x = foo()
Swift在您的示例中生成警告时非常一致,您确实需要这些警告。这完全不是武断的


编辑:您添加了不同的示例:

let x: Void = foo()

这明确地引用了
Optional.init()
,并返回
nil
编译器警告您“dummy”类型
Void
,它实际上是空元组的别名
()
,并且没有太多用法

如果您没有明确指定希望变量的类型为
Void
,并让编译器推断该类型,它将对此发出警告,因为您可能一开始就不想这样做

例如:

var x: Foo? = nil
x = Foo()
var i = Optional<Int>()
将给您一个警告,因为无论如何只有一个可能的值
doSomething()
可以返回-一个空元组

另一方面,

func doSomething() -> Void {
}

let a = doSomething()

当您明确告诉编译器您需要一个
Void
变量时,不会生成警告。

v2
仅声明,请尝试为其赋值,并查看编译器是否可以使用that@Cristicv2有默认值nil这是一个查找,我发现了相同的结果。为什么其他类型的人没有警告?顺便说一下,看看func f()throws->Void和一些有价值的用法,比如guard let v=try?f()(将在运行时知道)Rob,拜托,你能比较一下这两句话吗?var v=Optional();var i=Optional()我删除了关于
Any
的讨论。我记得对
Any
AnyObject
进行了特殊处理,但我最近的测试表明,它们与其他协议得到了相同的处理。我不确定这是否是Swift更高版本中的变化(我记得在Swift的早期版本中有一个关于
AnyObject
的特别警告),但现在看来肯定不是这样。非常感谢你的更新!特别是它的第一段。是的,正如你所写的“Swift不喜欢推断Void,因为它通常不是你的意思”似乎是真的,不幸的是没有任何真正的原因。实际上这不是一个大问题。我的期望是编译器