为什么在块swift之外看不到在块中分配给未初始化变量的值?

时间:2019-05-10 00:11:37

标签: swift scope declare

在Swift5中声明w / o值的机制是什么?第一个分配是否成为真实的声明?

而且,我们应该避免在Swift中声明无值吗?

var v:String;
if true {
    v = "Hello"
    print(v) // print "Hello" when without the print below
}
print(v) // variable 'v' used before being initialized
var v:String="";
if true {
    v = "Hello"
    print(v) // print "Hello"
}
print(v) // print "Hello"

2 个答案:

答案 0 :(得分:2)

好吧,该消息不是很有帮助,这就是问题所在。这种模式(我称为计算的初始化)完全合法且有用,而且-令人惊讶的是,您甚至可以使用using System.Windows; namespace MyWPFApp { public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void Button_Click_Poke_Kilroy(object sender, RoutedEventArgs e) { textBlock.Text = " \\|||/\r\n" + " (o o) \r\n" + "----ooO- (_) -Ooo----"; } } } 代替let。但是在使用它之前,必须通过所有可能的路径来初始化未初始化的变量 。所以你有:

var

但是拿着我的啤酒,看看这个

var v:String
if true {
    v = "Hello"
}
print(v) // error

甚至:

var v:String
if true {
    v = "Hello"
} else {
    v = "Goodbye"
}
print(v) // fine!

很棒,是吗?

现在,您可能会说:好的,但是let v:String if true { v = "Hello" } else { v = "Goodbye" } print(v) // fine! 永远都是正确的,因此让我满足“所有路径”规则是很愚蠢的。太糟糕了!编译器仍然坚持执行,然后在以后警告您true不会执行的情况下让您离开。但是警告可以编译。错误不会。事实是,您的示例是非常人为的。但这是现实生活中的可能性:

else

这种事情不仅合法,而且实际上是苹果在某些棘手的情况下推荐的模式。例如,它用在苹果自己的example code中,展示了如何使用Swift 5 Result结构:

let v:String
if self.someBoolProperty {
    v = "Hello"
} else {
    v = "Goodbye"
}
print(v) // fine!

答案 1 :(得分:0)

所以这是因为swift编译了您的代码,并注意到在使用之前未声明您的值var v:String;,这使它成为“可选”值。即使您在if语句中分配它,但如果要摆脱true值,则if语句可能永远不会运行,因此不会在v中存储任何值,因此将使用它在“分配”之前。

因此,如果您希望您的值是一个可选且可能为空的值,请回答v,将其声明为以下var v:String?,如果您希望它是一个非可选值,且该值始终存储在v中您应将其声明为以下var v = ""。 Swift会将这个声明解释为String。

要回答第二个问题,允许100%快速定义无值,这实际上取决于您如何处理代码。我一直在代码中使用可选值,但是我不一定喜欢可选值,因此,我通常喜欢以这种方式声明我的值,例如var v = "",如果该值是我的UI或其他任何我要操纵的值不会破裂。但是,如果我需要确保存在一个值,则必须将我的值设置为可选值,以便可以使用if语句检查它是否为有效值。

我要说的简短版本是,您收到编译器警告,因为您将v声明为非可选值,而不是可选值。