官术网_书友最值得收藏!

Types

Julia's type system is unique. Julia behaves as a dynamically typed language (such as Python, for instance) most of the time. This means that a variable bound to an integer at one point might later be bound to a string. For example, consider the following:

julia> x = 10 
10 
julia> x = "hello" 
"hello" 

However, one can, optionally, add type information to a variable. This causes the variable to only accept values that match that specific type. This is done through a type of annotation. For instance, declaring x::String implies that only strings can be bound to x; in general, it looks like var::TypeName. These are used the most often to qualify the arguments a function can take. The extra type information is useful for documenting the code, and often allows the JIT compiler to generate better-optimized native code. It also allows the development environments to give more support, and code tools such as a linter that can check your code for possible wrong type use.

Here is an example: a function with the calc_position name defined as the function calc_position(time::Float64) indicates that this function takes one argument named time of type Float64.

Julia uses the same syntax for type assertions, which are used to check whether a variable or an expression has a specific type. Writing (expr)::TypeName raises an error if expr is not of the required type. For instance, consider the following:

julia> (2+3)::String 
ERROR: TypeError: in typeassert, expected String, got Int64

Notice that the type comes after the variable name, unlike in most other languages. In general, the type of a variable can change in Julia, but this is detrimental to performance. For utmost performance, you need to write type-stable code. Code is type-stable if the type of every variable does not vary over time. Carefully thinking in terms of the types of variables is useful in avoiding performance bottlenecks. Adding type annotations to variables that are updated in the inner loop of a critical region of code can lead to drastic improvements in the performance by helping the JIT compiler remove some type checking. To see an excellent example where this is important, read the article available at http://www.johnmyleswhite.com/notebook/2013/12/06/writing-type-stable-code-in-julia/.

A lot of types exist; in fact, a whole type hierarchy is built-in in Julia. If you don't specify the type of a function argument, it has the Any type, which is effectively the root or parent of all types. Every object is at least of the universal type Any. At the other end of the spectrum, there is type Nothing, which has no values. No object can have this type, but it is a subtype of every other type. While running the code, Julia will infer the type of the parameters passed in a function, and with this information, it will generate optimal machine code.

You can define your own custom types as well, for instance, a Person type. We'll come back to this in Chapter 6, More on Types, Methods, and Modules. By convention, the names of types begin with a capital letter, and if necessary, the word separation is shown with CamelCase, such as BigFloat or AbstractArray.

If x is a variable, then typeof(x) gives its type, and isa(x, T) tests whether x is of type T. For example, isa("ABC", String) returns true, and isa(1, Bool) returns false.

Everything in Julia has a type, including types themselves, which are of type DataType: typeof(Int64) returns DataType. Conversion of a variable var to a type Type1 can be done using the type name as a function, such as Type1(var). For example, Int64(3.0) returns 3.

However, this raises an error if type conversion is impossible, as follows:

julia> Int64("hello") 
ERROR: MethodError: Cannot `convert` an object of type String to an object of type Int64

主站蜘蛛池模板: 宾川县| 玛纳斯县| 攀枝花市| 日土县| 蛟河市| 北辰区| 灌南县| 汝南县| 承德市| 景洪市| 繁昌县| 合阳县| 旌德县| 海口市| 弥勒县| 拉孜县| 江永县| 吐鲁番市| 屏东市| 余姚市| 如皋市| 凤城市| 绍兴市| 宜都市| 内江市| 元谋县| 盐城市| 大新县| 雅江县| 区。| 岳西县| 九台市| 二连浩特市| 灌阳县| 巴南区| 二手房| 方山县| 隆化县| 平武县| 濮阳市| 镇江市|