美文网首页
julia - MutableNamedTuples - 可变

julia - MutableNamedTuples - 可变

作者: 昵称违法 | 来源:发表于2021-02-23 22:25 被阅读0次

    假定你有一个命名元组
    mytuple = (a = 1,b=2)

    你可以读取 a 和 b的值,但是你不能修改 a和b的值

    如果你想要修改a和b的值,如何实现呢?

    关键点:利用Ref() 就是用引用

    【一】github网址

    链接:https://github.com/MasonProtter/MutableNamedTuples.jl

    【二】简要介绍

    MutableNamedTuples.jl

    Sometimes you want a named tuple, but mutable. This works by wrapping a named tuple where all the elements are mutable Ref s and then pretending that it’s elements are that contents of the Ref s instead.

    julia> using MutableNamedTuples
    
    julia> mnt = MutableNamedTuple(a=1, b= 2)
    MutableNamedTuple(a = 1, b = 2)
    
    julia> mnt.a = 2
    2
    
    julia> mnt
    MutableNamedTuple(a = 2, b = 2)
    
    julia> const MNT = MutableNamedTuple
    MutableNamedTuple
    
    julia> A = [MNT(a = 1, b=2) MNT(a=3, b=6)
                MNT(a =-1, b=4) MNT(a=1, b=1)]
    2×2 Array{MutableNamedTuple{(:a, :b),Tuple{Base.RefValue{Int64},Base.RefValue{Int64}}},2}:
     MutableNamedTuple(a = 1, b = 2)   MutableNamedTuple(a = 3, b = 6)
     MutableNamedTuple(a = -1, b = 4)  MutableNamedTuple(a = 1, b = 1)
    
    julia> A[1, 1].a = 100
    100
    
    julia> A
    2×2 Array{MutableNamedTuple{(:a, :b),Tuple{Base.RefValue{Int64},Base.RefValue{Int64}}},2}:
     MutableNamedTuple(a = 100, b = 2)  MutableNamedTuple(a = 3, b = 6)
     MutableNamedTuple(a = -1, b = 4)   MutableNamedTuple(a = 1, b = 1)   
    

    【三】关键源码

    module MutableNamedTuples
    
    export MutableNamedTuple
    
    struct MutableNamedTuple{N,T <: Tuple{Vararg{<:Ref}}}
        nt::NamedTuple{N, T}
    end
    
    MutableNamedTuple(;kwargs...) = MutableNamedTuple(NamedTuple{keys(kwargs.data)}(Ref.(values(kwargs.data))))
    
    function MutableNamedTuple{names}(tuple::Tuple) where names
        MutableNamedTuple(NamedTuple{names}(Ref.(tuple)))
    end
    
    Base.keys(::MutableNamedTuple{names}) where {names} = names 
    Base.values(mnt::MutableNamedTuple) = getindex.(values(getfield(mnt, :nt)))
    refvalues(mnt::MutableNamedTuple) = values(getfield(mnt, :nt))
    
    Base.NamedTuple(mnt::MutableNamedTuple) = NamedTuple{keys(mnt)}(values(mnt))
    Base.Tuple(mnt::MutableNamedTuple) = values(mnt)
    
    
    function Base.show(io::IO, mnt::MutableNamedTuple{names}) where {names}
        print(io, "MutableNamedTuple", NamedTuple(mnt))
    end
    
    Base.getproperty(mnt::MutableNamedTuple, s::Symbol) = getproperty(NamedTuple(mnt), s)
    
    function Base.setproperty!(mnt::MutableNamedTuple, s::Symbol, x)
        i = findfirst(x -> x === s, keys(mnt))
        refvalues(mnt)[i][] = x
    end
    
    Base.length(mnt::MutableNamedTuple) = length(getfield(mnt, :nt))
    Base.iterate(mnt::MutableNamedTuple, iter=1) = iterate(NamedTuple(mnt), iter)
    Base.firstindex(mnt::MutableNamedTuple) = 1
    Base.lastindex(mnt::MutableNamedTuple) = lastindex(NamedTuple(mnt))
    Base.getindex(mnt::MutableNamedTuple, i::Int) = getfield(NamedTuple(mnt), i)
    Base.getindex(mnt::MutableNamedTuple, i::Symbol) = getfield(NamedTuple(mnt), i)
    function Base.indexed_iterate(mnt::MutableNamedTuple, i::Int, state=1) 
        Base.indexed_iterate(NamedTuple(mnt), i, state) 
    end
    
    end # module
    
    

    相关文章

      网友评论

          本文标题:julia - MutableNamedTuples - 可变

          本文链接:https://www.haomeiwen.com/subject/ypgdfltx.html