如何继承Julia中的Ref
我一直在学习Julia,想花些时间尝试一下,在语言中添加一些我最喜欢的函数/不可变结构。具体来说:用于延迟计算和承诺的类型,如clojure的延迟和承诺类型 延迟和承诺在原则上与如何继承Julia中的Ref,julia,Julia,我一直在学习Julia,想花些时间尝试一下,在语言中添加一些我最喜欢的函数/不可变结构。具体来说:用于延迟计算和承诺的类型,如clojure的延迟和承诺类型 延迟和承诺在原则上与Ref{T}类似,但需要注意的是:(1)obj[]可能需要等待一个值或在返回前运行一个计算,而obj是一个承诺或延迟;(2)延迟/承诺只能设置一次,并且在设置之前不能读取,因此是不可变的(至少,它的接口是不可变对象的接口) 我的直觉是延迟和承诺都应该继承自一个抽象的不可变ref类型,因为它们的这部分行为至少是相似的;但是
Ref{T}
类似,但需要注意的是:(1)obj[]
可能需要等待一个值或在返回前运行一个计算,而obj
是一个承诺或延迟;(2)延迟/承诺只能设置一次,并且在设置之前不能读取,因此是不可变的(至少,它的接口是不可变对象的接口)
我的直觉是延迟和承诺都应该继承自一个抽象的不可变ref类型,因为它们的这部分行为至少是相似的;但是,我似乎不能这样做:
abstract type ImmutableRef <: Ref end
抽象类型ImmutableRef正如Lyndon所指出的,问题是您没有在类型签名中写入Ref{t}
有趣的是,这是我的一个承诺类型的实现,尽管我确信有一种更优雅的方式,它会更努力地假装是不变的
struct Promise{T} <: Ref{T}
r::Ref{T}
fufilled::Ref{Bool}
end
Promise{T}() where {T} = Promise{T}(Ref{T}(), Ref(false))
Promise() where {T} = Promise{Any}(Ref{T}(), Ref(false))
function Base.getindex(p::Promise)
@assert p.fufilled[] == true
p.r[]
end
function deliver(p::Promise{T}, val::U) where {U <: T}
p.r[] = val; p.fufilled[] = true
p
end
isrealized(p) = p.fufilled[]
延迟应该非常相似。我认为您缺少Ref
上的类型参数。您需要在子类型输入时包含这些参数,但我不在计算机旁,因此无法确定是否存在。谢谢!您的实现与我的非常相似;尽管我使用了一些互斥锁(互斥锁?)使其线程安全。好奇:似乎没有简单的方法将字段设置为私有或防止在模块外设置r
——这是真的吗?你可以在Promise
上重载getproperty
,这样它就会对用户大喊大叫,不允许用户访问它。但一般来说,julia不支持私有字段。
julia> x = Promise(); # If we know we'll deliver an Int then we should do Promise{Int}()
julia> isrealized(x)
false
julia> deliver(x, 1);
julia> x[]
1