Swift变量 - 为什么这么多?

时间:2016-01-22 19:18:39

标签: ios swift

Swift(或者至少Xcode)在创建不会改变的变量时甚至推荐let vs var似乎非常聪明 - 甚至是特殊的_变量名称

但对于很多let个变量,我们只是为了将它们传递给另一个函数而创建它们。为什么我们不把这个任务的“右侧”放在原位。

所以,而不是:

if let url = NSURL(string: "http://xyzapi.com") {
  if let data = NSData(contentsOfURL: url) {
    self.myArray.append(data)
  }
}

......我们可以说:

if let data = NSData(contentsOfURL: NSURL(string: "http://xyzapi.com")!) {
  self.myArray.append(data)
}

我已经尝试了这个,似乎工作得很好。但是每个示例,教程,示例代码等都有单步创建(和解包)自己的变量 - 即使是不可能为空的东西(如硬编码)字符串“xyzapi.com”)。

请不要陷入确切的例子中。这不是关于NSData或NSURL的问题,而是创建这么多无用变量的想法。

在其他语言中,我倾向于不在实时/生产代码中创建变量,除非我需要它们。 Swift有什么特别的东西可以让它好或者(可能)因为我正在看教程吗?

4 个答案:

答案 0 :(得分:2)

这在很大程度上是一种风格问题(因此很容易以意见为基础),但无论如何都试图提供帮助......

您提供的选项之间的运行时间差别不大。这真的是两个问题:

你想要防御性地编码吗?

NSURL.init(string:)是一个可用的初始化程序 - 并非每个字符串都是有效的URL,因此API会让您考虑如何处理传递非有效URL的字符串的情况。同样地,NSData.init(contentsOfURL:)可能由于多种原因而失败,因此您需要为无结果做好准备。

现在,您对可能失败的准备可能只是忽略它(即结果为零时什么都不做)或让您的应用程序崩溃。所以在某种意义上这个问题没有实际意义--Swift至少需要一个基本级别的防御性编程,要求你处理空选项的情况,无论是通过if-letguard-let,可选链接还是强制解包。

如果你在防御性编码,你想如何处理失败?

因此,一旦你进行防御性编码,你需要决定你想要的防守程度。你有什么假设,你想坚持这些假设的速度有多快?

对于您示例中的第一种情况,当输入字符串不是有效的URL时,存在NSURL.init(string:)失败的问题。你传递的是一个常量字符串文字,所以你可能知道(或者你会在开发过程中很快发现)你是否有一个有效的URL。并且您肯定知道该URL的有效性在运输应用程序中的运行时永远不会改变。

因此,您完全有理由展开结果(!中的NSURL(string: "http://xyzapi.com")!)。即使强制解包会导致应用程序崩溃,如果可选项为nil,非常有理由强制解包存在是允许您在可以断言真相的情况下减少样板编译器不能。

现在,一些开发人员认为Force Unwrap是一个黑暗的力量,并坚持在所有情况下避开它。这就是为什么你看到做这样的事情的教程:

if let url = NSURL(string: "http://xyzapi.com") {
    // ...
}

这种方法有一个好处,因为在你的字符串包含无效网址的情况下,force-unwrap会崩溃,而if-let则不会。

但仍有一个问题是,这实际上是否是一个理想的好处。在NSURL.init(string:)失败的情况下,此示例不执行任何其他操作 ...因此,大括号之间的任何内容都不会发生,并且在大括号继续之后应该发生什么无论如何。这可能会导致您的应用在以后出现其他问题,您将不知道原因。

使用force-unwrap,你知道失败的确切位置,因为你在那里崩溃,并且因为你强制解包在编译时保持不变的东西,你可以断言对常量字符串文字的一个修复是好的对于所有情况。

如果你足够迂腐以避免强行解缠,那么你也应该足够迂腐以实际处理你的错误。也就是说,你应该这样做:

if let url = NSURL(string: "http://xyzapi.com") {
    // use url
} else {
    // do something about the fact that there's no url
}

或者这个:

guard let url = NSURL(string: "http://xyzapi.com") 
    else { /* do something about no url */ }
// use url

答案 1 :(得分:1)

我还可以想象另一个原因:在调试时,您可能会查找局部变量和常量的内容。在创建NSURL实例时,它也可能抛出异常或以某种方式不可用。

我发现自己创造了不必要的"变量也只是为了让代码更容易理解,更容易调试。

如果你没有记录你做事的原因,你可以做的下一个最糟糕的事情是"未命名"。

答案 2 :(得分:0)

在第二个示例中,您强制解包网址可选,而在第一个示例中,您有条件地解除绑定,

此外,

在第一个示例中,您可以区分哪个文件正在归档。是否正在创建url对象。或者正在创建数据对象

答案 3 :(得分:-1)

if let x = something { 

}

在if语句中执行变量的展开,因此您可以不使用它!要么 ?。这通常比使用更安全,更清洁!或?,但并非总是如此。

例如

var x: Int? = nil

if let y = x {
    // Code will not be done
}

x = 3

if let y = x {
    // y will have a value of 3 and you won't need to use ! or ? to access it.
}