Julia接口:Iteration接口-迭代

一、簡介函數


julia提供的各類接口爲自定義類型擴展功能。
本文討論一下Iteration接口。
自定義的類型實現這裏接口就能夠實現迭代功能,也就是能夠直接在for循環這樣使用:
假如iter是你的自定義類型:this

for i in iter   # or  "for i = iter"
    # body
end

等同於:code

next = iterate(iter)
while next !== nothing
    (i, state) = next
    # body
    next = iterate(iter, state)
end

二、如何實現索引


要實現Iteration接口須要實現iterate(iter, state)方法,這個方法在Base包裏面,它的含義是返回iter的下一個元素和其狀態state,若是沒有就返回nothing, state能夠是索引。
咱們定義一個類型Squares,它有一個count域:接口

struct Squares
           count::Int
       end

而後定義他的iterate方法,要顯性的指定報名:element

Base.iterate(S::Squares, state=1) = state > S.count ? nothing : (state*state, state+1)

state小於count是計算它的平方值,而後+1,不然返回nothing。it

定義好以後用for循環迭代以下:io

julia> for i in Squares(5)
       println(i)
       end
1
4
9
16
25

三、其餘與迭代相關方法for循環


實現了iterable後還可使用其餘相關的函數, 如 in (檢查元素是否在集合中) 、 mean(求平均數) 和 std (求方差),後兩個函數在Statistics包裏:擴展

julia> 25 in Squares(10)
true

julia> using Statistics

julia> mean(Squares(3))
4.666666666666667

julia> std(Squares(100))
3024.355854282583

四、實現其餘迭代集合方法


咱們還能夠爲Squares實現其餘與迭代集合有關的方法:
eltype(返回集合元素類型), length(返回集合元素個數),

julia> Base.eltype(::Type{Squares}) = Int # Note that this is defined for the type

julia> Base.length(S::Squares) = S.count

julia> sum(Squares(100))
338350

默認的sum方法是經過循環迭代計算全部元素的和:
咱們能夠從新實現sum方法使其更高效,使用公式直接求和

julia> Base.sum(S::Squares) = (n = S.count; return n*(n+1)*(2n+1)÷6)

julia> sum(Squares(1803))
1955361914

5.反向迭代


要實現反向迭代,須要實現Iterators.Reverse{T}的iterate方法,T指類型,這裏咱們實現Iterators.Reverse{Squares},
collect收集集合元素,也能夠用for迭代:

julia> Base.iterate(rS::Iterators.Reverse{Squares}, state=rS.itr.count) = state < 1 ? nothing : (state*state, state-1)

julia> collect(Iterators.reverse(Squares(4)))
4-element Array{Int64,1}:
 16
  9
  4
  1
  
julia> for i in Iterators.reverse(Squares(5))
       println(i)
       end
25
16
9
4
1
相關文章
相關標籤/搜索