![](/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.