简体   繁体   中英

What's the difference between : and = in swift

Sorry if the title is rather confusing, but I'm curious to know the difference between these two lines:

var title = String()
var title: String

Is one being initialized and one only be declared? Which is more correct?

For example, if I have a struct should I use one of the other?

So the reason I ask this is because I'm learning about how to grab some JSON from a url and then display it in my app. One of the new ways of doing so is using Decodable. So, I have a struct in a model class like so:

struct Videos: Decodable {

    var title = String()
    var number_of_views : Int
    var thumbnail_image_name: String
    var channel: Channel
    var duration: Int

}

In another class I have this:

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()

So, should I declare or initialize the variables in my struct? I'm assuming I should just declare them like so: var title: String? Would that be the correct syntax in my struct?

UPDATE: I understand this question was more broad then I originally proposed it to be. I'm sorry about that, but thank you so much for all your great answers that clarified a lot up for me.

The difference is that : defines the type of your variable, whereas = assigns an actual value to the variable.

So:

var title = String()

This calls the initializer of the String type, creating a new String instance. It then assigns this value to title . The type of title is inferred to be String because you're assigning an object of type String to it; however, you could also write this line explicitly as:

var title: String = String()

This would mean you are declaring a title variable of type String , and assigning a new String to it.

var title: String

This simply says you're defining a variable of type String . However, you are not assigning a value to it. You will need to assign something to this variable before you use it, or you will get a compile error (and if this is a property rather than just a variable, you'll need to assign it before you get to the end of your type's init() method, unless it's optional with ? after it, in which case it gets implicitly initialized to nil ).

EDIT: For your example, I'd probably declare all the variables using let and : , assuming that your JSON provides values for all of those properties. The initializer generated by Decodable should then set all the properties when you create the object. So, something like:

struct Videos: Decodable {
    let title: String
    let number_of_views : Int
    let thumbnail_image_name: String
    let channel: Int
    let duration: Int
}

This initializes a value

var title = String()

This declares a value but does not initialize it

var title: String

If you attempt to use the latter, such as print(title) , you will get a compiler error stating Variable 'title' used before being initialized

It does not matter whether the value is a class or a struct.

The = operator is the assignment operator , it assigns a value to the object on the left of the =

Typically, class or struct properties are declared but not initialized until the init() is called. A simple class might be

class MyClass {
    let myProperty: String

    init(aString: String) {
        self.myProperty = aString
    }
}

Whereas inside the scope of a function you may declare a local variable that only lives inside the scope of the function.

func doSomethingToAString(aString: String) -> String {
    let extraString = "Something"
    let amendedString = aString + extraString
    return amendedString
}

In your specific example, the struct synthesizes an initializer that will allow you to initialize the struct with all the values needed to fill your properties. The initializer generated by Decodable should then set all the properties when you create a Videos struct, you will do it something like:

let aVideos = Videos(title: "My Title", number_of_views: 0, thumbnail_image_name: "ImageName", channel: Channel(), duration: 10)

Is one being initialized and one only be declared?


Yes, meaning that the declared cannot be used. If you tried to set a value for it, you would get a compile-time error:

variable 'title' passed by reference before being initialized

Which is more correct?

There is no rule of thumb to determine which is more correct, that would be depends on is there a need to initialize title directly.

On another hand, when it comes to declare properties for a class, saying var title = String() means that you are give title an initial value ("") which means that you are able to create an instance of this class directly, example:

class Foo {
    var title = String()
}

let myFoo = Foo()

However, if title declared as var title: String , you will have to implement the init for Foo :

class Foo {
    var title: String

    init(title: String) {
        self.title = title
    }
}

let myFoo = Foo(title: "")

Also, you have an option to declare it as lazy :

lazy var title = String()

which means:

A lazy stored property is a property whose initial value is not calculated until the first time it is used. You indicate a lazy stored property by writing the lazy modifier before its declaration. Properties - Lazy Stored Properties

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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