我试图了解参数类型在Julia中是如何工作的。
假设我有一个函数foo
,它采用Integer
(即非参数类型),我想断言这个函数来返回一个向量,其元素是{{1的子类型}}。从文档中我推断出它应该按如下方式实现:
Real
但它不起作用。我做错了什么?
答案 0 :(得分:2)
参数类型用于将输入参数化为函数,而不是输出。如果你的函数是类型稳定的(读取performance tips中的含义),那么编译器可以根据输入类型自动推断函数的输出,因此不需要指定它
所以你的功能看起来像这样:
function foo{T<:Real}(n::T)
#some code to generate vec
return(vec)
end
例如,您可以在函数体内生成适当类型的向量,例如像这样的东西:
function f1{T<:Number}(x::T)
y = Array(T, 0)
#some code to fill out y
return(y)
end
但请注意,T
必须出现在函数的输入的参数定义中,因为这是参数类型的目的。如果输入描述中没有出现T
,您将收到错误消息。这样的事情不起作用:
f{T<:Number}(x::Vector) = x
WARNING: static parameter T does not occur in signature for f at none:1.
The method will not be callable.
f (generic function with 1 method)
但这样做,并且类型稳定,因为如果输入类型已知,那么输出
也是如此f{T<:Number}(x::Vector{T}) = x
答案 1 :(得分:1)
使用传统的括号语法调用函数:
julia> f(2,3)
5
以上规则适用于参数和非参数方法。
因此,不应该尝试调用参数方法,如: 。我认为这个商城用法的来源可能是调用参数类型构造函数的语法:f{atype}(2,3)
julia> typeof(Array{Int})
DataType
julia> Array{Int}(2)
2-element Array{Int32,1}:
57943068
72474848
但是在参数化方法的情况下:
julia> same_type{T}(x::T, y::T) = true;
julia> typeof(same_type)
Function
julia> same_type{Int}
ERROR: TypeError: Type{...} expression: expected Type{T}, got Function
因此,通过这个介绍,它已经变得清晰,如:
function foo{T<:Real}(n::Integer)
.....
end
将毫无用处,因为T
的值不会从调用者的参数中确定。
julia> same_type{T}(x::T, y::T) = true;
julia> same_type(x,y) = false;
julia> same_type(1, 2)
true
julia> same_type(1, 2.0)
false
参数化方法的主要目的是让dispatch在调用函数时找到关于参数类型调用的正确方法,但它还具有以下惯用的副作用:
方法类型参数不限于用作类型 参数:它们可以在任何值的任何地方使用 函数或函数体的签名。
julia> mytypeof{T}(x::T) = T
mytypeof (generic function with 1 method)
julia> mytypeof(1)
Int64
现在,让我们回到主要问题:
如果您的方法已经是参数化的,您可以将参数值用作上述mytypeof
示例中的返回类型,例如:
julia> newoftype{T}(x::T,n) = T(n)
newoftype (generic function with 1 methods)
julia> newoftype([1,2],4)
4-element Array{Int32,1}:
57943296
72475184
141142104
1970365810
但是制作方法的返回类型,参数值的函数是一个简单的功能,可以简单地完成而无需参数化方法。很多典型的方法都可以做到这一点,例如:
julia> Array(Int,4)
4-element Array{Int32,1}:
126515600
72368848
72474944
0
julia> Array(Float64,4)
4-element Array{Float64,1}:
-2.122e-314
0.0
5.12099e-292
5.81876e-292
可以使用参数类型Type
来完成,例如:
julia> myarray(T::Type,n::Int)=Array(T,n);