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 trialandrew naeve
11,503 Pointsinit? with guard statements
Can't seem to solve this one.
also, can't seem to attach my code with the checkmarked box when posting.
struct Book {
let title: String
let author: String
let price: String?
let pubDate: String?
init?(dict: [String: String]) {
guard let title = dict["title"], author = dict["author"] else {
return nil
}
let price = dict["price"], pubDate = dict["pubDate"]
return nil
}
4 Answers
andrew naeve
11,503 Pointsstruct Book {
let title: String
let author: String
let price: String?
let pubDate: String?
init?(dict: [String: String]){
guard let title = dict["title"], author = dict["author"] else {
return nil
}
self.title = title
self.author = author
self.price = dict["price"]
self.pubDate = dict["pubDate"]
}
}
Nathan Tallack
22,160 PointsYeah, this one was REALLY hard! A little too hard to be included I think. I had to read the Swift guide and play around in an Xcode playground for quite a while to work this out.
Consider this code:
struct Book {
let title: String
let author: String
let price: String?
let pubDate: String?
init?(dict: [String: String]) {
if dict["title"] == nil { return nil }
if dict["author"] == nil { return nil }
self.title = dict["title"]!
self.author = dict["author"]!
self.price = dict["price"]
self.pubDate = dict["pubDate"]
}
}
Because we have to force unwrap the title and author strings from the dictionary (which is VERY VERY bad and we were told again and again never to do this) we need to first check to ensure they are set. That is what the two if return nil statements are. Hence the optional init? for the dictionary.
In this way we can pass a dictionary that MUST have values for title and author and can optionally have values for price and pubDate (because those are declared as optional properties in our Struct).
Scary stuff. Better not to use optionals in a Struct methinks. ;)
PS: I think guard can only be used in enums. Not sure. Will have to go read about it again. :P
WCM Operations
Courses Plus Student 15,102 PointsThis one frustrated me. Thanks for working it out.
andrew naeve
11,503 Pointsman, thats crazy! thought they were strongly hinting at guard statements from the preceding lessons. thanks!
Nathan Tallack
22,160 PointsThanks to Andrew Naeve's answer above, this is the CORRECT way to do it! No nasty forced unwrapping, and excellent use of the guard statement. :)
struct Book {
let title: String
let author: String
let price: String?
let pubDate: String?
init?(dict: [String: String]){
guard let title = dict["title"], author = dict["author"] else {
return nil
}
self.title = title
self.author = author
self.price = dict["price"]
self.pubDate = dict["pubDate"]
}
}
kols
27,007 Pointsandrew naeve's answer and Nathan Tallack's second answer are correct (thanks, guys!!) except for a missing let
keyword preceding the second statement in the guard statement (aka, 'author = ...'):
struct Book {
let title: String
let author: String
let price: String?
let pubDate: String?
init?(dict: [String:String]) {
guard let title = dict["title"], let author = dict["author"] else {
return nil
}
self.title = title
self.author = author
self.price = dict["price"]
self.pubDate = dict["pubDate"]
}
}