You are previewing Programming F#.

Programming F#

Cover of Programming F# by Chris Smith Published by O'Reilly Media, Inc.
O'Reilly logo

Structs

We have covered classes before and gone through the complexities of overriding Equals to create equality semantics that make sense. However, there is a better way for simple types. Rather than trying to simulate value type semantics through overriding Equals, why not just create a new value type? Structs are similar to classes, the main difference being that they are a value type, and therefore may be put on the stack. Struct instances take up much less memory than a class and, if stack allocated, will not need to be garbage collected.

Creating Structs

To create a struct, define a type as you normally would, but add the [<Struct>] attribute. Or, you could use the struct and end keywords before and after the struct’s body:

[<Struct>]
type StructPoint(x : int, y : int) =
    member this.X = x
    member this.Y = y

type StructRect(top : int, bottom : int, left : int, right : int) =
    struct
        member this.Top    = top
        member this.Bottom = bottom
        member this.Left   = left
        member this.Right  = right

        override this.ToString() =
            sprintf "[%d, %d, %d, %d]" top bottom left right
    end

Structs have many of the features of classes but may be stored on the stack rather than the heap. Therefore, equality (by default) is determined by simply comparing the values on the stack rather than references:

> // Define two different struct values let x = new StructPoint(6, 20) let y = new StructPoint(6, 20);; val x : StructPoint = FSI_0011+StructPoint val y : StructPoint = FSI_0011+StructPoint > x = y;; val it : bool = ...

The best content for your career. Discover unlimited learning on demand for around $1/day.