检查类型是否实现了 Julia 中的接口

Iss*_* T. 4 julia

如何检查 Julia 中的类型是否实现了接口?

例如迭代接口由函数start, next,实现done

我需要的是根据参数类型是否实现给定的接口来对函数进行专门化。

编辑

这是我想做的一个例子。

考虑以下代码:

a = [7,8,9]
f = 1.0    
s = Set()
push!(s,30)
push!(s,40)

function getsummary(obj)
  println("Object of type ", typeof(obj))
end

function getsummary{T<:AbstractArray}(obj::T)
  println("Iterable Object starting with ", next(obj, start(obj))[1])
end

getsummary(a)
getsummary(f)
getsummary(s)
Run Code Online (Sandbox Code Playgroud)

输出是:

Iterable Object starting with 7
Object of type Float64
Object of type Set{Any}
Run Code Online (Sandbox Code Playgroud)

这是我们所期望的,因为Set不是AbstractArray. 但显然我的第二种方法只需要类型 T 来实现迭代接口。

我的问题不仅与迭代接口有关,还与一组函数定义的所有接口有关。

编辑2

我认为我的问题与

https://github.com/JuliaLang/julia/issues/5

既然我们可以想象类似的事情T<:Iterable

Fen*_*ang 6

通常,这是通过特征来完成的。请参阅Traits.jl了解一种实现方式;类似的方法用于在、等Base上进行分派。例如,这是使用特征的实现方式:Base.iteratorsizeBase.linearindexingBasecollectiteratorsize

"""
    collect(element_type, collection)

Return an `Array` with the given element type of all items in a collection or iterable.
The result has the same shape and number of dimensions as `collection`.
"""
collect{T}(::Type{T}, itr) = _collect(T, itr, iteratorsize(itr))

_collect{T}(::Type{T}, itr, isz::HasLength) = copy!(Array{T,1}(Int(length(itr)::Integer)), itr)
_collect{T}(::Type{T}, itr, isz::HasShape)  = copy!(similar(Array{T}, indices(itr)), itr)
function _collect{T}(::Type{T}, itr, isz::SizeUnknown)
    a = Array{T,1}(0)
    for x in itr
        push!(a,x)
    end
    return a
end
Run Code Online (Sandbox Code Playgroud)

另请参阅Mauro Weder关于特质的演讲。

我将iterability(::T)特征定义如下:

immutable Iterable end
immutable NotIterable end
iterability(T) =
    if method_exists(length, (T,)) || !isa(Base.iteratorsize(T), Base.HasLength)
        Iterable()
    else
        NotIterable()
    end
Run Code Online (Sandbox Code Playgroud)

这似乎有效:

julia> iterability(Set)
Iterable()

julia> iterability(Number)
Iterable()

julia> iterability(Symbol)
NotIterable()
Run Code Online (Sandbox Code Playgroud)