Since I am a complete beginner, I don't even know whether I am asking the right question or not. But I am having trouble understand why the "User(name: "John ...)" part of the code in the for loop works
CASE1
struct User
{
let name: String
let company: String
let login: String
let password: String
static let database: Dictionary<String, User> = {
var theDatabase = Dictionary<String, User>()
for user in [
User(name: "John Appleseed", company: "Apple", login: "japple", password: "foo"),
User(name: "Madison Bumgarner", company: "World Champion San Francisco Giants", login: "madbum", password: "foo"),
User(name: "John Hennessy", company: "Stanford", login: "hennessy", password: "foo"),
User(name: "Bad Guy", company: "Criminals, Inc.", login: "baddie", password: "foo")
] {
theDatabase[user.login] = user
}
return theDatabase
}()
}
but this doesn't
CASE2
struct User
{
let name: String
let company: String
let login: String
let password: String
for user in User(name: "John Appleseed", company: "Apple", login: "japple", password: "foo"){
print(user)
}
}
To understand how CASE1 works I ran a simpler version of this code i.e. CASE2. Even though the exact same thing is happening in both cases,[ Regarding User(..arguments..) ] I get the error "Declaration Expected" in the second case. Sir Paul(Stanford cs193p) said this was a fairly simple database , but I have been trying to figure this problem out for more than 6 hours.
for-loops must be contained in closures.
In case 1, you are declaring a static property called database
using a closure. This is the declaration:
static let database: Dictionary<String, User> = {
// This is the body of the closure
}()
And you put the for-loop in the closure body. This tells the swift compiler when to execute the for-loop, which is when the closure is executed.
In case 2, the for-loop is in the struct. But a struct isn't a closure. So the swift compiler does not know when to execute the for-loop.
The only things that can be in a struct are declarations, such as property declarations, function declarations and struct declarations. A for-loop isn't a declaration so that's why the compiler complains that it expected to see a declaration.
The code in case 1 works because the database
is a property declaration.
But... there's another problem!
For-in loops only loops through objects that conform to the SequenceType
protocol. Examples of such objects include arrays and String.CharatcerView
.
In case 1, the for-in loop loops through an array, which conforms to SequenceType
. See those [
and ]
? They denote an array! In case 2, you don't have those around the newly created User
, so it is just a User
, which does not conform to SequenceType
and thus cannot be used in a for-in loop.
To solve both of your problems, use this code:
struct User
{
let name: String
let company: String
let login: String
let password: String
static let database: Dictionary<String, User> = {
var theDatabase = Dictionary<String, User>()
for user in [
User(name: "John Appleseed", company: "Apple", login: "japple", password: "foo")] {
theDatabase[user.login] = user
}
return theDatabase
}()
}
As you can see, I added a declaration of database
and the closure and added []
around the user.