2015-06-28 27 views
11

我剛開始學習斯威夫特,最近發現了何時使用?,!,None或Lazy?

  1. 「正常」 變量(缺乏一個更好的名字):

    例如:var test1: String

  2. 「可選」變量

    ex:var test2: String?

  3. 「隱無包裝選配」

    例如:var test3: String!

  4. 懶變量

    例如:lazy var test4: String

我的理解是這樣的:

  1. 使用「可選」變量(?)當變量可能會或可能不會在將來百分點初始化

  2. 使用開始初始化「隱無包裝選配」(!)時該變量被保證被初始化

  3. 選配可經由被轉換爲無包裝隱選配「強制通過拆」

    例如:let possibleString: String? = "Hello" println(possibleString!)

  4. 使用「懶惰變量」時,有沒有必要的東西要設置直到初始化(看來這可以被用於()或()?!)

因此,我的問題是:

  1. 什麼時候使用選項1 - 沒有一個變量?沒有!

  2. 什麼時候使用通常用於singletons「懶」

  3. 我讀「懶」 - 爲什麼?

我在Java和C++術語方面經驗最豐富,如果這有助於我的背景回答。

編輯:這裏的一切,我發現(主要問題是「正常」 VS 「隱無包裝選配」

  1. 「正常」 變量必須初始化:(a)在(b)在使用前的相同範圍內(用法表示與對象有某些操作),(c)在末尾的init iff變量是一個字段注意:init的範圍就是一切在類的範圍內,而不在功能範圍內在課堂上。
  2. 打印隱式解包可選將打印「無」,但使用該變量的函數將引發運行時異常。同時,使用(根本不包括打印)一個正常變量將不允許程序根本編譯
  3. 使用的目的! 「(Nothing)是(a)由於程序將編譯(並且在變量實際被初始化的情況下正確運行)並且(b)不允許你在開始時初始化所有內容。 注意:如果它是一個正常變量的任何字段未聲明是編譯時錯誤。

回答

2

不完全是這樣。

所有變量必須在第一次使用之前初始化,並且所有類/結構存儲的屬性必須在相應的初始化程序中賦值。可選項並不是關於允許某些時候沒有初始化,而是關於被允許不包含任何價值,nil代表的價值,該價值對於這樣的變量仍然是完全初始化的。因此,如果在初始化時不能知道什麼東西,那麼這可能是您將使用某種可選項(例如,代表視圖)的地方。

隱式解包optionals是一種變量可能爲空的情況下的簡寫形式,但我們絕對相信,當我們真正使用它時,它將保存實際值(典型示例是視圖控制器中的屬性對視圖持有參考)。

強制解包不會將可選內容轉換爲隱式解包可選內容,而是會爲您提供一個值(如果可選不是nil),並在不存在異常時引發異常。

當您希望將其初始化推遲到後續階段時(實際首次使用該屬性時),將使用惰性屬性。通常的情況是,如果你需要訪問一個昂貴的資源來做到這一點(從磁盤加載大文件,通過網絡下載等),特別是如果可能有這種情況下,根本不會使用這種屬性(爲什麼加載它可能來自磁盤,如果我們不使用它可能?)。

+0

啊好吧,我什麼時候可以使用 var test1:String //沒有?和不 ! ? – AeonNeo

+1

你會寫幾千行Swift代碼,並最終找出答案。 – gnasher729

+1

@AeonNeo,這取決於你的設計。如果某物業的「沒有價值」是流量的一部分,則使用「?」。如果它幾乎總是有一個值,除了一些「特殊」期間,當它不會被訪問時,使用「!」。否則堅持「正常」財產。一般來說,如果你可以不使用可選項,就可以不用它們。這些可能有些棘手(尤其是隱含的解包)。 – courteouselk

1

讓我們來看看蘋果公司的例子

class Person { 
    var residence: Residence? 
} 

class Residence { 
    var numberOfRooms = 1 
} 

公寓實例有一個int屬性稱爲numberOfRooms,有1人情況下的默認值有型住宅的可選住宅物業?

如果您創建一個新的Person實例,則其居住屬性默認初始化爲nil,因爲它是可選的。

如果你需要財產默認值是零 - 使用可選。使用變量沒有?和! - like'numberOfRoom' -

您可以在初始化程序中設置存儲屬性的初始值,如上所示。或者,指定默認屬性值作爲屬性聲明的一部分。您可以通過在定義屬性時指定初始值來指定默認屬性值。

注意

如果屬性始終以相同的初始值,提供一個默認值 而不是一個初始化內設置的值。結果 的結果是相同的,但默認值更緊密地將其屬性的 初始化與其聲明關聯。它使得初始化器更簡潔,並且使您能夠從其默認值推斷出屬性 的類型。默認值還使您更容易利用默認初始值設定項和初始值設定項繼承。

2.!用於在不是nil時訪問包含在變量內部的值,否則拋出exeption。所以,你可以使用!爲了使標記爲你類的用戶 - '這個值不會是零的時候,你解開它

懶惰變量用於當你想稍後初始化它,而不是在整個對象創建時,但恰好在你要求getter獲取數據的時候。

lazy var players: [String] = { 
     var temporaryPlayers = [String]() 
     temporaryPlayers.append("John Doe") 
     return temporaryPlayers 
     }() 

我什麼時候應該使用延遲初始化:當屬性存儲陣列,例如這是有用的?

何時使用延遲初始化的一個示例是,只有在初始化對象後才能知道屬性的初始值。

+0

當我有這樣的代碼: 類車{ VAR乘客:詮釋 的init(){ // passengers = 1 } } 這不會編譯,因爲它說並非所有的東西都被初始化了,是不是說它沒有放入默認值雖然? – AeonNeo

+0

同意,我會編輯答案。我看着文檔,你必須在不使用的時候初始化var?和! – Doro

+0

@Doro啊,好的。在那種情況下,不要!並沒有在最後使用任何東西基本上有相同的功能? – AeonNeo

0

簡短說明:

一個非可選變量始終值,並且永遠是零。 變量必須在init方法或聲明行中初始化。

var a : String 
var b = "bar" 

init { 
    a = "foo" 
} 

一種隱式展開的可選變量必須在init方法 或在聲明行被初始化,但保證具有總是一個值時,它的使用

var a : String! 

func viewDidLoad() { 
    a = "Hello" 
    a += " world!" 
} 

一種可選變量可能有一個值並且在聲明時爲零

var a : String? // = nil 

一個懶惰變量就在這一瞬後初始化它使用的第一次

class foo { 
    lazy var bar : String = { 
    return "Hello" 
    }() 
} 
+0

在這種情況下,如何使用 var a:字符串 而不是 var a:String! 既然必須在init方法/聲明行/相同的作用域中初始化它們? – AeonNeo

+0

'var a:String!'不能在init方法/聲明行中初始化。我更改了帖子,以澄清 – vadian

+0

嗯,我可以編譯/運行: var a:String! =「這是一個字符串」 雖然,所以它可以初始化 – AeonNeo

相關問題