![](/img/trans.png)
[英]What's the difference between using JSONSerialization and JSONDecoder in swift?
[英]What's the difference between : and = in swift
抱歉,標題太混亂了,但是我很想知道這兩行之間的區別:
var title = String()
var title: String
是否已初始化一個且僅聲明了一個? 哪個更正確?
例如,如果我有一個結構,是否應該使用另一個?
所以我之所以這樣問,是因為我正在學習如何從URL中獲取一些JSON,然后將其顯示在我的應用中。 這樣做的新方法之一是使用Decodable。 因此,我在模型類中有一個結構,如下所示:
struct Videos: Decodable {
var title = String()
var number_of_views : Int
var thumbnail_image_name: String
var channel: Channel
var duration: Int
}
在另一堂課中,我有這個:
URLSession.shared.dataTask(with: url){(data,response,error) in
if(error != nil){
print(error!)
return
}
guard let data = data else { return }
do{
self.Videos2 = try JSONDecoder().decode([Videos].self, from: data)
//self.collectionView?.reloadData()
}catch let jsonErr{
print(jsonErr)
}
}.resume()
因此,我應該在結構中聲明或初始化變量嗎? 我假設我應該像這樣聲明它們:var title:String? 那是我的結構中正確的語法嗎?
更新:我知道這個問題比我最初提出的要廣泛。 對此我感到很抱歉,但是非常感謝您為我澄清的所有出色答案。
區別在於:
定義變量的類型,而=
則為變量分配實際值。
所以:
var title = String()
這將調用String
類型的初始化程序,從而創建一個新的String
實例。 然后,它將此值分配給title
。 title
類型被推斷為String
因為您正在為其分配String
類型的對象。 但是,您也可以將此行顯式編寫為:
var title: String = String()
這意味着您要聲明一個String
類型的title
變量,並為其分配一個新的String
。
var title: String
這只是說您正在定義String
類型的變量。 但是,您沒有為其分配值。 使用該變量之前,您需要為其分配一些內容,否則會出現編譯錯誤(如果這是一個屬性,而不僅僅是一個變量,則需要在到達類型末尾之前對其進行賦值) init()
方法,除非它后面帶有?
是可選的,在這種情況下,它會隱式初始化為nil
)。
編輯:對於您的示例,我可能會使用let
和:
聲明所有變量,假設您的JSON為所有這些屬性提供值。 然后,在創建對象時,由Decodable
生成的初始化程序將設置所有屬性。 因此,類似:
struct Videos: Decodable {
let title: String
let number_of_views : Int
let thumbnail_image_name: String
let channel: Int
let duration: Int
}
這將初始化一個值
var title = String()
這會聲明一個值,但不會初始化它
var title: String
如果嘗試使用后者,例如print(title)
,則將Variable 'title' used before being initialized
指出編譯器錯誤,指出使用了Variable 'title' used before being initialized
值是類還是結構都沒有關系。
=
運算符是賦值運算符 ,它為=
左側的對象分配一個值
通常,類或結構屬性是聲明的,但是直到init()
才init()
。 一個簡單的類可能是
class MyClass {
let myProperty: String
init(aString: String) {
self.myProperty = aString
}
}
在函數范圍內,您可以聲明僅存在於函數范圍內的局部變量。
func doSomethingToAString(aString: String) -> String {
let extraString = "Something"
let amendedString = aString + extraString
return amendedString
}
在您的特定示例中,該結構綜合了一個初始化程序,該初始化程序將允許您使用填充屬性所需的所有值來初始化該結構。 然后,由Decodable
生成的初始化Decodable
應在創建視頻結構時設置所有屬性,您將執行以下操作:
let aVideos = Videos(title: "My Title", number_of_views: 0, thumbnail_image_name: "ImageName", channel: Channel(), duration: 10)
是否已初始化一個且僅聲明了一個?
是的,這意味着不能使用聲明的內容。 如果嘗試為其設置值,則會得到編譯時錯誤:
variable 'title' passed by reference before being initialized
哪個更正確?
沒有經驗法則可以確定哪個更正確,這取決於是否需要直接初始化title
。
另一方面,當聲明一個類的屬性時,說var title = String()
意味着給title
了一個初始值(“”),這意味着您可以直接創建該類的實例,例如:
class Foo {
var title = String()
}
let myFoo = Foo()
但是,如果title
聲明為var title: String
,則必須實現Foo
的init
:
class Foo {
var title: String
init(title: String) {
self.title = title
}
}
let myFoo = Foo(title: "")
另外,您可以選擇將其聲明為lazy :
lazy var title = String()
意思是:
惰性存儲的屬性是直到首次使用才計算其初始值的屬性。 您可以通過在聲明之前編寫lazy修飾符來表示一個惰性存儲屬性。 屬性-惰性存儲的屬性
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.