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

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.

主站蜘蛛池模板: 满城县| 观塘区| 团风县| 安西县| 湄潭县| 宣恩县| 寿宁县| 同德县| 西乌珠穆沁旗| 宿州市| 于田县| 项城市| 杭锦后旗| 北碚区| 太仆寺旗| 兴义市| 昌宁县| 天长市| 武威市| 祁阳县| 达孜县| 博客| 丹东市| 濉溪县| 德庆县| 巴楚县| 麟游县| 涿州市| 云南省| 包头市| 石家庄市| 阳谷县| 旬邑县| 永修县| 甘孜县| 平潭县| 天门市| 普格县| 肃宁县| 新宾| 云龙县|