检查类型是否在Julia

时间:2016-09-09 11:13:57

标签: julia

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

例如,迭代接口由函数startnextdone实现。

我需要的是一个函数的特化,这取决于参数类型是否实现给定的接口。

修改

以下是我想要做的一个例子。

请考虑以下代码:

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)

输出结果为:

Iterable Object starting with 7
Object of type Float64
Object of type Set{Any}

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

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

EDIT-2

我认为我的问题与

有关

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

因为我们可以想象T<:Iterable

之类的东西

2 个答案:

答案 0 :(得分:3)

通常,这是通过特征来完成的。有关一个实现,请参阅Traits.jl; Base中使用了类似的方法来发送Base.iteratorsizeBase.linearindexing等。例如,这是Base使用{{1}实现collect的方式特质:

iteratorsize

另见Mauro Werder's talk关于特征。

我会按如下方式定义""" 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 特征:

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

答案 1 :(得分:1)

您可以通过a type检查an interface是否实施methodswith,如下所示:

foo(a_type::Type, an_interface::Symbol) = an_interface ∈ [i.name for i in methodswith(a_type, true)]

julia> foo(EachLine, :done)
true

但我不太了解您在评论中提到的动态调度方法,泛型函数是什么样的?什么是输入&amp;输出功能?我想你想要这样的东西?

function foo(a_type::Type, an_interface::Symbol)
    # assume bar baz are predefined
    if an_interface ∈ [i.name for i in methodswith(a_type, true)]
        # call function bar
    else 
        # call function baz
    end
end

或一些元编程的东西分别在编译时生成这些函数?