对于两个对象A,B我们以前可以[A*A, A*B]使用代码获取向量A .* [A, B].根据Julia 0.7中的弃用警告,似乎新方法是使用第一个A的引用.所以它变成了Ref(A) .* [A,B].
似乎参考和广播业务之间没有强大的联系.这里有什么链接以及为什么使用参考首选(至少通过弃用警告)?
import Base.*
struct example
num::Int
end
function *(lhs::example, rhs::example)
return example(lhs.num * rhs.num)
end
A = example(2)
B = example(4)
# Previously this could be done as follows.
A .* [A, B]
# Now we need to use Refs
Ref(A) .* [A, B]
Run Code Online (Sandbox Code Playgroud)
我将在这里提到主要的情况Ref,即当你传递一个参数时(还有其他的子类型,Ref但它们在这里与我们无关).写入Ref(x)会在对象周围创建一个可变的包装器x.包装器是一种非常简单的RefValue类型,以下列方式定义:
mutable struct RefValue{T} <: Ref{T}
x::T
RefValue{T}() where {T} = new()
RefValue{T}(x) where {T} = new(x)
end
Run Code Online (Sandbox Code Playgroud)
现在为什么它有用,因为Ref已经定义了以下实用程序函数:
eltype(x::Type{<:Ref{T}}) where {T} = @isdefined(T) ? T : Any
size(x::Ref) = ()
axes(x::Ref) = ()
length(x::Ref) = 1
ndims(x::Ref) = 0
ndims(::Type{<:Ref}) = 0
iterate(r::Ref) = (r[], nothing)
iterate(r::Ref, s) = nothing
IteratorSize(::Type{<:Ref}) = HasShape{0}()
Run Code Online (Sandbox Code Playgroud)
这意味着它可以用于广播,因为只有axes定义和支持索引的对象才能使用broadcast.
幸运的是,很容易避免一直写作Ref(A).
只需定义:
Base.broadcastable(e::example) = Ref(e)
Run Code Online (Sandbox Code Playgroud)
并且broadcast将按照Base.broadcastable每个论点的要求再次运作broadcast.
有关自定义广播的更多详细信息,请访问https://docs.julialang.org/en/latest/manual/interfaces/#man-interfaces-broadcasting-1.