Recently, I learned of a new metadata tag in Haxe that allows you to get the flexibility of structs with the power of classes. That’s the power of Struct Init. Let’s talk about how to use it, starting now.
The Metadata Tag
If you haven’t used the metadata tags before. Metadata tags allow you to use or trigger special capabilities in Haxe. How do you use them or get them to work? Take a look at the example below!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@:structInit class Person { | |
final name:String; | |
var age:Int = 30; | |
public function new(name:String, age:Int) { | |
this.name = name; | |
this.age = age; | |
} | |
public function greet() | |
trace( 'Hello, I\'m $name, and I\'m $age years old!'); | |
} |
As you can see this is pretty easy you simply can attach the meta by assigning it to the class above. The same applies to some other metadata in the Haxe programming language; you prefix the class/function/variable with the tag. By doing that allows you to use some special abilities in the Haxe programming language. So, with that said how does struct init work?
Struct Init In Action
Let’s use our example above to create an instance of it using the syntax that using the structInit metadata tag allows you to do. See the example below:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Test it out here: https://try.haxe.org/#5Fb7F1f4 | |
class Test { | |
public static function main() { | |
// Uncomment this and see what happens | |
// var firstUser:Person = { | |
// name: 'Tim' | |
// }; | |
// trace(firstUser.name); | |
var user:Test2 = { | |
name: 'Tim' | |
}; | |
trace(user.name); | |
} | |
} | |
@:structInit | |
class Person { | |
public var age:Int = 30; | |
public var name:String = ''; | |
public var color:String = ''; | |
public var eyes:Int = 0; | |
// Try commenting out this function and see what happens | |
public function new(?color:String, ?eyes:Int) { | |
// do stuff like set private defaults | |
} | |
} | |
@:structInit class Test2 { | |
public var name:String; | |
var age:Int = 30; | |
// public function new(name:String, age:Int) { | |
// this.name = name; | |
// this.age = age; | |
// } | |
public function greet() | |
trace('Hello, I\'m $name, and I\'m $age years old!'); | |
} |
All you do is add the type information to the variable with the type name. After that it works; no longer do you need to use the new operator. Nice right? That means you could potentially combine structures using this notation to make more complex classes. It will also initialize the properties that you set. Awesome right? Now, this does come with some important notes that you should be aware of.
When using the struct init, you can’t create a class with this notation if your new constructor has required parameters(parameters that do not have the optional metatag or question mark in haxe) You’ll get an error if you don’t add them into the object. However, if you don’t have a constructor, it will still construct the class with the properties that you have. That’s very powerful; it allows you to create classes that are essentially just data objects while still leveraging the functionality of a class.
In your own code, definitely leverage in; try each of the classes in the code above and see the results.
With that said have a good one and good luck game-making!!
For more information, check out this link here: https://code.haxe.org/category/beginner/declare-classes-with-structinit.html