User-defined and composite types

In Julia, as a developer you can define your own types to structure data used in applications. For example, if you need to represent points in a three-dimensional space, you can define a type Point, as follows:

# see the code in Chapter 6user_defined.jl: 
mutable struct Point 
    x::Float64 
    y::Float64 
    z::Float64 
end 

mutable here means that Point values can be modified. If your type values cannot be changed, simply use struct.

The type Point is a concrete type. Objects of this type can be created as p1 = Point(2, 4, 1.3), and it has no subtypes: typeof(p1) returns Point (constructor with 2 methods), subtypes(Point)returns 0-element Array{Any,1}.

Such a user-defined type is composed of a set of named fields with an optional type annotation; that's why it is a composite type, and its type is also DataType. If the type of a named field is not given, then it is Any. A composite type is similar to struct in C, or a class without methods in Java.

Unlike in other object-oriented languages such as Python or Java, where you call a function on an object such as object.func(args), Julia uses the func(object, args) syntax.

Julia has no classes (as types with functions belong to that type); this keeps the data and functions separate. Functions and methods for a type will be defined outside that type. Methods cannot be tied to a single type, because multiple dispatch connects them with different types. This provides more flexibility, because when adding a new method for a type, you don't have to change the code of the type itself, as you would have to do with the code of the class in object-oriented languages.

The names of the fields that belong to a composite type can be obtained with the names function of the type or object: fieldnames(Point) or fieldnames(typeof(p1)) returns (:x, :y, :z).

A user-defined type has two default implicit constructors that have the same name as the type and take an argument for each field. You can see this by asking for the methods of Point: methods(Point); it returns two methods for generic function Point: Point(x::Float64, y::Float64, z::Float64) and Point(x ,y ,z). Here, the field values can be of type Any.

You can now make objects simply like this:

orig = Point(0, 0, 0) 
p1 = Point(2, 4, 1.3). 

Fields that together contain the state of the object can be accessed by name, as in: p1.y, which returns 4.0.

Objects of such a type are mutable, for example, I can change the z field to a new value with p1.z = 3.14, resulting in p1 now having the value Point(2.0, 4.0, 3.14). Of course, types are checked: p1.z = "A" results in an error.

Objects as arguments to functions are passed by reference, so that they can be changed inside the function (for example, refer to the function insert_elem(arr) in the Defining types section of Chapter 3, Functions).

If you don't want your objects to be changeable, replace type with the keyword struct, for example:

struct Vector3D 
    x::Float64 
    y::Float64 
    z::Float64 
end  

Calling p = Vector3D(1, 2, 3) returns Vector3D(1.0, 2.0, 3.0) and p.y = 5 returns ERROR: type Vector3D is immutable.

Immutable types enhance performance, because Julia can optimize the code for them. Another big advantage of immutable types is thread safety: an immutable object can be shared between threads without needing synchronization. If, however, such an immutable type contains a mutable field such as an array, the contents of that field can be changed. So, define your immutable types without mutable fields.

A type once defined cannot be changed. If we try to define a new type Point with fields of type Int64, or with added fields, we get an ERROR: invalid redefinition of constant TypeName error message.

A new type that is exactly the same as an existing type can be defined as an alias through a simple assignment, for instance, Point3D = Point. Now, objects of type Point3D can also be created: p31 = Point3D(1, 2, 3) returns Point(1.0, 2.0, 3.0). Julia also uses this internally; the alias Int is used for either Int64 or Int32, depending on the architecture of the system that is being used.

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

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