2017-08-03 35 views
0

以下沿着大书呆子牧场指南书我遇到了一个章节中的一段,要求您创建一个NumberFormatter的实例。一切正常,但我注意到,格式化使用创建closure为:NumberFormatter只能写在封闭

class ConversionViewController: UIViewController { 
    let numberFormatter: NumberFormatter = { 
     let nf = NumberFormatter() 

     nf.numberStyle = .decimal 
     nf.minimumFractionDigits = 0 
     nf.maximumFractionDigits = 1 

     return nf 
    }() 

    func updateCelsiusLabel() { 
     if let celsiusValue = celsiusValue { 
      celsiusLabel.text = numberFormatter.string(from: NSNumber(value: celsiusValue.value)) 
     } else { 
      celsiusLabel.text = "???" 
     } 
    } 
} 

只是出于好奇,我试图像封闭的外创建此格式:

let nf = NumberFormatter() 

nf.numberStyle = .decimal 
nf.minimumFractionDigits = 0 
nf.maximumFractionDigits = 1 

但得到的错误说

预计声明

我的问题是:

  1. 为什么不能NumberFormatters封闭外面在这种情况下, 创建?
  2. 括号()表示在 结束时表示什么?我的猜测是它是自我调用的,但为什么它需要成为?

到目前为止,我从来没有见过用这种方式写封闭。 Apple文档中是否有解释这一点的内容?

+0

您可以在创建格式化程序的位置共享更多代码吗? –

+0

可能的重复https://stackoverflow.com/questions/29835490/expected-declaration-error-using-swift/29835573#29835573 –

+0

@Ahhhhhhhh我更新了我的问题。让我知道这是否足够。 –

回答

1

NumberFormatter以及闭包实例在这里是一个红鲱鱼:问题是你试图直接在类型声明的范围内更改实例属性(nf)(尽管你没有显示我们所有的代码确实被包含在类型定义的范围内),但不在例如一个实例函数或一个初始化器。

比较用:

struct Foo { 
    var a = 1 
    a = 2 // Error: expected declaration 
} 

甲编译例子是:

struct Foo { 
    var a = 1 
    mutating func mutateMe() { 
     a = 2 // OK 
    } 
} 

至于你质疑2)()用于执行一个仅一次invokation的的括号闭包,其中闭包的返回用于实例化nf。如果您没有调用它,那么nf将是() -> NumberFormatter类型的封闭,而不是NumberFormatter的实际实例。比较:

struct Foo { 
    let a: Int = { 
     var a = 1 
     a = 2 
     return a 
    }() // instantiate 'a' of Foo by _once-only 
     // invoking a specified closure_. 
} 

比较相同的概念,而是一个类型声明/定义之外:

// this is a closure 
let aClosure:() -> Int = { _ in return 42 } 

// this is an invokation of a closure 
// (discarding the result) 
_ = aClosure() 

// this is also an invokation of a closure 
let num = { _ in return 42 }() // 'num' inferred to Int 
+0

我想我现在唯一的问题是在这种情况下类型注释的概念。 Swift中的变量足够聪明地确定闭包中的**返回值**是它的值吗? –

0

nf在这种情况下是一个实例属性。这本身就是一个拥有自己财产的阶级。当你声明

let nf = NumberFormatter() 

nf是你的,但有默认属性。你不能在声明中设置它的属性。你会得到这个错误。

enter image description here

1

第一个答案:我在测试你的游乐场代码片段,它并没有显示出任何错误。我想你可能会做一些与NumberFormatter无关的错误。

let nf = NumberFormatter() 
nf.numberStyle = .decimal 
nf.minimumFractionDigits = 0 
nf.maximumFractionDigits = 1 

第二个答案:封闭的结束花括号告诉斯威夫特立即执行关闭。如果省略这些圆括号,则试图将闭包本身分配给属性,而不是闭包的返回值。 App Doc

+1

显然,OP使用一个类。关于问题#1,类和游乐场的行为完全不同。 – vadian