朱莉娅的函数签名中的“不是子类型”

时间:2019-10-27 21:41:11

标签: polymorphism julia

我想拥有一个除某种特定类型外可以接受其他任何功能的函数。大概是这样的

function f(y::X) where y<:setdiff(Any,Real)
    return y
end

是否存在“ {subtype of”运算符,其作用与<:相反?还有其他方法可以实现吗?

编辑:这是错误的,对于理解问题或答案并不一定是必需的,因此删除线如下:原因是我想针对任何实数和通用方法使用一种特定的函数f方法任何任意对象。问题是,如果我仅将此函数签名保留为where y,那么它将把通用函数专门化为Float64类型,它比我为任何实数(where y<:Real)编写的函数更具体。 / strike>

2 个答案:

答案 0 :(得分:2)

确实存在“不是...的子类型”(它是>:),但是您不需要该操作符即可解决问题。

如果只想对所有类型使用通用方法,而对Real的子类型使用特定的方法,则应该这样做:

f(x::Any) = 1
f(x::Real) = 2

第一种方法与仅添加任何类型签名(即f(x) = 1)相同,该函数将作为所有参数类型的后备。但是,由于RealAny更具体,如果输入是Real,将使用第二种方法而不是第一种方法:

julia> f("Hello, world!"), f(0x01), f(1 + 2im), f(true)
(1, 2, 1, 2)

请注意,无论您在方法定义中使用哪种类型签名,无论您使用哪种类型签名,该方法在实际运行时都将根据具体输入将其编译为特定版本,从而获得最佳性能。类型。

答案 1 :(得分:1)

您实际上可以通过使用dispatch来实现自己的“ not subtype”运算符:

notasubtype(::Type{T1}, ::Type{T2}) where {T2, T1 <: T2} = false
notasubtype(::Type, ::Type) = true

julia> notasubtype(Int, Bool)
true

julia> notasubtype(Bool, Integer)
false

julia> notasubtype(Bool, Real)
false

julia> notasubtype(Bool, Array)
true

但是,这仅允许您在运行时确定关系,而不能作为类型约束。另一方面,由于我们已经证明了这是可能的,因此我们可以在具体功能中重用相同的原理:

f(x::T) where {T<:Real} = ... # T a subtype of Real 
f(x::T) where {T} = ...       # T not a subtype of Real

您可以像Jacob一样用更简单,等效的术语来写:

f(x::Any) = ...
f(x::Real) = ...

(顺序无关紧要。)