我想检查变量是否是julia中的标量,例如Integer,String,Number,但不是AstractArray,Tuple,type,struct等。是否有一个简单的方法来执行此操作(即{{1} })
答案 0 :(得分:6)
在没有更多背景的情况下,标量是或者不是标量的概念是不明确的。 在数学上,定义了标量; (Wikipedia)
标量是字段的元素,用于定义向量空间。
也就是说,在确定某些内容是否是标量(相对于该向量空间)之前,需要根据字段定义向量空间。 对于正确的向量空间,元组可以是标量。
当然,我们并不是在寻找一个数学上严谨的定义。 只是一个务实的。
我建议在julia中定义标量的唯一有意义的方式是广播行为。 在Julia 0.7-dev中#23939 我相信这应该简单:
using Base.Broadcast
isscalar(x::T) where T = isscalar(T)
isscalar(::Type{T}) where T = BroadcastStyle(T) isa Broadcast.Scalar
请参阅Broadcast的文档。
Scalar
是默认值。所以它基本上是任何没有特定广播行为的东西,即它会敲出像数组和元组等的东西。
在朱莉娅0.6中,这有点混乱,但相似:
isscalar(x::T) where T = isscalar(T)
isscalar(::Type{T}) where T = Base.Broadcast._containertype(T)===Any
使用Broadcast
的方法确定某些东西是否是标量,而不是使用自己的方法的优点是,任何一个以标量方式行事的新类型必须确保它能够与那些方法正确
(或者实际上是非标量的,因为标量是默认值。)
也就是说:有时结构是标量,有时它们不是,它取决于结构。
但请注意,这些方法不认为struct
是非标量的。
我认为你错了你的愿望。
Julia结构不是(必然或通常)集合类型。
请考虑:BigInteger
,BigFloat
,Complex128
等
都使用结构
我很想说使用start
方法会使类型成为非标量类型,但由于定义了start(::Number)
,这种方法会不正确。
(这是debated a few times)
答案 1 :(得分:0)
我发现自己需要在MultiResolutionIterators.jl中捕捉最近是否存在标量的概念。
我从other answer找到了基于广播的规则, 不符合我的需要。
特别是我想把字符串视为非标量。
我定义了一个特征,
基于method_exists(start, (T,))
,
除了上面提到的例外,例如Number
。
abstract type Scalarness end
struct Scalar <: Scalarness end
struct NotScalar <: Scalarness end
isscalar(::Type{Any}) = NotScalar() # if we don't know the type we can't really know if scalar or not
isscalar(::Type{<:AbstractString}) = NotScalar() # We consider strings to be nonscalar
isscalar(::Type{<:Number}) = Scalar() # We consider Numbers to be scalar
isscalar(::Type{Char}) = Scalar() # We consider Sharacter to be scalar
isscalar(::Type{T}) where T = method_exists(start, (T,)) ? NotScalar() : Scalar()
类似的事情也由AbstractTrees.jl
完成isscalar(x) == applicable(start, x) && !isa(x, Integer) && !isa(x, Char) && !isa(x, Task)