我不确定我理解为什么需要class Character(object):
def __init__(self):
self.NAME = ''
self.life = 50
players = ["red","green","blue","yellow"]
dict_players = {}
for player in players:
dict_players[player] = Character()
。每个iterable都保证生成__str__
类型的对象,所以如果你不知道更好,那么你总是默认为那个。区分“我知道它可能是任何东西”(IteratorEltype()
)和“我不知道它是什么,因此它可以是任何东西”(Any
)?
使用IteratorEltype == HasEltype && eltype = Any
我可以找到的基本朱莉娅中的唯一类型是IteratorEltype == EltypeUnknown
,这是EltypeUnknown()
语法背后的工具。我可以想象,如果Generator
是非叶类型,很难/不可能找到这样的生成器的(f(i) for i in iter)
,但不仅仅是将eltype
设置为eltype(iter)
在这种情况下?当然,如果eltype
是叶类型且Any
是类型稳定的,那么您不希望它是Any
,但这两种情况在编译时应该是可区分的。
答案 0 :(得分:0)
两个IteratorEltype()
选项之间的区别如下:
HasEltype()
说,即使eltype()
比迭代器中实际遇到的类型更通用,也应将迭代器的值视为类型eltype()
的对象。
EltypeUnknown()
要求类似collect()
的函数找出适用于所有元素的最特定类型。
示例:
julia> abstract type Wrapper end
Base.length(w::Wrapper) = length(w.data)
Base.iterate(w::Wrapper, s...) = iterate(w.data, s...)
struct EltypeWrapper{T,D} <: Wrapper
data::D
end
EltypeWrapper{T}(data) where T = EltypeWrapper{T,typeof(data)}(data)
Base.eltype(::Type{<:EltypeWrapper{T}}) where T = T
struct EltypeUnknownWrapper{D} <: Wrapper
data::D
end
Base.IteratorEltype(::Type{<:EltypeUnknownWrapper}) = Base.EltypeUnknown()
julia> collect(EltypeWrapper{Any}(Any[1,2.0]))
2-element Array{Any,1}:
1
2.0
julia> collect(EltypeUnknownWrapper(Any[1,2.0]))
2-element Array{Real,1}:
1
2.0
请注意,两个数组具有相同的条目,但第一个数组的类型为Vector{Any}
,而第二个数组的类型为Vector{Real}
。
似乎HasEltype()
应该更有效,因为它允许在collect()
之类的函数中预先分配输出。朱莉娅(Julia)很擅长推导迭代器Eltype,并且EltypeUnknown()
可以和HasEltype()
一样快(或者由于某些奇怪的原因甚至比julia> using BenchmarkTools
abstract type AbstractIterable end
struct TypedIterable <: AbstractIterable; end
struct UntypedIterable <: AbstractIterable; end
Base.length(::AbstractIterable) = 100000
Base.eltype(::Type{TypedIterable}) = Int
Base.IteratorEltype(::Type{UntypedIterable}) = Base.EltypeUnknown()
function Base.iterate(f::AbstractIterable,i = 1)
i > length(f) && return nothing
return i, i+1
end
@btime collect(UntypedIterable())
@btime collect(TypedIterable())
;
43.033 μs (2 allocations: 781.33 KiB)
56.772 μs (2 allocations: 781.33 KiB)
快):
IteratorEltype()
EltypeUnknown()
因此不一定会影响使用迭代器的性能,但可能会严重影响调用堆栈中进一步的性能。如果对非叶子类型进行操作,则几乎所有代码的速度都快几个数量级,因此将IteratorEltype()
设置为eltype()
并希望将IteratorEltype() = HasEltype()
简化为而不是先设置eltype()
,然后再将git log --graph --oneline --decorate --pretty=format:"%cn committed %h on %cd"
设置为某种抽象类型。