我想拥有一个除某种特定类型外可以接受其他任何功能的函数。大概是这样的
function f(y::X) where y<:setdiff(Any,Real)
return y
end
是否存在“ {subtype of”运算符,其作用与<:
相反?还有其他方法可以实现吗?
编辑:这是错误的,对于理解问题或答案并不一定是必需的,因此删除线如下:原因是我想针对任何实数和通用方法使用一种特定的函数f
方法任何任意对象。问题是,如果我仅将此函数签名保留为where y
,那么它将把通用函数专门化为Float64类型,它比我为任何实数(where y<:Real
)编写的函数更具体。 / strike>
答案 0 :(得分:2)
确实存在“不是...的子类型”(它是>:
),但是您不需要该操作符即可解决问题。
如果只想对所有类型使用通用方法,而对Real的子类型使用特定的方法,则应该这样做:
f(x::Any) = 1
f(x::Real) = 2
第一种方法与仅添加任何类型签名(即f(x) = 1
)相同,该函数将作为所有参数类型的后备。但是,由于Real
比Any
更具体,如果输入是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) = ...
(顺序无关紧要。)