尝试将数组传递给函数

D_D*_*D_D 1 julia

我对 Julia 很陌生,我试图将一个数字数组传递给一个函数并计算其中零的数量。我不断收到错误:

错误:UndefVarError:数组未定义

我真的不明白我做错了什么,所以如果这看起来是一项我做不到的简单任务,我很抱歉。

function number_of_zeros(lst::array[])

    count = 0

   for e in lst

    if e == 0

        count + 1

    end

end

println(count)

end 

lst = [0,1,2,3,0,4]

number_of_zeros(lst)
Run Code Online (Sandbox Code Playgroud)

Nil*_*dat 5

您的函数定义有两个问题:

  1. 正如 Shayan 的回答和 Dan 的评论中所指出的,Julia 中的数组类型被称为Array(大写)而不是array。查看:
julia> array
ERROR: UndefVarError: array not defined

julia> Array
Array
Run Code Online (Sandbox Code Playgroud)
  1. 空方括号用于实例化数组,如果前面有类型,则它们专门实例化包含该类型对象的数组:
julia> x = Int[]
Int64[]

julia> push!(x, 3); x
1-element Vector{Int64}:
 3

julia> push!(x, "test"); x
ERROR: MethodError: Cannot `convert` an object of type String to an object of type Int64
Run Code Online (Sandbox Code Playgroud)

因此,当你这样做时,Array[]你实际上是在实例化 s 的空向量Array

julia> y = Array[]
Array[]

julia> push!(y, rand(2)); y
1-element Vector{Array}:
 [0.10298669573927233, 0.04327245960128345]
Run Code Online (Sandbox Code Playgroud)

现在需要注意的是,类型和类型的对象之间存在差异,如果您想限制函数的输入参数的类型,您需要通过指定函数应接受的类型来实现这一点,不是这种类型的实例array要看到这一点,请考虑如果您修正了拼写错误并传递了一个Array[]代替,会发生什么:

julia> f(x::Array[])
ERROR: TypeError: in typeassert, expected Type, got a value of type Vector{Array}
Run Code Online (Sandbox Code Playgroud)

这里 Julia 抱怨你在类型注释中提供了类型的值Vector{Array},而我应该提供类型。

但更一般地说,您应该考虑为什么要向函数添加任何类型限制。如果您定义一个没有任何输入类型的函数,Julia 仍然会编译一个专门针对首次调用该函数时提供的输入类型的方法实例,因此生成(大多数时候)针对特定类型的最佳机器代码通过了。

也就是说,两者之间没有区别

number_of_zeros(lst::Vector{Int64})
Run Code Online (Sandbox Code Playgroud)

number_of_zeros(lst)
Run Code Online (Sandbox Code Playgroud)

当使用 类型的参数调用第二个定义时,就运行时性能而言Vector{Int64}。有些人仍然喜欢将类型注释作为错误检查的一种形式,但您还需要考虑到添加类型注释会使您的方法不那么通用,并且通常会限制您将它们与其他人编写的代码结合使用。最常见的例子是 Julia 出色的自动微分功能 - 它们依赖于使用双数字运行代码,这是一种支持自动微分的特定数字类型。如果您严格按照建议 ( ) 输入函数,Vector{Int}则会阻止您的函数以这种方式自动区分。

最后需要注意的是Array类型 - Julia 的数组可以是多维的,这意味着它Array{Int}不是具体类型:

julia> isconcretetype(Array{Int})
false
Run Code Online (Sandbox Code Playgroud)

为了使其具体化,必须提供数组的维数:

julia> isconcretetype(Array{Int, 1})
true
Run Code Online (Sandbox Code Playgroud)