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

Parametric types and methods

An array can take elements of different types. Therefore, we can have, for example, arrays of the following types: Array{Int64,1}, Array{Int8,1}, Array{Float64,1}, or Array{String, 1}, and so on. That is why an Array is a parametric type; its elements can be of any arbitrary type T, written as Array{T, 1}.

In general, types can take type parameters, so that type declarations actually introduce a whole family of new types. Returning to the Point example of the previous section, we can generalize it to the following:

# see the code in Chapter 6\parametric.jl
mutable struct Point{T}
x::T
y::T
end

This is conceptually similar to the generic types in Java or templates in C++.

This abstract type creates a whole family of new possible concrete types (but they are only compiled as needed at runtime), such as Point{Int64}, Point{Float64}, and Point{String}.

These are all subtypes of Point: Point{String} <: Point returns true. However, this is not the case when comparing different Point types, whose parameter types are subtypes of one another: Point{Float64} <: Point{Real} returns false.

To construct objects, you can indicate the type T in the constructor, as in p = Point{Int64}(2, 5), but this can be shortened to p = Point(2, 5). Or let's consider another example: p = Point("London", "Great-Britain").

If you want to restrict the parameter type T to only the subtypes of Real, this can be written as follows:

mutable struct Point{T <: Real}
x::T
y::T
end

Now, the statement p = Point("London", "Great-Britain") results in an ERROR: MethodError: `Point{T<:Real}` has no method matching Point{T<:Real}(::String, :String) error message, because String is not a subtype of Real.

In much the same way, methods can also optionally have type parameters immediately after their name and before the tuple of arguments. For example, to constrain two arguments to be of the same type T, run the following command:

add(x::T, y::T) where T = x + y

Now, add(2, 3) returns 5 and add(2, 3.0) returns an ERROR: MethodError: `add` has no method matching add(::Int64, ::Float64) error message.

Here, we restrict T to be a subtype of Number in add as follows:

add(x::T, y::T) where T <: Number = x + y

As another example, here is how to check whether a vecfloat function only takes a vector of floating point numbers as the input. Simply define it with a type parameter T as follows:

function vecfloat(x::Vector{T}) where T <: AbstractFloat 
# code
end

Inner constructors can also take type parameters in their definition.

主站蜘蛛池模板: 水城县| 武清区| 搜索| 万盛区| 宣威市| 合山市| 油尖旺区| 许昌市| 灵川县| 漯河市| 邵阳县| 宜昌市| 兴山县| 北安市| 新竹市| 合山市| 黔江区| 宁乡县| 深泽县| 长岛县| 越西县| 和平区| 泌阳县| 保康县| 邵东县| 正安县| 吴堡县| 新巴尔虎左旗| 张掖市| 和田县| 新巴尔虎右旗| 景泰县| 贺兰县| 沂水县| 泽普县| 错那县| 当涂县| 蒲江县| 仲巴县| 云林县| 托里县|