很抱歉,如果标题相当令人困惑,但我很想知道这两行之间的区别:
var title = String()
var title: String
是否有一个被初始化而且只有一个被宣布?哪个更正确?
例如,如果我有一个结构,我应该使用另一个吗?
所以我问这个的原因是因为我正在学习如何从网址中获取一些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? 这是我结构中正确的语法吗?
更新: 我明白这个问题比我最初提出的要宽泛得多。对此我感到很抱歉,但是非常感谢你所有为我澄清的重要答案。
答案 0 :(得分:3)
区别在于:
定义了变量的类型,而=
为变量赋予了实际值。
所以:
var title = String()
这会调用String
类型的初始值设定项,从而创建一个新的String
实例。然后它将此值分配给title
。 title
的类型被推断为String
,因为您正在为其分配类型为String
的对象;但是,您也可以将此行明确写为:
var title: String = String()
这意味着您要声明title
类型String
的变量,并为其指定新的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
}
答案 1 :(得分:2)
初始化值
var title = String()
这声明了一个值,但没有初始化它
var title: String
如果您尝试使用后者,例如print(title)
,则会出现编译错误,指出Variable 'title' used before being initialized
值是类还是结构无关紧要。
=
运算符是赋值运算符,它为=
通常,在调用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
}
在您的特定示例中,struct合成了一个初始化程序,该初始化程序允许您使用填充属性所需的所有值初始化struct。然后,Decodable
生成的初始化程序应该在创建视频结构时设置所有属性,您将执行以下操作:
let aVideos = Videos(title: "My Title", number_of_views: 0, thumbnail_image_name: "ImageName", channel: Channel(), duration: 10)
答案 2 :(得分:1)
是否正在初始化一个并且只能声明一个?
是的,这意味着声明不能使用。如果您尝试为其设置值,则会出现编译时错误:
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
,则必须为init
实施Foo
:
class Foo {
var title: String
init(title: String) {
self.title = title
}
}
let myFoo = Foo(title: "")
此外,您可以选择将其声明为 lazy :
lazy var title = String()
表示:
惰性存储属性是一个初始值不是的属性 计算直到第一次使用。你表示存储懒惰 通过在声明之前写入延迟修饰符来实现属性。 <子> Properties - Lazy Stored Properties 子>