tags:

views:

143

answers:

3

Is it possible to emulate a C union structure using Scala? In this case variables are overwritten each other.

Following is a list of characteristics that might be possible:

  1. With the same variable allow to use different types.
  2. Variables use the same memory location.
  3. Any way to know what types are stored.

I think that the second characteristic is the most difficult to emulate.

Thanks

+5  A: 

One would generally use case classes to create discriminated (tagged) unions (or otherwise employ type contracts). This has a similar effect and is type-safe.

In the case class tour, you can see Var, Fun an App can all be stored in something capable of holding a Term. Then pattern matching can be used to extract what has been stored and act depending upon the specific type (Var, Fun, App, etc.) matched upon. This whole process is similar to using an extra "type" flag and if/else-construct often used with C unions only, again, type-safe (and much more convenient in most cases :-)

(Actually, looking at those links is rather disappointing as it doesn't really scratch the surface :-/)

A practical example/explanation using Scala: What is an algebraic data type? It also does the nice job of showing how it relates/is handled in "lesser" languages.

pst
+1  A: 

One very common use of a union is to allow you to see (for example) a long and 3 ints represented by an array of bytes, typically for file or network I/O.

To do the equivalent in Java, and therefore in Scala, you should look at the NIO library: http://en.wikipedia.org/wiki/New_I/O This provides all the functionality you need to read/write rich values against sockets, files, etc.

You can instead use the older Reader/Writer/Stream approach (http://tutorials.jenkov.com/java-io/index.html) if you feel more comfortable with that API, and you may have more luck finding online tutorials there.

Kevin Wright
+1  A: 

I think your best bet is Either:

var x: Either[Int, Double] = _
x = Left(5)
x = Right(1.5)
x match {
    case Left(i) => println("Int "+i)
    case Right(d) => println("Double "+d)
}

What this does not let you do is to "read" one type as if it were the other. It does uses one reference more than the size of the types alone, but it doesn't add the size taken by both types together. And it does allow you to know which type is stored.

Daniel