Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

iOS

Michael Williams
PLUS
Michael Williams
Courses Plus Student 8,059 Points

I need a refresher.

My learning progress has slowed down a little due to life, and I'm having trouble understanding a line of code.

I understand everything going on below, but the one part that I'm a little fuzzy on is why do you have to say name: name, age: age, address: address when returning Friend? Because in my mind name, age, and address are already being assigned those dictionary values ```["name": "Derek"]. But something tells me my logic is off.

NOTE: If anyone can help me format my code properly, I'm all ears. I've always written it out according to the posting guidelines and it always turns out orange, like below. ¯_(ツ)_/¯

iOS

struct Friend {
    let name: String
    let age: String
    let address: String?
}

enum FriendError: Error {
    case invalidData(description: String)
}

func friend(from dict: [String : String]) throws -> Friend {
    guard let name = dict["name"] else {
        throw FriendError.invalidData(description: "Invalid name value") //once we do this, we exit the function completely
    }

    guard let age = dict["age"] else {
        throw FriendError.invalidData(description: "Invalid age value")
    }

    let address = dict["address"]

    return Friend(name: name, age: age, address: address)
}

let response = ["name": "Derek", "age": "24", "address": "someAddress"]
let someFriend = try friend(from: response) //when you have 'try' it may not be executed depending on the function result
print(someFriend)
Paolo Scamardella
Paolo Scamardella
24,828 Points

Michael, I'll be glad to help you out; however, I'm not understanding you question/s. Are you asking why the arguments are listed the way they are inside Friend struct like Friend(name: name, age: age, address: address)?

Could you please be more specific?

2 Answers

Michael Williams
PLUS
Michael Williams
Courses Plus Student 8,059 Points

Yes, I'm curious why they arguments are listed the way they are. Why are this way:

return Friend(name: name, age: age, address: address)

versus this way:

return Friend(name, age, address)
Paolo Scamardella
Paolo Scamardella
24,828 Points

It is because by default, structs automatically creates an init method with parameters names and its types based on the properties listed inside the structs. This is also called memberwise initializer.

Note that the order matters too:

struct Friend {
    let name: String
    let age: String
    let address: String?
}

let friend = Friend(name: "John", age: "25", address: "") // this will work because

// this will not work because the listed properties in Friend struct is not in the order of age, name, and address, 
// but it is name, age, and address
let friend = Friend(age: "25", name: "John", address: "")   

If you really want to omit the parameters names, all you have to do is add an underscore for each parameter like this:

struct Friend {
    let name: String
    let age: String
    let address: String?

    init(_ name: String, _ age: String, _ address: String?) {
       self.name = name
       self.age = age
       self.address = address
    }
}

let friend = Friend("25", "John", "")   

Things to remember... With structs, you can omit the init method because of memberwise initializer by default. Unlike structs, classes needs to have an init method unless all properties have a default value.