如何检查类型是否在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)
输出结果为:
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
答案 0 :(得分:3)
通常,这是通过特征来完成的。有关一个实现,请参阅Traits.jl; Base
中使用了类似的方法来发送Base.iteratorsize
,Base.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
或一些元编程的东西分别在编译时生成这些函数?