繁体   English   中英

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 ,则必须实现Fooinit

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM