Working with Structs

Objects created from classes take up heap memory, and the garbage collector needs to release that. As you saw in the loop code in Structuring a Class, creating many objects can quickly consume a lot of resources. To boost performance in such a case, you can use a sort of lightweight class called struct, which inherits from class Struct.

Structs are allocated in stack memory, so a struct is copied when reassigned or passed to a method. In other words: it’s passed by value. At first sight, they look very much like classes: they have properties, constructors, and methods, and they can even be generic.

The following example defines a struct to accommodate user data:

 struct User
  property name, age
 
 def​ ​initialize​(@name : String, @age : Int32)
 end
 
 def​ ​print
  puts ​"​​#{​age​}​​ - ​​#{​name​}​​"
 end
 end
 
 d = User.​new​(​"Donald"​, 42)
 d.​name​ ​# => Donald
 d.​age​ = 78
 d.​print​ ​# => 78 - Donald

Changing Structs in Methods

images/aside-icons/warning.png

Because structs are copied when passed, you must think about returning the value and reassigning it after return. In the following snippet, the no_change method doesn’t change the struct, only the change method works:

 def​ ​no_change​(user)
  user.​age​ = 50
 end
 
 def​ ​change​(user)
  user.​age​ = 50
  user
 end
 
 d = User.​new​(​"Donald"​, 78)
 d.​print​ ​# => 78 - Donald
 no_change(d)
 d.​print​ ​# => 78 - Donald
 d = change(d)
 d.​print​ ​# => 50 - Donald

Structs work best for non-changing (also called immutable) data structures, especially when the structure is small and you have lots of them. As a good example, the standard library implements complex numbers through the struct Complex.

Inheritance can also be defined for a struct, but only from an abstract struct.

Use Structs for Performance

images/aside-icons/tip.png

Try changing class to struct in your code and see if it enhances performance. If it does and it fits with the functionality, go for it.

Your Turn 3

Vec2D—Overloading an Operator on a Struct: Suppose you need to add lots of two-dimensional vectors. Define a struct Vec2D for doing just that and overload the + operator. Then define a few of them and work with these vectors. (Hint: Restrict the + operation to adding another Vec2D by using self.)

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.138.69.163