什么是:和/在swift之间的区别

时间:2018-04-12 22:45:42

标签: ios swift

很抱歉,如果标题相当令人困惑,但我很想知道这两行之间的区别:

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? 这是我结构中正确的语法吗?

更新: 我明白这个问题比我最初提出的要宽泛得多。对此我感到很抱歉,但是非常感谢你所有为我澄清的重要答案。

3 个答案:

答案 0 :(得分:3)

区别在于:定义了变量的类型,而=为变量赋予了实际值。

所以:

var title = String()

这会调用String类型的初始值设定项,从而创建一个新的String实例。然后它将此值分配给titletitle的类型被推断为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