4

In C# I can declare a list declaratively, in other words declare its structure and initialise it at the same time as follows:

var users = new List<User>
            {
                new User {Name = "tom", Age = 12}, 
                new User {Name = "bill", Age = 23}
            };

Ignoring the differences between a List in .Net and a List in Scala (ie, feel free to use a different collection type), is it possible to do something similar in Scala 2.8?

UPDATE

Adapting Thomas' code from below I believe this is the nearest equivalent to the C# code shown:

class User(var name: String = "", var age: Int = 0)

val users = List(
  new User(name = "tom", age = 12), 
  new User(name = "bill", age = 23))
Rupert Bates
  • 3,041
  • 27
  • 20
  • Is it necessary to write ``? Can't C# infer the generic type of List from the "contents"? – soc Feb 09 '11 at 14:49
  • Do you have a link to that syntax you are showing here? Would like to read that up. Is it similar to Java's instance initializer blocks? – soc Feb 09 '11 at 14:57
  • @soc - c# can't infer that I want to create a list, I need to tell it that. If I wanted an array I could do the following: var users = new [] { new User {Name = "tom", Age = 12}, new User {Name = "bill", Age = 23} }; here is a link to a description of the syntax: http://msdn.microsoft.com/en-us/library/bb384062.aspx – Rupert Bates Feb 09 '11 at 15:32
  • @Rupert: Very weird. It says this syntax works for subtypes of IEnumerable, but I couldn't find anything in the interface nor the class implementing that feature. – soc Feb 10 '11 at 09:11
  • @soc: I believe it is implemented by the compiler. – Rupert Bates Feb 10 '11 at 11:25
  • @Rupert: Uh ok... ouch, that's pretty ugly from a language design POV. :-) – soc Feb 10 '11 at 14:23

4 Answers4

20

What about:

case class User(name: String, age: Int)

val users = List(User("tom", 12), User("bill", 23))

which will give you:

users: List[User] = List(User(tom,12), User(bill,23))
Thomas Rawyler
  • 1,075
  • 7
  • 16
  • 1
    Thanks for your answer, this is very useful but subtly different to the way the C# code behaves because we are providing an explicit constructor which has to be fulfilled. In the C# version we are actually calling the default no args constructor and then setting properties on the object after it is created, any properties we don't set just have their default values. I've updated my code above to show what I think would be the nearest Scala equivalent, using default parameters to the constructor – Rupert Bates Feb 09 '11 at 17:17
  • I see. Thanks for your further explanation. I agree, that seems to be the closest to your C# code. – Thomas Rawyler Feb 09 '11 at 17:57
  • @Rupert: Is the problem that it looks different in Scala? Feature-wise it seems Scala provides more functionality, with less complex syntax than C#. Or am I missing something? – soc Feb 10 '11 at 09:15
  • @soc it's not just that it looks different, it is actually functionally different. The Scala code relies on having a constructor defined which accepts values for the fields we want to populate. The C# version doesn't, it uses a no argument constructor and then sets the values afterwards. I wouldn't like to say that one was better than the other, my feeling is that C# one is probably slightly more flexible, but by knowledge of Scala is not as good as my knowledge of C# so I could be biased or just missing a more idiomatic way of doing it. – Rupert Bates Feb 10 '11 at 11:23
  • Ah ok. I guess the equivalent to your C# example would be something like `new { val name = "Foo"; val age = 42 } with User`. `User` being defined as `trait User { val name: String; val age: Int }`. But yes, usually you would probably use a case class (with default arguments in the constructor if you need them). – soc Feb 10 '11 at 14:28
4
val users = User("tom", 12) :: User("bill", 23) :: Nil

You could also use Scalas tupel class:

val users = ("tom", 12) :: ("bill", 23) :: Nil
gruenewa
  • 1,666
  • 11
  • 16
3

Or you can create objects without use of explicit class defined in your compilation module this way

List(
   new {var name = "john"; var age = 18},
   new {var name = "mary"; var age = 21}
)
Note, that this code has some serious drawback, it will create an anonymous class per each new.
ryskajakub
  • 6,351
  • 8
  • 45
  • 75
1

Adapting Thomas' code from below I believe this is the nearest equivalent to the C# code shown:

class User(var name: String = "", var age: Int = 0)

val users = List(
  new User(name = "tom", age = 12), 
  new User(name = "bill", age = 23))

It is subtly different to the way the C# code behaves because we are providing an explicit constructor with default values rather than using the no args constructor and setting properties subsequently, but the end result is comparable.

Rupert Bates
  • 3,041
  • 27
  • 20