Swift类型推断需要问号或感叹号

时间:2017-01-02 21:33:48

标签: ios swift xcode

在阅读了Apple的ARC指南之后,我慢慢地试图掌握保留周期但是我不清楚的是,快速的类型推断需要可选的问号或者在类的全局范围内推断变量时强制解包感叹号。

例如:

import XCTest
@testable import PassionProject

class ItemManagerTests: XCTestCase {

    var sut: ItemManager!

    override func setUp() {
        super.setUp()
        // Put setup code here. This method is called before the invocation of each test method in the class.

        sut = ItemManager()
    }

    override func tearDown() {
        // Put teardown code here. This method is called after the invocation of each test method in the class.
        super.tearDown()
    }

    func tests_ToDoCount_Is_InitiallyZero() {

        XCTAssertEqual(sut.toDoCount, 0)
    }

    func tests_DoneCount_Is_InitiallyZero(){

        XCTAssertEqual(sut.doneCount, 0)
    }
}

如果我在下一行中省略了问号或解释点,则会引发关于没有初始化程序的类的错误:

var sut: ItemManager

我的问题是,是不是简单地说这个变量属于这种类型?如果是这样的话,为什么Xcode认为它不是一个属性,如果我们没有给它一个初始值?第二,如果我们从未设置其值,为什么强制展开推断类型编译?

如果需要,这里是我们使用的对象的代码作为示例,并提前感谢您更好地掌握:

import Foundation

class ItemManager {

    let toDoCount = 0

    let doneCount = 0

}

2 个答案:

答案 0 :(得分:5)

那不是类型推断。如果您声明变量的类型,则推理不会发生。如果您没有明确说出,那么推论就是要弄清楚(推断)类型是什么

您遇到Swift初始化程序规则问题。如果您声明某个类具有此属性:

var sut: ItemManager

然后,这是非可选的,这意味着在初始化完成时必须有一个值。你不这样做,所以Swift抱怨你的初始化者。您可以添加一个赋值的init方法,也可以声明它并同时指定一个值 - 这可能如下所示:

var sut: ItemManager = ItemManager()

如果你这样声明:

var sut: ItemManager?

然后它是可选的,这意味着如果你没有分配一个值,那么它的值为nil。您不必在初始化期间分配值,因为它已经有一个值。

答案 1 :(得分:2)

出于安全原因,Swift要求所有变量始终保持一个值。这可以防止变量值可能未知的情况。但是,在编程中仍然存在需要表示缺少值的情况。一个很好的例子就是执行搜索。人们希望能够从搜索中返回一些表明没有找到值的内容。

因此在Swift中,类成员在声明时必须有一个值。默认情况下,特定类型的成员,例如,Int不能为nil并且它不会获得默认值。如果我们知道该值变量可能为nil然后我们将其定义为Optional。

现在您有三个选项可以为类成员提供初始值:

  1. 在声明时初始化

  2. 在init方法中提供一个值

  3. 将其定义为可选或未包装的可选项,取决于变量的使用