Đây là một câu hỏi thú vị. Câu hỏi chính là những gì chúng ta định nghĩa là loại khai báo . Nếu bạn có nghĩa là có một ::SomeType
tuyên bố trong mọi định nghĩa phương thức thì sẽ hơi khó thực hiện khi bạn có các khả năng tạo mã động khác nhau trong Julia. Có thể có một giải pháp hoàn chỉnh theo nghĩa này nhưng tôi không biết nó (tôi rất thích tìm hiểu nó).
Mặc dù vậy, điều xuất hiện trong đầu tôi dường như tương đối đơn giản hơn là kiểm tra xem có phương thức nào được xác định trong mô-đun chấp nhận Any
làm đối số của nó không. Điều này tương tự nhưng không tương đương với tuyên bố trước đó như:
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
trông giống nhau cho methods
chức năng như chữ ký của cả hai chức năng chấp nhận x
như Any
.
Bây giờ để kiểm tra xem có phương thức nào trong mô-đun / gói chấp nhận Any
làm đối số cho bất kỳ phương thức nào được xác định trong đó không, có thể sử dụng mã như sau không (tôi đã không kiểm tra rộng rãi khi tôi vừa viết ra, nhưng dường như chủ yếu là bao gồm các trường hợp có thể):
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
Bây giờ khi bạn chạy nó trên Base.Iterators
mô-đun, bạn nhận được:
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
và khi bạn ví dụ kiểm tra gói DataSt Structures.jl bạn nhận được:
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
Những gì tôi đề xuất không phải là một giải pháp đầy đủ cho câu hỏi của bạn nhưng tôi thấy nó hữu ích cho bản thân mình nên tôi đã nghĩ đến việc chia sẻ nó.
BIÊN TẬP
Các mã trên chấp nhận f
là Function
duy nhất. Nói chung, bạn có thể có các loại có thể gọi được. Sau đó, check_declared(m::Module, f::Function)
chữ ký có thể được thay đổi thành check_declared(m::Module, f)
(thực ra sau đó chính hàm sẽ cho phép Any
làm đối số thứ hai :)) và chuyển tất cả các tên được đánh giá cho hàm này. Sau đó, bạn sẽ phải kiểm tra xem methods(f)
có tích cực length
bên trong hàm không (như methods
đối với không thể gọi được trả về một giá trị có độ dài 0
).
hasmethod(f, (Any,) )
sẽ trở lạifalse
nếu không có định nghĩa chung chung nào được xác định. Mặc dù vậy, bạn vẫn cần khớp số lượng đối số (ví dụ:hasmethod(f, (Any,Any) )
đối với hàm hai đối số).