Ini pertanyaan yang menarik. Pertanyaan kuncinya adalah apa yang kita definisikan sebagai tipe yang dideklarasikan . Jika Anda maksudkan ada ::SomeType
pernyataan dalam setiap definisi metode maka agak sulit dilakukan karena Anda memiliki berbagai kemungkinan pembuatan kode dinamis di Julia. Mungkin ada solusi lengkap dalam hal ini tetapi saya tidak mengetahuinya (saya ingin mempelajarinya).
Hal yang terlintas dalam pikiran saya, yang tampaknya relatif lebih mudah untuk dilakukan adalah memeriksa apakah ada metode yang didefinisikan dalam modul menerima Any
sebagai argumennya. Ini serupa tetapi tidak setara dengan pernyataan sebelumnya sebagai:
julia> z1(x::Any) = 1
z1 (generic function with 1 method)
julia> z2(x) = 1
z2 (generic function with 1 method)
julia> methods(z1)
# 1 method for generic function "z1":
[1] z1(x) in Main at REPL[1]:1
julia> methods(z2)
# 1 method for generic function "z2":
[1] z2(x) in Main at REPL[2]:1
terlihat sama untuk methods
fungsi sebagai tanda tangan dari kedua fungsi menerima x
sebagaiAny
.
Sekarang untuk memeriksa apakah ada metode dalam modul / paket menerima Any
sebagai argumen untuk salah satu metode yang didefinisikan di dalamnya sesuatu seperti kode berikut dapat digunakan (saya belum mengujinya secara ekstensif karena saya baru saja menuliskannya, tetapi tampaknya sebagian besar menutup kemungkinan kasus):
function check_declared(m::Module, f::Function)
for mf in methods(f).ms
if mf.module == m
if mf.sig isa UnionAll
b = mf.sig.body
else
b = mf.sig
end
x = getfield(b, 3)
for i in 2:length(x)
if x[i] == Any
println(mf)
break
end
end
end
end
end
function check_declared(m::Module)
for n in names(m)
try
f = m.eval(n)
if f isa Function
check_declared(m, f)
end
catch
# modules sometimes return names that cannot be evaluated in their scope
end
end
end
Sekarang ketika Anda menjalankannya pada Base.Iterators
modul Anda mendapatkan:
julia> check_declared(Iterators)
cycle(xs) in Base.Iterators at iterators.jl:672
drop(xs, n::Integer) in Base.Iterators at iterators.jl:628
enumerate(iter) in Base.Iterators at iterators.jl:133
flatten(itr) in Base.Iterators at iterators.jl:869
repeated(x) in Base.Iterators at iterators.jl:694
repeated(x, n::Integer) in Base.Iterators at iterators.jl:714
rest(itr::Base.Iterators.Rest, state) in Base.Iterators at iterators.jl:465
rest(itr) in Base.Iterators at iterators.jl:466
rest(itr, state) in Base.Iterators at iterators.jl:464
take(xs, n::Integer) in Base.Iterators at iterators.jl:572
dan ketika Anda mis memeriksa paket DataStructures.jl Anda mendapatkan:
julia> check_declared(DataStructures)
compare(c::DataStructures.LessThan, x, y) in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\heaps.jl:66
compare(c::DataStructures.GreaterThan, x, y) in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\heaps.jl:67
cons(h, t::LinkedList{T}) where T in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\list.jl:13
dec!(ct::Accumulator, x, a::Number) in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\accumulator.jl:86
dequeue!(pq::PriorityQueue, key) in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\priorityqueue.jl:288
dequeue_pair!(pq::PriorityQueue, key) in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\priorityqueue.jl:328
enqueue!(s::Queue, x) in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\queue.jl:28
findkey(t::DataStructures.BalancedTree23, k) in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\balanced_tree.jl:277
findkey(m::SortedDict, k_) in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\sorted_dict.jl:245
findkey(m::SortedSet, k_) in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\sorted_set.jl:91
heappush!(xs::AbstractArray, x) in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\heaps\arrays_as_heaps.jl:71
heappush!(xs::AbstractArray, x, o::Base.Order.Ordering) in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\heaps\arrays_as_heaps.jl:71
inc!(ct::Accumulator, x, a::Number) in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\accumulator.jl:68
incdec!(ft::FenwickTree{T}, left::Integer, right::Integer, val) where T in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\fenwick.jl:64
nil(T) in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\list.jl:15
nlargest(acc::Accumulator, n) in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\accumulator.jl:161
nsmallest(acc::Accumulator, n) in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\accumulator.jl:175
reset!(ct::Accumulator{#s14,V} where #s14, x) where V in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\accumulator.jl:131
searchequalrange(m::SortedMultiDict, k_) in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\sorted_multi_dict.jl:226
searchsortedafter(m::Union{SortedDict, SortedMultiDict, SortedSet}, k_) in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\tokens2.jl:154
sizehint!(d::RobinDict, newsz) in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\robin_dict.jl:231
update!(h::MutableBinaryHeap{T,Comp} where Comp, i::Int64, v) where T in DataStructures at D:\AppData\.julia\packages\DataStructures\iymwN\src\heaps\mutable_binary_heap.jl:250
Apa yang saya usulkan bukanlah solusi lengkap untuk pertanyaan Anda, tetapi saya menemukan itu berguna untuk diri saya sendiri sehingga saya berpikir untuk membagikannya.
EDIT
Kode di atas menerima f
untuk menjadi Function
saja. Secara umum Anda dapat memiliki jenis yang dapat dipanggil. Kemudian check_declared(m::Module, f::Function)
tanda tangan dapat diubah menjadi check_declared(m::Module, f)
(sebenarnya maka fungsi itu sendiri akan memungkinkan Any
sebagai argumen kedua :)) dan meneruskan semua nama yang dievaluasi ke fungsi ini. Maka Anda harus memeriksa apakah methods(f)
ada positif length
di dalam fungsi (seperti methods
untuk pengembalian yang tidak dapat dipanggil, nilai yang memiliki panjang0
).
hasmethod(f, (Any,) )
akan kembalifalse
jika tidak ada generik yang telah didefinisikan. Anda masih harus mencocokkan jumlah argumen (yaituhasmethod(f, (Any,Any) )
untuk fungsi dua argumen).