2017-01-02 101 views
0

在閱讀Apple的ARC指南後,我慢慢嘗試瞭解保留週期,但不清楚的是swift的類型推斷需要可選問號或強制展開當在一個類的全局範圍內推斷一個變量時感嘆號。Swift Type推理需要問號或感嘆號

例如:

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 

} 

回答

4

那不是類型推斷。如果你聲明一個變量的類型,推理不會發生。如果你沒有明確地說明,推論全是關於如何計算(推斷)什麼類型是

你遇到了Swift初始化規則的問題。如果您聲明一個類有此屬性:

var sut: ItemManager 

那麼這是不可選的,這意味着它必須有時間初始化值是完全。你沒有這樣做,所以Swift抱怨你的初始化器。您可以添加一個init方法分配一個值,或者你可以把它聲明並分配在同一時間 - 一個值,它可能是這樣的:

var sut: ItemManager = ItemManager() 

如果你聲明它是這樣的:

var sut: ItemManager? 

然後它是可選的,這意味着如果你不分配一個值,那麼它的值爲零。您不必在初始化期間分配值,因爲它已經有一個值。

+1

如果您正在分配,請不要明確說明類型。讓推理完成它的工作:'var sut = ItemManager()' – Alexander

1

爲安全起見,Swift要求所有變量始終保持一個值。這可以防止變量的值可能未知的場景。但是,在編程中仍然存在一些想要表示缺少值的情況。一個很好的例子是執行搜索時。人們希望能夠從搜索中返回指示沒有找到值的內容。

因此,在Swift中,類成員在聲明時必須有一個值。默認情況下,特定類型的成員,例如,Int不能爲零,並且不會獲得默認值。如果我們知道一個變量的值可能爲零,那麼我們將其定義爲一個可選項。

現在,你有三種選擇,以提供一個初始值類成員:

  1. 通過在聲明

  2. 時初始化它通過在init()方法提供一個值

  3. 通過將其定義爲可選或展開的可選項,取決於使用變量